Using the id selector with other selectors - css

I want to know, what does the following CSS mean?
.twoCol #sidebar
Isn't #sidebar alone enough? What does this line of CSS actually select?

This is accessing the element with the id sidebar within any element that uses the twoCol class.
#sidebar is enough on its own really, as it's an ID, but this is a little more semantically correct.

Isn't #sidebar alone is enough?
Yes. An id should be unique. (and it will be, unless you're dealing with poor quality HTML)
The .twoCol prefix is not optimal because it's adding redundant information.
This is comically demonstrated here: http://www.css-101.org/descendant-selector/go_fetch_yourself.php
A more complete article, which isn't specific to this case, but a good and relevant read nonetheless:
http://css-tricks.com/efficiently-rendering-css/

Demian and thirtydot are largely correct, but this does have a conditional use:
If you have several templates and sometimes #sidebar occurs in .twoCol, but sometimes it occurs somewhere else - you can target that specific template without including another CSS file.
In this case, it makes more sense to assign a class to the <html>, <body>, or template wrapper, but I just thought I'd point out that it's not strictly useless.

Related

CSS: Is it important to specify the exact path for a particular element for speed/accuracy?

When defining CSS for a particular element does specifying exact path make any difference when we are talking about speed/accuracy/processing of a web page?
for e.g. if I have text inputs ONLY in 3rd column of my table, which is better for speed, accuracy, processing and other parameters?
OPTION 1:
table input[type="text"]
{
background:yellow;
}
OPTION 2:
table td:nth-child(3) input[type="text"]
{
background:yellow;
}
No, adding more compound selectors just gives the browser more elements to check and thus more work to do.
If the inputs will only ever appear in a specific place and you can guarantee that they will never appear anywhere else in a given page, then however precise you make your selector beyond input[type="text"] is irrelevant because it will always target the same set of elements anyway. Any extra checks you add then become redundant.
But the real question is whether performance even matters here. Unless you have tens of thousands of such elements, chances are the answer is no. Be as specific as you feel comfortable with. If you need the contextual selectors to make sure you don't accidentally target the wrong elements, there is no harm in putting them in.

Should CSS selectors include elements from the DOM?

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.

div#name vs #name

I know that in a stylesheet div#name and #name do the same thing. Personally I've taken to using div#name for most styling I do, with the reasoning that it's slightly faster, and means that I can identify HTML elements more easily by looking at the CSS.
However all of the big websites I seem to look at use #name over div#name (stack overflow included)
In fact I'm finding it very difficult to find many websites at all that use div#name over #name
Is there some advantage to doing #name that I'm missing? Are there any reasons to use it over div#name that I don't yet know about?
Since the div part of div#name is not required (because ID are unique per page), it makes for smaller CSS files to remove it. Smaller CSS files means faster HTTP requests and page load times.
And as NickC pointed out, lack of div allows one to change the HTML tag of the element without breaking the style rule.
Since ID's have to be unique on the page, most ID's you'd run into would only ever appear once in your style sheet, so it makes sense not to bother including what element it would appear on. Excluding it also saves a few characters in your style sheet, which for large sites which get visited millions and millions of times a day, saves quite a bit of bandwidth.
There is an advantage to including the element name in the case where a division with ID "name" might appear differently than a span with ID "name" (where it would show a division on one type of page and a span on another type of page). This is pretty rare though, and I've never personally run across a site that has done this. Usually they just use different ID's for them.
It's true that including the element name is faster, but the speed difference between including it and excluding it on an ID selector is very, very small. Much smaller than the bandwidth that the site is saving by excluding it.
a matter of code maintainability and readability.
when declaring element#foo the code-style becomes rigid - if one desires to change the document's structure, or replace element types, one would have to change the stylesheets as well.
if declaring #foo we'll better conform to the 'separation of concerns' and 'KISS' principals.
another important issue is the CSS files get minified by a couple of characters, that may build up to many of characters on large stylesheets.
Since an id like #name should be unique to the page, there is no reason per se to put the element with it. However, div#name will have a higher precedence, which may (or may not) be desired. See this fiddle where the following #name does not override the css of div#name.
I would guess that including the element name in your id selector would actually be slower – browsers typically hash elements with id attributes for quicker element look up. Adding in the element name would add an extra step that could potentially slow it down.
One reason you might want to use element name with id is if you need to create a stronger selector. For example you have a base stylesheet with:
#titlebar {
background-color: #fafafa;
}
But, on a few pages, you include another stylesheet with some styles that are unique to those pages. If you wanted to override the style in the base stylesheet, you could beef up your selector:
div#titlebar {
background-color: #ffff00;
}
This selector is more specific (has a higher specificity), so it will overwrite the base style.
Another reason you would want to use element name with id would be if different pages use a different element for the same id. Eg, using a span instead of a link when there is no appropriate link:
a#productId {
color: #0000ff;
}
span#productId {
color: #cccccc;
}
Using #name only:
Well the first obvious advantage would be that a person editing the HTML (template or whatever) wouldn't break CSS without knowing it by changing an element.
With all of the new HTML5 elements, element names have become a lot more interchangeable for the purpose of semantics alone (for example, changing a <div> to be a more semantic <header> or <section>).
Using div#name:
You said "with the reasoning that it's slightly faster". Without some hard facts from the rendering engine developers themselves, I would hesitate to even make this assumption.
First of all, the engine is likely to store a hash table of elements by ID. That would mean that creating a more specific identifier is not likely to have any speed increase.
Second, and more importantly, such implementation details are going to vary browser to browser and could change at any time, so even if you had hard data, you probably shouldn't let it factor into your development.
I use the div#name because the code is more readable in the CSS file.
I also structure my CSS like this:
ul
{
margin: 0;
padding: 0;
}
ul.Home
{
padding: 10px 0;
}
ul#Nav
{
padding: 0 10px;
}
So I'm starting generic and then becoming more specific later on.
It just makes sense to me.
Linking div name: http://jsfiddle.net/wWUU7/1/
CSS:
<style>
div[name=DIVNAME]{
color:green;
cursor:default;
font-weight:bold;
}
div[name=DIVNAME]:hover{
color:blue;
cursor:default;
font-weight:bold;
}
</style>
HTML:
<div name="DIVNAME">Hover This!</div>
List of Css selectors:
http://www.w3schools.com/cssref/css_selectors.asp

