¿Hay un selector de CSS “hermano anterior”?

+ es para el próximo hermano. ¿Hay un equivalente para el hermano anterior?

No, no hay selector de “hermanos anteriores”.

En una nota relacionada, ~ es para hermano sucesor general (es decir, el elemento viene después de este, pero no necesariamente inmediatamente después) y es un selector de CSS3. + es para el próximo hermano y es CSS2.1.

Ver el combinador de hermanos adyacente de los selectores Nivel 3 y 5.7 Selectores de hermanos adyacentes de las hojas de estilo en cascada Revisión de nivel 2 1 (CSS 2.1) .

Encontré una manera de estilizar a todos los hermanos anteriores (opuestos a ~ ) que pueden funcionar dependiendo de lo que necesites.

Supongamos que tiene una lista de enlaces y al pasar el ratón sobre uno, todos los anteriores deben ponerse rojos. Puedes hacerlo así:

 /* default link color is blue */ .parent a { color: blue; } /* prev siblings should be red */ .parent:hover a { color: red; } .parent a:hover, .parent a:hover ~ a { color: blue; } 
  

Selectores nivel 4 introduce :has() (anteriormente el indicador de sujeto ! ) Que le permitirá seleccionar un hermano anterior con:

 previous:has(+ next) {} 

… pero en el momento de escribir esto, está un poco más allá del límite de compatibilidad con el navegador.

Considere la propiedad order de los diseños de flex y grid.

Me centraré en flexbox en los ejemplos a continuación, pero los mismos conceptos se aplican a Grid.


Con flexbox, se puede simular un selector de hermanos anterior.

En particular, la propiedad de order flexible puede mover elementos alrededor de la pantalla.

Aquí hay un ejemplo:

Desea que el elemento A se ponga rojo cuando el elemento B está suspendido.

 
  • A
  • B

PASOS

  1. Haga que el ul un contenedor flexible.

     ul { display: flex; } 

  1. Invierta el orden de los hermanos en el recargo.

     
    • B
    • A

  1. Use un selector de hermanos para apuntar al Elemento A ( ~ o + lo hará).

     li:hover + li { background-color: red; } 

  1. Use la propiedad de order flexible para restaurar el orden de los hermanos en la pantalla visual.

     li:last-child { order: -1; } 

…¡y voilá! Un selector de hermanos anterior nace (o al menos simulado).

Aquí está el código completo:

 ul { display: flex; } li:hover + li { background-color: red; } li:last-child { order: -1; } /* non-essential decorative styles */ li { height: 200px; width: 200px; background-color: aqua; margin: 5px; list-style-type: none; cursor: pointer; } 
 
  • B
  • A

Tenía la misma pregunta, pero luego tuve un momento “duh”. En lugar de escribir

 x ~ y 

escribir

 y ~ x 

Obviamente, esto coincide con “x” en lugar de “y”, pero responde “¿hay una coincidencia?” pregunta, y el recorrido DOM simple puede llegar al elemento correcto de manera más eficiente que el bucle en JavaScript.

Me doy cuenta de que la pregunta original era una pregunta de CSS, por lo que esta respuesta probablemente sea completamente irrelevante, pero otros usuarios de Javascript pueden tropezar con la pregunta a través de la búsqueda como yo.

Dos trucos . Básicamente, invertir el orden HTML de los elementos deseados en HTML y usar
~ Siguiente operador de hermanos :

float-right + reverse el orden de los elementos HTML

 div{ /* Do with the parent whatever you know just to make the inner float-right elements appear where desired */ display:inline-block; } span{ float:right; /* float-right the elements! */ } span:hover ~ span{ /* On hover target it's "previous";) elements */ background:red; } 
 
5 4 3 2 1

+ es para el próximo hermano. ¿Hay un equivalente para el hermano anterior?

Puede usar los dos selectores de hacha :! y ?

Hay 2 selectores de hermanos posteriores en CSS convencional:

  • + es el selector de hermanos inmediatamente posterior
  • ~ es el selector de hermanos subsiguiente

En CSS convencional, no hay selector de hermanos anterior .

Sin embargo, en la biblioteca de postprocesador CSS de ax , hay 2 selectores hermanos anteriores:

  • ? es el selector hermano anterior inmediato (opuesto a + )
  • ! es el selector de hermanos anterior (opuesto a ~ )

Ejemplo de trabajo:

En el siguiente ejemplo:

  • .any-subsequent:hover ~ div selecciona cualquier div posterior
  • .immediate-subsequent:hover + div selecciona el div inmediato siguiente
  • .any-previous:hover ! div .any-previous:hover ! div selecciona cualquier div anterior
  • .immediate-previous:hover ? div .immediate-previous:hover ? div selecciona el div anterior inmediato
 div { display: inline-block; width: 60px; height: 100px; color: rgb(255, 255, 255); background-color: rgb(255, 0, 0); text-align: center; vertical-align: top; cursor: pointer; opacity: 0; transition: opacity 0.6s ease-out; } code { display: block; margin: 4px; font-size: 24px; line-height: 24px; background-color: rgba(0, 0, 0, 0.5); } div:nth-of-type(-n+4) { background-color: rgb(0, 0, 255); } div:nth-of-type(n+3):nth-of-type(-n+6) { opacity: 1; } .any-subsequent:hover ~ div, .immediate-subsequent:hover + div, .any-previous:hover ! div, .immediate-previous:hover ? div { opacity: 1; } 
 

