22

对于这个问题,我使用以下标记:

<body>
    <p>1</p> <!-- Paragraph 1 -->
    <p>2</p> <!-- Paragraph 2 -->
    <p>3</p> <!-- Paragraph 3 -->
</body>

Selectors Level 3 规范中,以下选择器规则适用:

*        any element
E + F    an F element immediately preceded by an E element
E ~ F    an F element preceded by an E element

基于此,应发生以下情况:

body + * { } /* Selects nothing as no elements precede body */
body ~ * { } /* As above. */
p + *    { } /* Selects Paragraph 2 and Paragraph 3 as these are preceded by p */
p ~ *    { } /* As above. */
* + *    { } /* As above. */
* ~ *    { } /* As above. */

错误的!

* + *并且* ~ *能够以某种方式选择第 1 段以及第 2 段和第 3 段!第 1 段前面没有任何内容,因此应该无法访问:

body + * { background: #000; }
body ~ * { background: #000; }
p ~ *    { color: #f00; }
p + *    { font-weight: bold; }
* + *    { text-decoration: underline; }
* ~ *    { font-style: italic; }

结果:

Result example; paragraph 2 and 3 are red and all paragraphs are italic and underlined

如您所见,第 1 段前面没有 thebody或 phantom p,但显然前面有一些东西。它根本不应该应用任何自定义样式,但会受到最后两个选择器的影响。这背后的逻辑是什么?

JSFiddle 示例

4

3 回答 3

21

* + * Styles any element that is an immediate sibling of any element starting from the document root - Since the <head> is actually an immediate preceding sibling of the body (despite not being visible in your code) this selector targets the body and the last two paragraphs, since the first paragraph isn't immediately following another sibling element. All three paragraphs happened to be underlined due to the nature of text-decoration on block-level descendants in the normal flow.

* ~ * This is basically the same thing as above, except using the general sibling combinator .. it styles downstream sibling element(s) that appear after the <head> regardless of whether they're immediate siblings or not. Since the <body> is the only sibling, this has the same effect as the above selector. The first paragraph is italicized due to inheritance.

p ~ * selects a sibling element that is following a <p> which in your example is the last two paragraphs. p + * styles any element that is immediate sibling of a paragraph, which would also be the last two <p> elements.

于 2013-05-22T15:32:07.793 回答
20

They are not applied to the first paragraph actually. To demonstrate this, let's change the stylesheet a bit:

* + *    { border-right: solid red }
* ~ *    { border-left: solid black; }

demo

fiddle

They are both applied to the "body" element which is in fact preceded by "head".

于 2013-05-22T15:33:42.393 回答
2

That's an error in your test case. As you would expect, none of the selectors match the first paragraph, but the styling from the body cascades to the paragraphs!

Both * + * and * ~ * match body as it is preceded by a head tag. Thus, it receives text-decoration:underline and font-style:italic. That explains why all of the paragraphs are both underlined and italicised.

于 2013-05-22T15:32:54.633 回答