- What is the difference between
ul > li > a {...}
andul li a {...}
in CSS? - Which one is more efficient and why?
问题:
回答1:
">
" is the child selector
"" is the descendant selector
The difference is that a descendant can be a child of the element, or a child of a child of the element or a child of a child of a child ad inifinitum.
A child element is simply one that is directly contained within the parent element:
<foo> <!-- parent -->
<bar> <!-- child of foo, descendant of foo -->
<baz> <!-- descendant of foo -->
</baz>
</bar>
</foo>
for this example, foo *
would match <bar>
and <baz>
, whereas foo > *
would only match <bar>
.
As for your second question:
Which one is more efficient and why?
I'm not actually going to answer this question as it's completely irrelevant to development. CSS rendering engines are so fast that there is almost never* a reason to optimize CSS selectors beyond making them as short as possible.
Instead of worrying about micro-optimizations, focus on writing selectors that make sense for the case at hand. I often use >
selectors when styling nested lists, because it's important to distinguish which level of the list is being styled.
* if it genuinely is an issue in rendering the page, you've probably got too many elements on the page, or too much CSS. Then you'll have to run some tests to see what the actual issue is.
回答2:
ul>li
selects all li
that are a direct child of ul
whereas ul li
selects all li
that are anywhere within (descending as deep as you like) a ul
For HTML:
<ul>
<li><span><a href='#'>Something</a></span></li>
<li><a href='#'>or Other</a></li>
</ul>
And CSS:
li a{ color: green; }
li>a{ color: red; }
The colour of Something
will remain green but or Other
will be red
Part 2, you should write the rule to be appropriate to the situation, I think the speed difference would be incredibly small, and probably overshadowed by the extra characters involved in writing more code, and definitely overshadowed by the time taken by the developer to think about it.
However, as a rule of thumb, the more specific you are with your rules, the faster the CSS engines can locate the DOM elements you want to apply it to, so I expect li>a
is faster than li a
as the DOM search can be cut short earlier. It also means that nested anchors are not styled with that rule, is that what you want? <~~ much more pertinent question.
回答3:
ul > li > a
selects only the direct children. In this case only the first level <a>
of the first level <li>
inside the <ul>
will be selected.
ul li a
on the other hand will select ALL <a>
-s in ALL <li>
-s in the unordered list
Example of ul > li
ul > li.bg {
background: red;
}
<ul>
<li class="bg">affected</li>
<li class="bg">affected</li>
<li>
<ol>
<li class="bg">NOT affected</li>
<li class="bg">NOT affected</li>
</ol>
</li>
</ul>
if you'd be using ul li
- ALL of the li
-s would be affected
UPDATE The order of more to less efficient CSS selectors goes thus:
- ID, e.g.
#header
- Class, e.g.
.promo
- Type, e.g.
div
- Adjacent sibling, e.g.
h2 + p
- Child, e.g.
li > ul
- Descendant, e.g.
ul a
- Universal, i.e.
*
- Attribute, e.g.
[type="text"]
- Pseudo-classes/-elements, e.g.
a:hover
So your better bet is to use the children
selector instead of just descendant
. However the difference on a regular page (without tens of thousands elements to go through) might be absolutely negligible.
回答4:
1) for example HTML code:
<ul>
<li>
<a href="#">firstlink</a>
<span><a href="#">second link</a>
</li>
</ul>
and css rules:
1) ul li a {color:red;}
2) ul > li > a {color:blue;}
">" - symbol mean that that will be searching only child selector (parentTag > childTag)
so first css rule will apply to all links (first and second) and second rule will apply anly to first link
2) As for efficiency - I think second will be more fast - as in case with JavaScript selectors. This rule read from right to left, this mean that when rule will parse by browser, it get all links on page: - in first case it will find all parent elements for each link on page and filter all links where exist parent tags "ul" and "li" - in second case it will check only parent node of link if it is "li" tag then -> check if parent tag of "li" is "ul"
some thing like this. Hope I describe all properly for you
回答5:
to answer to your second question - performance IS affected - if you are using those selectors with a single (no nested) ul:
<ul>
<li>jjj</li>
<li>jjj</li>
<li>jjj</li>
</ul>
the child selector ul > li
is more performant than ul li
because it is more specific. the browser traverse the dom "right to left", so when it finds a li
it then looks for a any ul
as a parent in the case of a child selector, while it has to traverse the whole dom tree to find any ul
ancestors in case of the descendant selector