理解:nth-​​of-type()和选择器从右到左解析

时间:2015-11-25 05:19:54

标签: css css3 css-selectors

我知道CSS selectors are parsed right to left,以及有关nth-of-type选择器的内容,但是当我编写以下代码时我很困惑:

#container div {
  float: left;
  border: solid 1px #ccc;
  width: 100px;
  height: 100px;
  margin: 10px;
}
#container > div:nth-of-type(2n+1).sub {
  border-color: red;
}
<div id='container'>
  <div class="sub">1</div>
  <div class="sub">2</div>
  <div class="dispear">3</div>
  <div class="sub">4</div>
</div>

因此,当CSS选择器从右向左解析时,浏览器首先查看.sub

<div class="sub">1</div>
<div class="sub">2</div>
<div class="sub">4</div>

然后它会显示div:nth-of-type(2n+1),首先我认为它会匹配:

<div class="sub">1</div>
<div class="sub">4</div>

但结果显示只匹配<div class="sub">1</div>就这么奇怪......

我理解对吗?任何人都可以向我解释一下吗?

2 个答案:

答案 0 :(得分:2)

这是因为您使用的是nth-of-type,而class='disappear的元素也是div元素。 nth-of-type选择器直接在元素类型上工作,并且您添加到它的类条件只是一个附加条件,而不是主要条件。

选择器以这种方式工作 - 选择所有div元素,这些元素是#container的直接子元素,匹配nth-of-type(2n+1)条件,另外class='sub'

#container div, #container p {
  float: left;
  border: solid 1px #ccc;
  width: 100px;
  height: 100px;
  margin: 10px;
}
#container>div:nth-of-type(2n+1).sub {
  border-color: red;
}

/* just for demo */

#container{
  clear: both;
}
<div id='container'>
  <div class="sub">1</div> <!-- this would be selected -->
  <div class="sub">2</div>
  <div class="sub">3</div> <!-- this would also be selected because it matches both -->
  <div class="sub">4</div>
</div>

<div id='container'>
  <div class="sub">1</div> <!-- this would be selected -->
  <div class="sub">2</div>
  <p class="disappear">3</p>
  <div class="sub">4</div> <!-- this would be selected because it is 3rd div and has sub class -->
</div>

<div id='container'>
  <div class="sub">1</div> <!-- this would be selected -->
  <div class="sub">2</div>
  <div class="disappear">3</div> <!-- this won't be selected because it is 3rd div but doesn't have the required class -->
  <div class="sub">4</div> <!-- this won't be selected because it has required class but doesn't match nth-of-type(2n+1) which is the primary -->
</div>

答案 1 :(得分:2)

这与RTL匹配无关,因为问题不在于#container >部分,而在于div:nth-of-type(2n+1).sub部分本身,RTL匹配根本不适用。您对浏览器如何评估选择器的评估充其量是不准确的。

RTL匹配实际上意味着典型的浏览器遍历整个DOM,为DOM中的每个元素查找候选规则,并查看哪些匹配。这意味着浏览器会评估每个一个div元素,并独立评估每个元素的所有候选选择器。对于每个选择器,浏览器首先将目标元素与键选择器进行比较,键选择器是最后一个组合器之后最右边的一组简单选择器(在这种情况下,整个div:nth-of-type(2n+1).sub部分作为一个单元),然后只需继续匹配元素子树中的元素,就可以通过复杂选择器的其余部分从右到左

:nth-of-type()按元素类型计算,即div。就这些。该类仅与div元素必须具有该类才能应用样式相关,并且它不会以任何方式影响:nth-of-type()的计数,这就是为什么尽管div.dispear :nth-of-type(2n+1),但grails.databinding.convertEmptyStringsToNull=false grails.databinding.trimStrings=false 仍然无法匹配。

另请参阅:Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?