Is the CSS star selector considered harmful (and why)?
When it comes to performance, Steve Souders is the man:
- Performance Impact of CSS Selectors
- Simplifying CSS Selectors
Shameless quote from one of the reports:
The key to optimizing CSS selectors is
to focus on the rightmost selector,
also called the key selector
(coincidence?). Here’s a much more
expensive selector: A.class0007 * {}.
Although this selector might look
simpler, it’s more expensive for the
browser to match. Because the browser
moves right to left, it starts by
checking all the elements that match
the key selector, “*“. This means the
browser must try to match this
selector against all elements in the
page.
[bold emphasis mine]
What is the performance impact of the universal selector?
In modern browsers the performance impact is negligible, provided you don’t apply slow-effects to every element (eg. box-shadow, z-axis rotation). The myth that the universal-selector is slow is a hangover from ten years ago when it was slow.
Reference: http://www.kendoui.com/blogs/teamblog/posts/12-09-28/css_tip_star_selector_not_that_bad.aspx
Difference between universal and descending selector in CSS
The general rule is to use the universal selector very sparsely due to its bad impact on performance. You basically almost never use it.
The descendant selector, as the name suggests, targets descendants of the element preceding the descendant selector.
Please note that both selectors you show are not exactly the same.
It helps alot to read selector from right to left:
div * .test
targets
- items that have a css class
test
(.test
) - which are descendants
- of any element
*
- which is a descendant
- of a
div
element.
See this example:
div * .test{
color: red;
}
<div>
<div class="test">test</div>
</div>
CSS Universal selector (*) specificity
The universal selector (*
) has no effect on specifity, therefore the latter selector's styles will be the ones that are applied.
An asterisk (*) is the universal selector for CSS. It matches a single
element of any type. Omitting the asterisk with simple selectors has
the same effect. For instance, *.warning and .warning are considered
equal.
Is element-specific CSS selector bad?
.error
is more efficient than p.error
.
To understand why this is more efficient I recommend you read this article over at css tricks.
CSS Specificity and Inheritance
The .container
rule doesn't match the p
element. So specificity is irrelevant here. Inheritance and specificity are separate concepts and the only time they interact is when more specific/less specific rules contain declarations with inherit
. That is not the case here.
As far as the p
element is concerned, only the *
rule applies, and the *
contains its own font-size
declaration, and so the specified font size follows that declaration.
If the *
rule didn't have its own font-size
declaration, then the p
element would inherit from .container
.
If you want descendants of .container
to take after its font size, you will need an additional .container *
rule. Be very careful with the inherit
keyword when it comes to relative values, though — you probably meant to keep all descendants the same size, so 1em
or 100%
is more appropriate here than inherit
:
* { font-size: 18px;}
.container { font-size: 50%;}
.container * { font-size: 1em;}
<div class="container"> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate explicabo fugiat laborum minus ullam? Amet delectus facilis id quam temporibus. </p></div>
CSS selectors Descendant selectors
To answer your question, you need to first understand how CSS rules are interpreted by the browser.
Whenever you write a CSS selector, you can use one or many elements in the selector. For instance, the selector div
has one element, both div p
and div > p
have two.
Think of a CSS selector as several stages of filtering. CSS selectors are actually interpreted by the browser reading them from right to left. When multiple elements are specified in a selector, you first find the set all the elements for the right-most piece, then filter that set by the next piece, and so on.
In the case of the div
rule, we are saying "find me all 'div' elements on the page". Simple enough.
In the case of the div p
rule, we first "find all the 'p' elements on the page". But then, for each of those 'p' elements, we then ask "give me just the 'p' elements that have a 'div' as an ancestor".
Using the same logic, let's describe div * p
: we first "find all the 'p' elements on the page". Next, we ask "give me just the 'p' elements that have a parent element of any kind". From that set, we then ask 'give me just the elements out of this set that have a 'div' as an ancestor".
The selector div * p
would be almost the same as div p
, but with one key difference: the <div>
would have to be at least a grandparent of the <p>
for the selector to match. See http://jsfiddle.net/cDTGY/ for an example.
Related Topics
Show Child Div Within Hidden Parent Div
Html 5 Strange Img Always Adds 3Px Margin At Bottom
Single Huge .Css File Vs. Multiple Smaller Specific .Css Files
How to Force a Div Block to Extend to the Bottom of a Page Even If It Has No Content
Why Does Minmax(0, 1Fr) Work For Long Elements While 1Fr Doesn'T
Flex-Box: Align Last Row to Grid
Bootstrap Dropdown Sub Menu Missing
Which Characters Are Valid in CSS Class Names/Selectors
How to Make Bootstrap Columns All the Same Height
Bootstrap Center Vertical and Horizontal Alignment
How to Really Isolate Stylesheets in the Google Chrome Extension
On a CSS Hover Event, How to Change Another Div'S Styling
Can a CSS Class Inherit One or More Other Classes
Why Is a Flex Item Limited to Parent Size
Fill Remaining Vertical Space With CSS Using Display:Flex
How to Align Button in Center or Right Using Ionic Framework