This works, but actually I've never come across it earlier. Does it have some "weak spots"?
div.floated { float: left; }
div.floated+* { clear: both; }
Though I did not notice any "side effect".
You can use it at your will, although according to MDN, you should take into account that universal selector is the most expensive CSS selector in terms of webpage performance.
Universal CSS Selector Performance
Here some problems I see:
"floated" is not a semantic class name.
This will clear adjacent elements after divs with the "floated" class, but not anything that is floated by other means.
In most designs I work with, I don't want to clear adjacent elements. Now I'll have to write more CSS to undo this.
I think I don't understand the value of this.
Related
I was wondering if there was a way to use css to style a wrapper a certain way ONLY if it had a div with a specific id inside. Let's say that I have
<div class="intro_wrapper"></div>
in several places throughout the site but want to change the padding ONLY if it
<div class="intro_wrapper">
<div id="slider"></div>
</div>
has #slider inside of it. The thing is that I want to make it have less padding when #slider is nested in it so I can't really mess with the margin for #slider without cutting off the content all weird. I tried using negative margins but it ends up cutting off the image I have in a weird way.
I know you can use stuff like p + p for paragraphs that have paragraphs following them, so I am assuming there may be a way to do something like I am trying to. Thanks in advance.
You cannot do that with any CSS rules at this point as a reverse combinator to apply style on parent based on child. Instead you can hack it by adding a margin to the child instead.
div.intro_wrapper > #slider
{
margin:20px;
}
Whilst I think PSL's answer is already pretty good (cross browser, simple etc.) it doesn't help if you actually need to use a parent selector. Whilst at the moment it's best to avoid this when you can, there are definitely some circumstances which may require a parent selector (or some such alternative).
One solution if you absolutely have to use a parent selector would be jquery, its selector engine recongnises the :parent selector, for example you could do:
$("#slider:parent").addClass('padded_intro_wrapper');
Then in your CSS:
.padded_intro_wrapper
{
padding: 20px;
}
Equally, if the #slider div isn't always inside the .intro_wrapper div you could do:
$('#slider').closest('.intro_wrapper').addClass('padded_intro_wrapper');
That's where it starts getting a bit messy though.
EDIT: Fiddle if you're feeling lazy
When I studied front end dev at the university a few years ago, our teacher taught us to always provide the full (almost) parental
DOM hierarchy of the targeted element within our CSS selectors.
So in our web projects we had to write selectors like:
div#container div#content p.bread a.external { }
instead of just:
#container #content .bread .external { }
or (I see the disadvantages with class conflicts that may occur here)
.external { }
I personally write my selectors like
#container #content p.bread a.external {}
until I recently read an article saying that it should be avoided (but with no obvious reason why) and another article saying the same but that one was intended for jQuery selectors.
Was my teacher wrong and what is the right (fastest to parse and with most support) way of writing CSS selectors?
Practically speaking, you should use the least specific selectors you can.
div#container div#content p.bread a.external { } is a very, very specific selector. It is unnecessarily specific. There can only be one #content element, and it will surely always be within #container.
Write general rules. Don't attempt to target the precise DOM element. If a.external will capture the set of elements you want, use that. Otherwise you'll end up having to write p.bread a.external, p.potato a.external, p.olive a.external, etc, etc.
The difference in performance will be minimal. The benefits of general, reusable rules are large.
My 2 cents
Specific enough to target only what needs targeting (as others have said) is the general rule.
I agree with lonesomeday that "difference in performance will be minimal," but every added element in the chain is one more check to be done.
So Think About How to Reduce It
Are the ID's needed?
I disagree with Spudley that "there should never be a need to specify more than one ID in a selector." If your site is set up to have different display on different pages, and so #page1 #content is different than #page2 #content for displaying, then that is a legitimate case of two id's in one selector. However,
If all pages are #container #content then the drop the #container.
Also, if all p.bread elements are inside #content, then drop that selector also.
Are element names needed?
Is .bread intended to be used on anything other than a p? If not, drop the p.
Is .external intended to be used on anything other than an a (probably linking to an external site)? If not, drop the a.
Is the decedent relation of classes needed?
Is the .bread .external significant for display? That is, does .external exist outside of a .bread parent and does it change because of that parent? If so, then keep the relation. Otherwise, if the important thing is only the .external (no matter where it is), then that is the only selector you need.
Yes, your teacher was wrong.
From your example:
div#container div#content p.bread a.external { }
Given that an ID in a DOM document must be unique, there should never be a need to specify more than one ID in a selector. So the above selector that contains both #container and #content is immediately wrong simply by that criteria.
An ID is the most efficient and direct way to reference an element. Again, it's unique and instantly accessible, so there's no need to qualify it in any way, so adding div in front of either of the #container or #content here is redundant.
The other two parts of the selector p.bread and a.external are likely to be wrong, but it's not so clear-cut for these.
A selector only needs to specify the parts that are necessary to select the elements required and exclude any elements that are not required. In this example, if all .bread elements are ps or all .external elements are as then the element type a or p would be redundant and should be dropped. But without seeing your actual HTML content, it's not possible to be certain of this in the way that it is possible for the IDs because a given classname can legitimately be applied to multiple elements of multiple type.
Longer selectors such as div#container div#content p.bread a.external { } do take longer, yes. But rarely do they make any noticeable impact on the paint time.
Also, since IDs are (supposed to be) always unique, div#container and div#content should really just be #container and #content, respectively.
Elements are superfluous (or rather should be) when used with ID selectors (#), since your DOM should contain only unique IDs for elements.
It's also worth noting that classes should be used to bunch the styles of the same elements. In case you have two .bread elements in your DOM, but want them styled differently, you should consider using a different class name.
Both ways will work, and the impact on speed will probably be minimal. However there is no need to add the element to your rule, and I would encourage you not to as it helps your rules become more reusable - something you should always aim for.
You should also avoid using location to target elements. E.g. .sidebar h3. Instead, add a class to those h3s and target the class. This means you can reuse those styles you wrote elsewhere, just by adding the class. These are all concepts of Object Oriented CSS, and will help you write more efficient CSS by reducing the amount of duplicate code.
I recently came across this CSS selector while trying to find a way to easily space out major blog elements such as paragraphs and images. An example of its use would be something like this:
.post *+* {margin-top: 15px;}
/* or... */
.post > *+* {margin-top: 15px;}
/* if you don't want the margin to apply to nested elements */
At first glance, it seemed pretty useful. So my question is: What downsides are there to using these selectors?
Specifically:
What's the browser support like for this?
Are there any cases you wouldn't want an even margin spacing between elements in an article and if not, is it easier to declare this first and then overwrite or simply declare each element individually?
Does this have performance issues since you're selecting everything twice?
What's the browser support like for this?
Basically, IE7+ and any other modern browser.
There may be corner cases for each browser depending on what elements are actually being selected or queried with the sibling combinator +, but I wouldn't worry about those as much as the fact that the margin is being applied to just about any element that's a sibling for no practical reason.
Are there any cases you wouldn't want an even margin spacing between elements in an article and if not, is it easier to declare this first and then overwrite or simply declare each element individually?
It does seem pretty useful at first glance, but if you think about it, it'll probably be a much better idea to be more specific about what to apply the margin to. This is one rule that I can imagine will be overridden many, many times throughout the rest of the stylesheet by other specific selectors, making it quite redundant and even undesired in many cases. I can't think of any real-world use for a rule like your example.
Bear in mind that, in this specific case, vertical margins will collapse, so you only need to define vertical margins for a set of elements without having to resort to applying margin-top exclusively to all of an element's following siblings.
Does this have performance issues since you're selecting everything twice?
Actually, it's not selecting everything twice. The browser only looks at each element once, then determines whether each element follows another one under the same parent element. It doesn't care what kind of element it follows, as long as it follows another. It doesn't go around selecting every element again then compare to see if they're siblings of each other.
Now, people say that using the universal selector * in conjunction with just about any combinator causes rendering performance catastrophes, so people say that this kind of stuff should be avoided at all costs. But this stuff is hardly important at all (honestly, a selector like * + * is only a few microseconds slower than p + p), so you really don't need to worry about it. Consider the utility of the CSS rule itself first, then decide whether you really need the rule based on that.
Now with all that said (it's getting pretty late here), I would probably have rewritten the example like this, based on what I said above regarding collapsing margins:
.post > * { margin: 15px 0; }
It's probably only worth replacing the * with p if you know that the only children you want to space out are paragraphs:
.post > p { margin: 15px 0; }
Or any paragraphs within .post for that matter (e.g. within blockquotes):
.post p { margin: 15px 0; }
(* being used with the descendant selector is fair game, I'll admit; the child combinator, on the other hand, is limited to only one level of nesting, so for anyone obsessing about performance, this won't hurt at all.)
It's called the "Sibling Selector".
According to SitePoint, it's supported in all recent browsers and in IE8+. IE7 has a few limitations explained on the SitePoint page, but will mostly work as well.
It's defined in the CSS2 spec.
About the performance: a lot of CSS is overriding other selectors. That's part of the cascading nature of it. Also, performance varies so much between render engines that it's not practical to worry about performance when it comes to CSS.
You should also consider IE7 bug related to ignoring adjacent-sibling combinator (as well as :first-child pseudoclass) if HTML comment is in place of where IE7 expects to see an element. There is a workaround that removes comments as DOM nodes after page is loaded in IE7.
While there exist selectors to select items preceded (#hlinks+#hsearch) or owned (#topbar>#hlinks) by other items, there's no way to do the opposite.
For example there isn't something like
li:has(ul){ }
To detect list items that have other lists within them. Wouldn't that be convenient?
AFAIK, the feature is not even in the plans for CSS, so my question is: why is this so?
This is generally called a "parent selector"; as you say, they don't exist in CSS, though they could be useful.
There's an interesting discussion here; the summary is that they would have a large negative effect on performance and would allow people to make mistakes with large consequences. People who understand these things seem to think that these issues can be overcome, but there hasn't yet been sufficient demand for someone to actually do it.
You're referring to the concept of a "parent" selector - selecting the parent element under a particular condition. You're correct about this feature not being present in CSS (not event CSS3) - to my knowledge, it not possible at the moment to the way the DOM is parsed by CSS. However, this feature is available using jQuery and the :parent selector or the :has selector, which it seems you may be familiar with already.
EDIT: For a tremendous amount of detail on the idea of a parent selector, see http://shauninman.com/archive/2008/05/05/css_qualified_selectors.
This is standard in CSS since...uh.... the beginning of CSS.
It's just a space:
li ul means any ul that is inside li
If you want to do that just do:
ul li ul li {
}
So now you are searching for any list-item that has an unordered-list inside of it with a list item.
So, I was wondering about the following: I have some main content div and a sidebar div and the CSS looks as follows:
.main{
width: 400px;
height: 300px
}
.sidebar{
width: 100px;
height: 300px;
}
I will not include now all the floating properties, since I am only interested in the following:
If I have a p element in both of them and I want them to have different styles, shall I give the paragraphs different classes or shall I define the style for them like this:
.main p{
color: blue;
text-align: right;
font-family: ...
}
And then for .sidebar p I would define something else...
The alternative would be to define a class p.myclass and define the style there.
I am trying to understand what a better practice is. Obviously I need less markup if I have 30 p elements in one of the elements with the first method, since I would have to give them all a class. On the other hand, I create CSS that I can only "use" for that parent element, instead of having a general definition that I can apply in more places in the site...
I noticed that in a lot of "big" websites, almost every single html element has its own class...
Any ideas?
I would definitely go ahead with the containment selector in the case you give. Fewer spurious classes in the markup is easier to maintain, and the rule ‘.main p’ says clearly what it does. Use your judgement to whether more complicated cases are still clear.
Note that ‘.main p’ selects all descendent paragraphs and not just direct children, which may or may not be what you want; accidentally-nested descendant matches are a potential source of bugs (especially for cumulative properties like relative font size). If you want only children to be selected you need ‘.main>p’, which unfortunately does not work in IE6.
This is one reason why many sites go crazy with the classnames: the more involved selectors that could otherwise be used to pick out elements without a classname, tend not to work in IE.
I vote for .main p and .sidebar p because:
It most clearly expresses your intention, as you're expressing it in English
It reduces the number of explicit classes you need in your HTML
If you change your mind later and want an explicit paragraph class with that style you can just add it: .main p, p.foo
In my opinion using nested selectors [ parent child relations ] will be harder to read and maintainable.
Evdn if the design changes in a frequent manner CSS should be less affected by that. So styling individual element will be easier in the case of maintainability.
If the element is going to exist in a predictable location then you can style it based on a parent element.
The major drawback of styling by class on each individual element is the bloat: If you have many of these elements, the CSS attributes will become a noticeable percentage of the transferred bytes. Especially for large documents, saving a couple of KB in the download can count. Even more so with AJAX requests or IE where parsing innerHTML is extremely slow.