For this question, I'm only comparing a browser's speed in rendering the CSS on 2 elements which are different only in that one has a class and one has an id.
(This has nothing to do with JS identification, anchor use, etc.)
<div class="myclass">classed element</div>
<div id="myid">ided element</div>
Does anyone have numbers on this? I have read that CSS ids are 'faster,' but by how much? I'm going to hazard a guess that it's negligible, but it would be interesting to know.
https://web.archive.org/web/20190901050026/http://oli.jp/2011/ids/
ID's are faster in some cases, but not all
It’s a common belief that ID selectors are the fastest, but this comes with a big caveat: IDs are fastest CSS selector only if they’re the key selector. What’s that? Well, while you probably read selectors from left to right, browsers read them from right to left.
There's also a performance test here for your numbers request: https://web.archive.org/web/20190901050026/http://oli.jp/2011/ids/#table1
Conclusion
ID's used correctly are faster, but with such a minimal difference vs classes - it's not worth any consideration.
It seems to me that there are no convincing reasons to use IDs in selectors for CSS styling¹, as CSS classes can do everything IDs can. Hopefully you’ll agree there are some good reasons not to. Think about it the next time you start a personal project or redesign your own site, and try adding a class (or ARIA landmark roles) for styling instead. Save IDs for fragment identifiers or JavaScript hooks
Related
There was a recommendation by Google PageSpeed that asked web developers to Use efficient CSS selectors:
Avoiding inefficient key selectors that match large numbers of
elements can speed up page rendering.
Details
As the browser parses HTML, it constructs an internal document tree
representing all the elements to be displayed. It then matches
elements to styles specified in various stylesheets, according to the
standard CSS cascade, inheritance, and ordering rules. In Mozilla's
implementation (and probably others as well), for each element, the
CSS engine searches through style rules to find a match. The engine
evaluates each rule from right to left, starting from the rightmost
selector (called the "key") and moving through each selector until it
finds a match or discards the rule. (The "selector" is the document
element to which the rule should apply.)
According to this system, the fewer rules the engine has to evaluate
the better. [...]. After that, for pages that contain large numbers of
elements and/or large numbers of CSS rules, optimizing the definitions
of the rules themselves can enhance performance as well. The key to
optimizing rules lies in defining rules that are as specific as
possible and that avoid unnecessary redundancy, to allow the style
engine to quickly find matches without spending time evaluating rules
that don't apply.
This recommendation has been removed from current Page Speed Insights rules. Now I am wondering why this rule was removed. Did browsers get efficient at matching CSS rules in the meantime? And is this recommendation valid anymore?
In Feb 2011, Webkit core developer Antti Koivisto made several improvements to CSS selector performance in Webkit.
Antti Koivisto taught the CSS Style Selector to skip over sibling selectors and faster sorting, which bring some minor improvements, after which he landed two more awesome patches: one which enables ancestor identifier filtering for tree building, halving the remaining time in style matching over a typical page load, and a fast path for simple selectors that speed up matching up another 50% on some websites.
CSS Selector Performance has changed! (For the better) by Nicole Sullivan runs through these improvements in greater detail. In summary -
According to Antti, direct and indirect adjacent combinators can still be slow, however, ancestor filters and rule hashes can lower the impact as those selectors will only rarely be matched. He also says that there is still a lot of room for webkit to optimize pseudo classes and elements, but regardless they are much faster than trying to do the same thing with JavaScript and DOM manipulations. In fact, though there is still room for improvement, he says:
“Used in moderation pretty much everything will perform just fine from the style matching perspective.”
While browsers are much faster at matching CSS selectors, it's worth reiterating that CSS selectors should still be optimised (eg. kept as 'flat' as possible) to reduce file sizes and avoid specificity issues.
Here's a thorough article (which is dated early 2014)
I am quoting Benjamin Poulain, a WebKit Engineer who had a lot to say about the CSS selectors performance test:
~10% of the time is spent in the rasterizer. ~21% of the time is spent
on the first layout. ~48% of the time is spent in the parser and DOM
tree creation ~8% is spent on style resolution ~5% is spent on
collecting the style – this is what we should be testing and what
should take most of the time. (The remaining time is spread over many
many little functions)
And he continues:
“I completely agree it is useless to optimize selectors upfront, but
for completely different reasons:
It is practically impossible to predict the final performance impact
of a given selector by just examining the selectors. In the engine,
selectors are reordered, split, collected and compiled. To know the
final performance of a given selectors, you would have to know in
which bucket the selector was collected, how it is compiled, and
finally what does the DOM tree looks like.
All of that is very different between the various engines, making the
whole process even less predictable.
The second argument I have against web developers optimizing selectors
is that they will likely make things worse. The amount of
misinformation about selectors is larger than correct cross-browser
information. The chance of someone doing the right thing is pretty
low.
In practice, people discover performance problems with CSS and start
removing rules one by one until the problem go away. I think that is
the right way to go about this, it is easy and will lead to correct
outcome.”
There are approaches, like BEM for example, which models the CSS as flat as possible, to minimize DOM hierarchy dependency and to decouple web components so they could be "moved" across the DOM and work regardless.
Maybe because doing CSS for CMSes or frameworks is more common now and it's hard then to avoid using general CSS selectors. This to limit the complexity of the stylesheet.
Also, modern browsers are really fast at rendering CSS. Even with huge stylesheets on IE9, it did not feel like the rendering was slow. (I must admit I tested on a good computer. Maybe there are benchmarks out there).
Anyway, I think you must write very inefficient CSS to slow down Chrome or Firefox...
There's a 2 years old post on performance # Which CSS selectors or rules can significantly affect front-end layout / rendering performance in the real world?
I like his one-liner conclusion : Anything within the limits of "yeah, this CSS makes sense" is okay.
I thought that I understand id's vs classes in css documents. As far as I know there should be only one instance of id element in html document and many class elements. Now I'm looking on Microsoft driven Site.css template which is generated on every new mvc3 project and I see that there is .page element not #page ? Am I missing something here ?
It's become common to only use ids for javascript, and only to use classes for CSS.
There a number of reasons behind this:
Selecting an ID using JS is very fast
ID have a higher specificity than a class
It's a convenient way to split JS and CSS up
As an example:
<a class='btn btn-primary' id='alert' href='#'>Click Me</a>
Would be a typical use, where the btn and btn-primary classes are used for CSS, but the alert id is going to be used in JS.
That means that the link can be restyled without losing the JS link, and can have it's behaviour changed without changing its styling.
It's easier to maintain a nice cascade when using classes. Id's are a really specific way of linking style to your document. Also, at the moment you might have only one element so using id might seem the way to go but what if in the near future you are switching to two.
CSS Specifity
Developers generally use #id if they are looking for applying some javascript to that element, and ID should be unique, where as .whatever is a class which you can use it multiple times..
As you said
Microsoft may be using .page because it must be applying to multiple things, so it's simply not using #page, it doesn't really make a difference, ya but as far as the specifity goes, #id selector has higher precedence than .class
Don't know the Microsoft driven Site.css template at all; but quite frankly I wouldn't take any advice concerning CSS from them: their browser has consistently been the worst of all major browsers in terms of adopting international standards in relation to styling.
There should only be one id of any particular item on a given page; but more than one will still almost certainly work... for styling at least (try it with scripting :p).
Hell, I've just put in the microsoft homepage into the w3c
html validator: 28 Errors, 581 warning(s)
and the w3c CSS validator
We found the following errors (68)
Although arguably many CSS errors may be generated by quite acceptable hacks designed to fix problems in badly designed browsers... principally Microsoft's!
Even so, I'm intrigued about this Microsoft driven Site.css template: any chance you could post a link?
Just as an aditional note: ID in CSS is always given higher priority than class, regardless of order.
I'm wondering why someone would want to use CSS selectors rather than XPath selectors, or vice-versa, if he could use either one. I think that understanding the algorithms that process the languages will resolve my wonder.
There's a lot of documentation on XPath and CSS selectors individually, but I've found very few comparisons. Also, I don't use CSS selectors that much.
Here's what I've read about the differences. (These three references discuss the use of XPath and CSS selectors in Selenium to query HTML, but my wonder is general.)
XPath allows traversal from child to parent
CSS selectors have features specific to HTML
CSS selectors are faster when you're using Internet Explorer in Selenium
It looks like CSS selection algorithms are somehow optimized for HTML, but I don't know how.
Is there a paper on how CSS and XPath query algorithms work and how they differ?
Are there other abstract differences between the languages that I'm missing?
The main difference is in how stable is the document structure you target:
XPath is a good query language when the structure matters and/or is stable. You usually specify path, conditions, exact offset... it is also a good query language to retrieve a set of similar objects and because of that, it has an intimate relationship with XQuery. Here the document has a stable structure and you must retrieve repeated/similar sections
CSS selectors suits better CSS stylesheets. These do not care about the document structure because this changes a lot. Think of one CSS stylesheet applied to all the HTML pages of a website. The content and structure of every page is different. Here CSS selectors are better because of that changing structure. You will notice that access is more tag based. Most CSS syntax specify a set of elements, attributes, id, classes... and not so much their structure. Here you must locate sections that do not have a clear location within a document structure but are marked with certain attributes.
Update: After a closer look to your question I realized that you are more interested in the current implementation, not the nature of the the query languages. In that case I cannot give you the answer you are looking for. I can only suppose that the reason is still that one is more dependent on the structure than the other.
For example, in XPath you must keep track of the structure of the document you are working on. On the other hand CSS selectors are triggered when a specific tag shows up, and it usually does not matter what came before it. I can imagine that it will be much easier to implement a CSS selector algorithm that work as you read a document, while XPath has more cases where you really need the full document and/or strict track of what it is reading (because the history and background of what you are reading is more important)
Now, do not take me too serious on my update. I am only guessing here because I had some background on language parsing, but I actually do not have experience with the ones designed for data querying.
Perhaps this question has been asked elsewhere, but I'm unable to find it. With HTML5 and CSS3 modules inching closer, I'm getting interested in a discussion about the way we write CSS.
Something like this where selection is done via element order and pseudo-classes is particularly fascinating. The big advantage to this method seems to be complete modularization of HTML and CSS to make tweaks and redesigns simpler.
At the same time, semantic IDs and classes seem advantageous for sundry reasons. Particularly, direct linking, JS targeting, and shorter CSS selectors. Also, it seems selector length might be an issue. For instance, I just wrote the following, which would be admittedly easier using some semantic HTML5 elements:
body>div:nth-child(2)>div:nth-child(2)>ul:nth-child(2)>li:last-child
So what say you, Stack Overflow? Is the future of CSS writing focused on element order and pseudo-classes? Or are IDs and classes and the current ways here to stay?
(I'm well aware the IDs and classes have their place, although I am interested to hear more ways you think they'll continue to be necessary. I don't want to misrepresent this or frame it as "Are pseudo-classes ID killers?" The discussion I'm interested in is bigger-picture and the ways writing CSS is changing.)
I think that's an unreadable abomination which will mysteriously stop working when the HTML changes.
Order-based selectors are completely non-self-documenting.
If someone else takes over the project, and the HTML changes, he will have no idea what the selector is supposed to select, and will be hard-pressed to fix it correctly.
This is especially important if any part of the HTML is automatically generated.
Ok so in another question something was being discussed, and this link was mentioned:
https://developer.mozilla.org/en/Writing_Efficient_CSS
In that article, they say some things I didn't know, but before I ask about them, I should ask this... Does that apply to CSS interpreted by Firefox? Forgive my noobness, but I wasn't sure what they meant by Mozilla UI. (don't hurt me!)
If it does apply, when they say:
Avoid the descendant selector!
The descendant selector is the most
expensive selector in CSS. It is
dreadfully expensive, especially if a
rule using the selector is in the tag
or universal category. Frequently what
is really desired is the child
selector. The use of the descendant
selector is banned in UI CSS without
the explicit approval of your skin's
module owner.
* BAD - treehead treerow treecell { }
* BETTER, BUT STILL BAD (see next guideline) - treehead > treerow > treecell { }
The descendant selector is just a space? And then what would the difference be between child and descendant? Child is an element inside another, but isn't that the same as descendant? As I'm writing I think I might have figured it out. A descendant could be a child/grandchild/great-grandchild/etc? And child is only one deep?
Sorry again for the stupid level of my question... just wondering, because I have been constantly using descendants in my CSS for my site. But yeah, if this isn't about Firefox then this whole question is pointless...
If its not about Firefox, does anyone have a link to an article explaining efficiency for Firefox or Browsers in general?
A descendant could be a child/grandchild/great-grandchild/etc? And child is only one deep?
Yes, exactly. Since a child can only be one deep, there's a much smaller space that the rendering engine has to recursively search to check if the rule matches or not.
And yes, that article is about both Firefox and browsers in general. Most (all?) of what is in it applies to any page rendering engine.
First of all - the suggestions in this article are not for html pages - they are specifically for the Mozilla UI - XUL, so it may be best practice for XUL, but not for html.
Applying the CSS on an average HTML page is one of the quickest things than happen while loading the page.
Also, the article may suggest the fastest way to apply css rules, but at what cost? For example, they suggest not having more than one class per rule:
BAD - .treecell.indented { }
GOOD - .treecell-indented { }
That is almost outrageous. It may lead to quicker CSS, but who cares? Assuming you already have .treecell and .indented, following these suggestions leads to complicated logic, harder maintenance, duplicated css rules, harder JavaScript (which costs a lot more that CSS), etc.
They suggest not using the full richness of CSS selectors and replacing these selectors with flat classes, which is a shame.
...as I'm writing I think I might have figured it out. A descendant could be a child/grandchild/great-grandchild/etc? And child is only one deep?
Indeed.
One thing I can add on the efficiency side of things is: Don't use * unless you really mean it. It's pretty intensive as rules go and most people could get away just specifying the elements they really want to target.
A "parent > child" is only one step down, whereas an "ancestor descendant" could be one or more steps down.
Even better is to use "#id" tags wherever possible such that there is less DOM searching.
The UI CSS is for styling the internals of the browser - the settings dialog, extensions interfaces etc.
Descendants and children are different, children are much more specific and result in much less having to be considered.
The problem with the child selector is that it's not as well supported. Of course, this might've been fixed on newer IE browsers.
In any case, when writing CSS for a webpage it isn't going to be that big of a deal. I doubt the fractions of seconds you'd save in page load would even be noticed. This article seems more directed towards people writing stuff for the actual browser, not websites.
O'Reillys "Even Faster Web Sites" has a whole chapter on this entitled "Simplifying CSS Selectors". It references your link on Mozilla.
I think two points are worth bearing in mind.
Yes, if you did this as far as possible, your HTML and CSS would be a mess of styles and possibly even more inefficient due to added file size. It is up to the developer to pick the best balance. Don't agonize over optimizing every line as you write it, get it working then see what can be beneficial.
As another commenter noted, it takes the browser milliseconds to figure it out how to apply your styles on page load. However, where this can have much bigger impact is with DHTML. Every time you change the DOM, the browser re-applies your whole style sheet to the page. In this scenario many inefficient selectors could make a visible impact to your page (perceived lagginess/ unresponsiveness).
The documentation for Google's Page Speed (a Firefox/Firebug add-on) includes a good page on efficient CSS.