兄弟选择器* + *和*〜*背后的逻辑是什么?

时间:2013-05-22 15:17:06

标签: html css css3 css-selectors

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

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

Selectors Level 3 specification开始,以下选择器规则适用:

*        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段前面没有body或幻像p,但它显然先于某些内容。它应该没有应用任何自定义样式,但在某种程度上受到最后两个选择器的影响。这背后的逻辑是什么?

JSFiddle example

3 个答案:

答案 0 :(得分:21)

* + *设置从文档根开始的任何元素的直接兄弟元素的任何元素 - 因为<head>实际上是正文的前一个兄弟(尽管在代码中不可见)这个选择器的目标是主体和最后两个段落,因为第一段并不紧跟在另一个兄弟元素之后。由于正常流程中块级后代text-decoration的性质,所有三个段落都被加下划线。

* ~ *这与上面基本相同,只是使用general sibling combinator ..它将<head>之后出现的下游兄弟元素设置为样式,无论它们是否是直接兄弟姐妹与否。由于<body>是唯一的兄弟,这与上面的选择器具有相同的效果。由于继承,第一段用斜体表示。

p ~ *选择跟随 a <p>的兄弟元素,在您的示例中是最后两段。 p + *样式任何段落的直接兄弟元素,也可能是最后两个<p>元素。

答案 1 :(得分:20)

它们实际上并未应用于第一段。为了证明这一点,让我们稍微改变一下样式表:

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

demo

fiddle

它们都应用于“body”元素,实际上前面是“head”。

答案 2 :(得分:2)

这是您的测试用例中的错误。正如您所料,没有一个选择器匹配第一段,但是body级联到段落的样式

* + ** ~ *都匹配body,因为前面有head标记。因此,它会收到text-decoration:underlinefont-style:italic。这就解释了为什么所有段落都加下划线和斜体。