Quicker of two CSS rules: with/without multiple IDs specified

So I've recently been doing a lot of work with Concrete5. I noticed, however, that the default theme has many CSS rules which are defined like so:
#page #central #sidebar p{line-height:24px}
Since "sidebar" is an ID there should only be one "sidebar" on the entire page (assuming that it validates, which I'm taking care it does). Therefore if #sidebar is in #page #central, it should always be in #page #central. No matter what. On every page.
By this logic, the following rule does the exact same thing:
#sidebar p{line-height:24px}
Testing this, sure enough, it worked. So my question is- which would have better performance? Is there a speed-related reason that the Concrete5 team went with the longer specification, or was it merely to help future developers locate the #sidebar div? I can see arguments for it being faster in either case.
If case 1 is faster (#page #central #sidebar):
If the browser uses a breadth-first-search algorithm to locate the proper DOM element then finding #sidebar would involve searching the second tier of EVERY DOM element that had children before it reached the third tier, at which point it would still have several elements it looks at before finding #sidebar. By specifying the elements in this way the breadth-first-search would recognize #page and know that it only needs to continue searching within this element, rather than continuing with the entire DOM.
If case 2 is faster (#sidebar):
If the browser searches the entire document in the order it's written, rather than treating the DOM like a tree, then it would be performing a single linear search rather than three linear searches. In fact, even in the best-case scenario where it's smart enough to recognize the start and end points of the previously found DOM element (essentially a depth-first-search), it would still have to read just as many lines of code in a linear search - first it would read until it found #page, then it would start reading from the start of #page until it found #center, then it would read from the start of #center until it found #sidebar. The only difference then would be the slight amount of overhead involved in switching from one search to another
Short story: the more of anything you use, the slower it is to parse.
An ID is always unique, so you should only ever use one; but even with classes, specifying any other elements or criteria is always going to be slower.
http://css-tricks.com/efficiently-rendering-css/
That article goes far more in depth into exactly what you are asking about.
AFAIK there is no feasible way of testing the speed of browsers CSS matching algorithm, and the differences between #page #central #sidebar and #sidebar as far as speed is concerned is so negligible that it's not worth worrying about.
What is worth worrying about is the difference in specificity.
Sometimes it's worth adding an extra id/class/element to a selector to make sure the style doesn't get overwritten by mistake with a simple selector later on in the cascade.
#page #central #sidebar p has a specificity of 3-0-1, while #sidebar p has a specificity of 1-0-1, which means that #page #central #sidebar p will take precedence.
Additionally, you mentioned:
...if #sidebar is in #page #central, it should always be in #page #central. No matter what. On every page.
This is very much not the case, and is important to understand why. Just because an id is unique, does not mean that it must follow the exact same page structure on every page.
For example: a popular content management system (Drupal) allows the developer to specify rules for the placement of blocks on differing areas of different pages. I may want the #search-block to be in the #header on the homepage and then in the #sidebar in all other pages. using a more specific selector would allow me to give the #search-block different styles depending on what its parent containers are.
Performance issues aside, these don't always translate to the same thing.
#header {
background: blue;
}
#home #header {
background: red;
}
This is a perfectly valid use of the cascade to make one page appear different to another. I use this pattern all the time, usually because I assign class or id to my body element, as a hook for CSS and JavaScript.
I don't know about performance, nor do I care, but putting multiple ID selectors together certainly means differently from using just one ID selector, and I'm pretty sure people don't chain selectors like that for performance reasons more than anything else.
#page #central #sidebar p
This only finds p in #sidebar if #sidebar is in #central which is inside #page. Therefore it won't find these #sidebars:
<body>
<div id="sidebar"></div>
</body>
<body>
<div id="page">
<div id="sidebar"></div>
</div>
</body>
<body>
<div id="central">
<div id="sidebar"></div>
</div>
</body>
Again, not sure about performance, but of course the browser has to do more work here because it has to check the DOM hierarchy for each element as it parses this selector from right to left. It's for a real reason; if your CSS says to style #sidebar such and such only if it's found in #page #central, the browser is going to have to do those checks before attempting to apply styles.
#sidebar p
This finds p in #sidebar, wherever in the DOM #sidebar may be located.
Also, maybe I misread your question, but regarding this:
Since "sidebar" is an ID there should only be one "sidebar" on the entire page (assuming that it validates, which I'm taking care it does). Therefore if #sidebar is in #page #central, it should always be in #page #central. No matter what. On every page.
No, not always. You could place #sidebar anywhere, it's just that the selector with all three IDs picks up #sidebar if and only if it lives in #page #central. The only way to satisfy your assumption is to ensure your markup is structured as such. Your styles can't and won't know about your markup, especially not if it's being used to style multiple pages across a site.
With that said, if you can ensure your markup always contains #page #central #sidebar in that structure, then there's no problem with selecting #sidebar alone. My point is that different selectors mean different things and you don't just pick one or the other for performance reasons — more often that not it's beyond that.

What is a better way to set CSS styles?

Example you need to float a bunch of elements.
Option 1 - Chain elements
#elm1, #elm2, #elm3, #elm4 {float:left}
Option 2 - Add a similar class to elements
.float {float:left}
Option 3 - Add style to class individually
#elm1{float:left}
#elm2{float:left}
#elm3{float:left}
#elm4{float:left}
I prefer 1 but I don't know how much of a speed impact it has, are there any other options? Whats the convention for this?
http://css-tricks.com/efficiently-rendering-css/ Seems to say that IDs are the most efficient, although IMHO I would think the class is cleaner and more accurately represents what you are trying to express.
From Google's article # http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
"Avoid a universal key selector.
Allow elements to inherit from ancestors, or use a class to apply a style to multiple elements."
So, I think best practices says use a class. Its clean and readable IMHO.
Use option two (classes) for the global cases. That's what class selectors are meant to do.
Use the ID for styling specific differences. This is what ID selectors are meant to do.
.myclass {
float:left;
height:10px;
}
#elem2 {
height:69px;
color:#ABCDEF;
}
The whole purpose of css is to free html from presentation. Thus the semantic approach is always the good one.
If you use .float { float:left } you might as well use style="float:left"... (okay this is an exageration, but the point is that the less style classes you use the better the separation between presentation and information)
As previously mentioned, the best approach is to semantically identify and classify your html code and then use DOM relationships
#elements {
float:left;
}
#elements li {
color:#ABCDEF
}
#elements li.odd {
color:#123456
}
Most CSS minimizer and "cleaners" will do your first option. In my opinion, it's much better than creating a new class to add to a bunch of elements just for style and it's a million times better than your last option.
In CSS, if it already has an ID or a class, you can apply style to it. So, comparing option 1 to option 2, option 1 should be your better choice. You don't have to go back through your code and add classes to elements that already have IDs and you don't have to juggle style between the ID and the class for the same element in your stylesheet.
As far as speed is concerned, I don't think there is much difference between the 3 options. I think it's more of a maintainability question. It seems like option 1 is going to be easiest to maintain of the options so that's probably what I would go with.
There are certain trade-offs involved. Generally, anything ID-based is believed to be faster, especially as the pages grow heavier. On the other hand, http://net.tutsplus.com/tutorials/html-css-techniques/object-oriented-css-what-how-and-why/ and similar article authors believe that using classes for common rules makes sense and should be used. The speed difference is often negligible and carefully used classes make maintaining and updating design a lot simpler.

Resources