Hover over any of the blocks below

Hover for ? selector
Hover for ! selector
Hover for ~ selector
Hover for + selector

Otra solución flexbox

Puede usar el orden inverso de los elementos en HTML. Luego, además de usar el order como en la respuesta de Michael_B, puedes usar flex-direction: row-reverse; o flex-direction: column-reverse; dependiendo de tu diseño

Muestra de trabajo:

 .flex { display: flex; flex-direction: row-reverse; /* Align content at the "reversed" end ie beginning */ justify-content: flex-end; } /* On hover target its "previous" elements */ .flex-item:hover ~ .flex-item { background-color: lime; } /* styles just for demo */ .flex-item { background-color: orange; color: white; padding: 20px; font-size: 3rem; border-radius: 50%; } 
 
5
4
3
2
1

¡No hay manera oficial de hacerlo en este momento, pero puedes usar un pequeño truco para lograrlo! Recuerde que es experimental y tiene alguna limitación … (consulte este enlace si le preocupa la compatibilidad del navegador)

Lo que puedes hacer es usar un selector CSS3: el pseudo classe llamado nth-child()

 #list>* { display: inline-block; padding: 20px 28px; margin-right: 5px; border: 1px solid #bbb; background: #ddd; color: #444; margin: 0.4em 0; } #list :nth-child(-n+4) { color: #600b90; border: 1px dashed red; background: orange; } 
 

The oranges elements are the previous sibling li selected using li:nth-child(-n+4)

1

2

3

4
5

6

7

8

9

Si conoce la posición exacta, una exclusión basada en :nth-child() de todos los hermanos siguientes funcionaría.

 ul li:not(:nth-child(n+3)) 

Que seleccionaría todas las li s antes de la 3ra (ej. 1ra y 2da). Pero, en mi opinión, esto se ve feo y tiene un uso muy apretado.

También puede seleccionar el enésimo hijo de derecha a izquierda:

 ul li:nth-child(-n+2) 

Que hace lo mismo.

Desafortunadamente, no hay un selector de hermanos “anterior”, pero posiblemente pueda obtener el mismo efecto al usar el posicionamiento (por ejemplo, flotar a la derecha). Depende de lo que estés tratando de hacer.

En mi caso, quería un sistema de calificación de 5 estrellas principalmente CSS. Tendría que colorear (o cambiar el icono de) las estrellas anteriores. Al flotar cada elemento correctamente, esencialmente obtengo el mismo efecto (el html para las estrellas debe escribirse ‘hacia atrás’).

Estoy usando FontAwesome en este ejemplo e intercambio entre los unicodes de fa-star-o y fa-star http://fortawesome.github.io/Font-Awesome/

CSS:

 .fa { display: inline-block; font-family: FontAwesome; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* set all stars to 'empty star' */ .stars-container { display: inline-block; } /* set all stars to 'empty star' */ .stars-container .star { float: right; display: inline-block; padding: 2px; color: orange; cursor: pointer; } .stars-container .star:before { content: "\f006"; /* fontAwesome empty star code */ } /* set hovered star to 'filled star' */ .star:hover:before{ content: "\f005"; /* fontAwesome filled star code */ } /* set all stars after hovered to'filled star' ** it will appear that it selects all after due to positioning */ .star:hover ~ .star:before { content: "\f005"; /* fontAwesome filled star code */ } 

HTML: (40)

JSFiddle: http://jsfiddle.net/andrewleyva/88j0105g/

Dependiendo de su objective exacto, hay una manera de lograr la utilidad de un selector principal sin usar uno (incluso si existiera) …

Digamos que tenemos:

  

¿Qué podemos hacer para que el bloque Calcetines (incluidos los colores de los calcetines) se destaque visualmente mediante el espaciado?

Lo que sería bueno pero no existe:

 ul li ul:parent { margin-top: 15px; margin-bottom: 15px; } 

Lo que existe:

 li > a { margin-top: 15px; display: block; } li > a:only-child { margin-top: 0px; } 

Esto establece que todos los enlaces de anclaje tengan un margen de 15 píxeles en la parte superior y lo restablece a 0 para aquellos que no tienen elementos UL (u otras tags) dentro de LI.

Tuve un problema similar y descubrí que todos los problemas de esta naturaleza se pueden resolver de la siguiente manera:

  1. dales a todos tus artículos un estilo.
  2. dale un estilo al elemento seleccionado
  3. Da estilo a los siguientes elementos usando + o ~.

y de esta manera podrás diseñar tus artículos actuales y anteriores (todos los artículos anulados con los artículos actuales y siguientes) y tus próximos artículos.

ejemplo:

 /* all items (will be styled as previous) */ li { color: blue; } /* the item i want to distinguish */ li.milk { color: red; } /* next items */ li ~ li { color: green; } 
  • Tea
  • Milk
  • Juice
  • others

Espero que ayude a alguien.

Como ya se ha dicho muchas veces, con div ~ p todos los elementos

que están precedidos por un elemento

.

Consulte esta lista de todos los selectores de CSS.