TL; DR
根据规范,以下内容不起作用,但可以:
.a .b + .b {margin-top:20px;}
详细信息
According to the spec“下一个同级组合器”(或“相邻同级组合器”)仅适用于“简单选择器序列”,which themselves are defined为
...一系列不由组合符分隔的简单选择器。
在上面给出的示例中,左侧的选择器.a .b
包含“后代组合器”(由空格表示),因此不应使用。
有趣的是,以下内容实际上根本不起作用:
.b + .a .b {margin-top:20px;}
为什么我的介绍性示例在现代浏览器中有效?
答案 0 :(得分:2)
在the specification中,您可以阅读:
下一个同级组合器由分隔两个简单选择器序列的“加号”(U + 002B,+)字符组成。这两个序列表示的元素在文档树中共享同一父级,而第一个序列表示的元素紧接在第二个序列表示的元素之前。
没有什么可说的,它仅适用于“简单选择器序列” 。简而言之,+
字符将两个简单选择器序列分开,并且没有限制,因此可以有更多选择器。
让我们考虑以下示例:
.a .b + .b
.b + .b
span.a:not(.b) .b + .b > div
在所有这些中,我们都有.b + .b
部分,描述如下:
分隔两个简单选择器序列的“加号”(U + 002B,+)字符。
如果您在本规范的开头阅读了内容,则会发现通用的规则,可以确认这一点:
选择器是由一个或多个序列组成的简单选择器序列,由组合符分隔。一个伪元素可以附加到选择器中最后一个简单选择器序列上。
一系列简单选择器是一系列简单选择器,它们之间没有用组合符分隔。它总是以类型选择器或通用选择器开头。序列中不允许使用其他类型选择器或通用选择器。
一个简单的选择器可以是类型选择器,通用选择器,属性选择器,类选择器,ID选择器或伪类。
基本上我们可以拥有
Seq_simple_selectors + Seq_simple_selectors Seq_simple_selectors > Seq_simple_selectors
然后在每个Seq_simple_selectors
中,我们可以有类似的内容:
div.a.b#id::before
如果我们考虑您的示例.a .b + .b
,则您有3个序列,并且在每个序列中只有一个简单的选择器。
您的第二个示例也很好,并且可以使用正确的HTML进行工作:
.b + .a .b {
background: red;
height: 20px;
}
<div class="b"></div>
<div class="a">
<div class="b"></div>
</div>
无效的是拥有这样的.b + > .a
。在这种情况下,我们没有:
分隔两个简单选择器序列的“加号”(U + 002B,+)字符。
但是我们在一系列简单选择器和一个组合选择器之间是分开的。
答案 1 :(得分:2)
“简单选择器序列”的新名称是compound selector。选择器4中的复合选择器和组合器以及许多其他术语的定义比选择器3中的定义更加清晰,以至于I no longer recommend using selectors-3 as a reference试图理解选择器语法时:
复合选择器 是不由组合器分隔的一系列简单选择器,代表单个元素上的一组同时条件。
组合器 是在任一侧由复合选择器表示的两个元素之间关系的条件。
这应该大大减少可能引起您疑问的困惑,所以我将在答案中仅使用新名称。
在第一个示例中,+
组合器出现在两个复合选择器之间,每个复合选择器都包含一个简单的选择器.b
。换句话说,.b + .b
不是 a 复合选择器...,因为它是两个复合选择器和一个组合器。您的第一个示例是一个有效的复杂选择器,它由三个复合选择器和两个组合器组成。
一个有效的复杂选择器可以包含多少个复合选择器没有限制,只要每两个复合选择器之间是一个组合器而不是一些意外的标记即可。这意味着一个复杂的选择器实际上只能包含一个复合选择器,而没有组合器。这三个示例是有效的复杂选择器(使用selectors-4 grammar中的表示法):
<complex-selector> = <compound-selector>
<complex-selector> = <compound-selector> <combinator> <compound-selector>
<complex-selector> = <compound-selector> <combinator> <compound-selector> <combinator> <compound-selector>
还请记住,不匹配任何内容的复杂选择器仍然有效。
请注意,.b + .a .b
似乎不起作用的原因是,它与.a .b + .b
的含义不同 ,并且您的HTML与标准不匹配该复杂的选择器详细说明了。
.a .b + .b
的意思是
匹配任何
.b
那是另一个.b
的下一个兄弟姐妹
是.a
的后代。
.b + .a .b
的意思是
匹配任何
.b
是.a
的后代
那是另一个.b
的下一个兄弟姐妹。
请注意,另一个.b
是每个上下文中不同元素的先前同级。如果您的HTML满足其中一个条件,但不满足另一个条件,则它将仅与一个条件匹配,而不与另一个条件匹配。但是,以下片段将满足这两个条件(因此两者都匹配):
.a .b + .b { color: red; }
.b + .a .b { font-style: italic; }
code { display: block; }
<div class="b"></div>
<div class="a">
<code class="b">.b</code>
<code class="b">.b + .b</code>
</div>