Can someone help me explain why:
#id .classname
is worse than:
#id element.classname
from a rendering/performance perspective?
Because the DOM has special functions (getElementByTagName) dedicated to find all elements in a tree by their tag name. These functions use lookup tables and are well optimized. No such method exist for classnames, however, and finding a classname requires to iterate through all the tree(s) and check existing classnames. This algorithm can be made quicker by reducing the size of the trees to iterate, and using an element. prefix does just this: it reduces the size of the trees to look for the classname.
simply because .classname has to check all elements for the specifyed classname, while type.classname only hast to check elements matching the specified type.
I think because in the first example, the browser rendering engine should search for every element with class classname inside the #id element.
The second example would be faster because the engine looks just for every element element with that class.
Sorry for the word game, however this should be non influential from a performance perspective.
It's not.
For the first selector, the browser checks if an element has the class, then it checks if any descendant has the id.
For the second selector, the browser checks if an element has the class, then if checks if the element matches the tag name, then it checks if any descendant has the id.
If the selectors have the same effect, the first selector is better, as the browser has to do fewer checks to match the rule.
More information about efficient selectors: http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
Don't overoptimize your code, make it clear (and this is just about you and your habits, or your team standard) and see about performance later.
When your css selector will be your bottleneck, then you'll have 1 000 engineers working for you.
Related
Given any CSS with a selector like:
.class-xyz:not(.class-xyz) {
...
}
Is it possible that it ever matches any element?
What about augmenting it with things like ::after, ::placeholder and so on?
My intent is to simplify a bunch of huge CSS sheets, with lots of selectors like this.
That selector will not match any element, regardless of namespace (since, even with namespaces present, the outside .class-xyz represents the default namespace, and the one inside the negation always considers the same namespace as the outside selector).
Since that selector will not match any element, it follows that no pseudo-element will be matched. For a pseudo-element to apply, elements need to be matched in the first place.
If you wish to hide a CSS rule without outright deleting the rule or tampering with the original portion of the selector, a shorter way to do so using the negation pseudo-class would be :not(*) (or, if namespaces are present, :not(*|*)). This use case is explicitly given in the level 3 and 4 specs.
But the shortest and clearest way to hide a CSS rule by far is to comment it out.
I am taking practice test for Microsoft 70-480. I came across the question in the image. To select attributes that end in specific given value should be a css attribute selector such as [attribute$='value']. I don't understand how we make that selection with a css pseudo-element. Can some one explain to me why
As you've correctly stated, you need an attribute selector for this (although you would need to use [attribute*=value] instead), and you can't match elements using pseudo-element selectors (that's why they're called pseudo-elements!).
The only explanation for the "correct answer" here being option C is that whoever wrote that test either made a mistake with the options, or doesn't understand CSS selectors. Hopefully the former.
Lets imagine very simple case:
div.className{}
vs
.className{}
Which option is faster and why ?
.className{} is faster in downloading, because of smaller size of the css file.
It is also faster when rendering page, because it is not necessary to look for div elements.
A guideline from google:
Avoid qualifying ID and class names with type selectors. Unless
necessary (for example with helper classes), do not use element names
in conjunction with IDs or classes.
Avoiding unnecessary ancestor selectors is useful for performance reasons .
One very important difference between div.classname and simply .classname is in something called selector specificity. It is a set of rules which defines which selector gets more weight once the browser starts going through all the selectors that potentially have influence on a particular element.
ne of the most basic rules of CSS is that selectors can be redefined in a way that whatever definition comes last and has influence on a particular element its the one that is going to be used (the sole exception being when using !important which always takes precedence).
Now in the above example redefining the .class selector should actually hide the text but instead its still visible. How is that possible if we said that latter rules always take precedence? Its because the div.classname rule has a higher specificity that .box since it actually gets points for containing both an element (div) and a class selector (.class) in its selector declaration (div.class).
Of course the div.class rule will be applied only on a div element but since class selectors are often reusable pieces of code there is plenty of situations when they are used on divs.
Although the rules in the official W3 specification are not that hard to understand they are sometimes pretty hard to remember. That's why I would like to recommend an excellent article on CSS selector specificity which can be found here.
In my opinion selector specificity is by far the most important thing to master when it comes to tracing inheritance problems with CSS stylesheets.
For Example
Find some more info
Follow Up
I have been reading a lot of CSS performance articles, such as;
Efficiently Rendering CSS
Writing efficient CSS selectors
Writing efficient CSS
I get why selectors like this are bad
#social a {
}
As the browser will read a first, then is forced to loop through all the <a> tags in the page.
But why is a selector such as a[title="home"] slower than using a class?
I assume that the browser creates some sort of an index to be able to figure out what elements have a certain class (Correct?).
But shouldn't browsers also have indexed up what elements have a certain attribute? (such as title)?
My question is; why is the CSS / element look up way slower when using selectors such as a[title="home"] compared to using a class? What or how does the browser act in order that the result is so much slower?
Browser implementors optimize the most common cases. Since classes are used very frequently to match styles, they must implement this as efficiently as they can. When they load in CSS, they index the classes to make this possible.
Since random selectors like title="home" are not used very frequently, they can get away with implementing them using simpler searches. It won't have as much impact on performance, because it will rarely be used.
Classes also require special treatment in the browser, because an element may have multiple classes, e.g. class="foo bar baz". When parsing the document, the browser needs to split this up so that it can match any of them against CSS selectors.
Benchmark
Conclusions
In most cases 'attribute selector with unknown attribute, e.g. [a="b"]' and 'attribute selector with known attribute, e.g. [title="a"]' showed up in the '3 Worst' category. It's safe to say you should avoid those selectors.
According to mdn :
The descendant selector is the most expensive selector in CSS. It is
dreadfully expensive—especially if the selector is in the Tag or
Universal Category.
When Modernizr is up , it adds all the non supported classes to the html tag.
Meaning he can later do :
.myNotSupportedClass .myLastDiv <-- notice descendants selecotr[ ]
{
color:red;
}
But this is absolutely slow operation an operation which can be optimized.... which has to go through all the DOM tree in order to find the div.
I know there isn't another way of doing it , but still :
1) they could have added those classes to the body/form which is closer to the elements. soo there will be less of searching.
Or am I wrong ...,?
But this is absolutely slow operation
Eh.
they could have added those classes to the body/form which is closer to the elements. soo there will be less of searching.
body: how much less searching? 1 level less? How much of a difference does that make?
form: not every page has a form, and pages can have more than one form. The form element itself can be placed anywhere in the page body too, so the elements that should be affected by selectors in Modernizr class context may very well be unrelated to it, making searching completely impossible.
Do whatever you like, but since Modernizr chooses to place classes on the html element, write contextual selectors that make use of those classes and the descendant selector. If you're that obsessive about descendant selector performance, you have the choice not to use Modernizr and lose all the feature detection goodness it brings.
Why it chooses to place classes on the html element is anybody's guess. It could have been the most convenient element to place them on.