¿Cuál es la lógica detrás de los selectores hermanos * + * y * ~ *?

Para esta pregunta estoy usando el siguiente marcado:

 

1

2

3

A partir de la especificación Level 3 de Selectors, se aplican las siguientes reglas de selector:

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

En base a esto, lo siguiente debería ocurrir:

 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. */ 

¡Falso!

* + * y * ~ * alguna manera son capaces de seleccionar el Párrafo 1 junto con 2 y 3. El párrafo 1 no está precedido por nada, por lo que debe ser imposible acceder:

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

Resultado:

Ejemplo de resultado; los párrafos 2 y 3 son rojos y todos los párrafos están en cursiva y subrayados

Como puede ver, el párrafo 1 no está precedido por el body o un p fantasma, sin embargo, aparentemente está precedido por algo. No debe tener ningún estilo personalizado aplicado en absoluto, pero de alguna manera se ve afectado por los dos últimos selectores. ¿Cuál es la lógica detrás de esto?

Ejemplo JSFiddle .

* + * Estilos de cualquier elemento que sea un hermano inmediato de cualquier elemento a partir de la raíz del documento: como es en realidad un hermano anterior inmediato del cuerpo (a pesar de no ser visible en el código), este selector apunta al cuerpo y al los dos últimos párrafos, ya que el primer párrafo no sigue inmediatamente a otro elemento hermano. Los tres párrafos pasaron a estar subrayados debido a la naturaleza de text-decoration de text-decoration en descendientes de nivel de bloque en el flujo normal.

* ~ * Esto es básicamente lo mismo que el anterior, excepto que usa el combinador hermano general . Estilos elemento (s) hermano (s) descendente (s) que aparecen después del independientemente de si son hermanos inmediatos o no. Como es el único hermano, tiene el mismo efecto que el selector anterior. El primer párrafo está en cursiva debido a la herencia.

p ~ * selecciona un elemento hermano que está siguiendo a un

que en su ejemplo son los dos últimos párrafos. p + * estiliza cualquier elemento que sea hermano inmediato de un párrafo, que también serían los dos últimos

elementos.

No se aplican en realidad al primer párrafo. Para demostrar esto, cambiemos la hoja de estilo un poco:

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

manifestación

violín

Ambos se aplican al elemento “cuerpo” que de hecho está precedido por “cabeza”.

Eso es un error en tu caso de prueba. Como era de esperar, ninguno de los selectores coincide con el primer párrafo, ¡pero el estilo del body cascada a los párrafos !

Ambos * + * y * ~ * coinciden con el body ya que está precedido por una etiqueta de head . Por lo tanto, recibe text-decoration:underline y font-style:italic . Eso explica por qué todos los párrafos están subrayados y en cursiva.