Pregunta ¿Hay un selector de CSS "hermano anterior"?


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


1031
2017-11-30 04:06


origen


Respuestas:


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 Combinador de hermanos adyacentes de Selectores Nivel 3 y 5.7 Selectores de hermanos adyacentes de Hojas de estilo en cascada Nivel 2 Revisión 1 (CSS 2.1) Especificación.


665
2017-11-30 04:08



Encontré una manera de estilizar a todos los hermanos anteriores (opuesto 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;
}
<div class="parent">
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
</div>


160
2018-01-16 22:45



Selectores de nivel 4 presenta :has() (anteriormente el indicador de tema !) 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.


118
2018-03-19 15:19



Considera el order propiedad 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, el flex order la propiedad 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.

<ul>
    <li>A</li>
    <li>B</li>
</ul>

PASOS

  1. Hacer el ul un contenedor flexible

    ul { display: flex; }
    

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

    <ul>
       <li>B</li>
       <li>A</li>
    </ul>
    

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

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

  1. Usa el flex order propiedad 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;
}
<ul>
    <li>B</li>
    <li>A</li>
</ul>

Desde la especificación flexbox:

5.4. Orden de visualización: el order propiedad

Los elementos Flex se muestran, y se muestran por defecto, en el mismo orden en que aparecen en el documento original. los    order la propiedad se puede usar para cambiar este orden.

los order propiedad controla el orden en que aparecen los elementos flexibles dentro del contenedor flexible, asignándolos a grupos ordinales. Toma un solo <integer> valor, que especifica qué grupo ordinal es el elemento flexible   pertenece a.

La inicial order el valor para todos los artículos flexibles es 0.

Ver también order en la especificación CSS Grid Layout.


Ejemplos de "selectores hermanos anteriores" creados con la flexión order propiedad.

.container { display: flex; }

.box5 { order: 1; }    
.box5:hover + .box4 { background-color: orangered; font-size: 1.5em; }

.box6 { order: -4; }
.box7 { order: -3; }
.box8 { order: -2; }
.box9 { order: -1; }
.box9:hover ~ :not(.box12):nth-child(-1n+5) { background-color: orangered;
                                              font-size: 1.5em; }
.box12 { order: 2; }
.box12:hover ~ :nth-last-child(-1n+2) { background-color: orangered;
                                        font-size: 1.5em; }
.box21 { order: 1; }
.box21:hover ~ .box { background-color: orangered; font-size: 1.5em; }

/* non-essential decorative styles */
.container {
    padding: 5px;
    background-color: #888;
}
.box {
    height: 50px;
    width: 75px;
    margin: 5px;
    background-color: lightgreen;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    cursor: pointer;
}
<p>
Using the flex <code>order</code> property to construct a previous sibling selector
</p>

<div class="container">
    <div class="box box1"><span>1</span></div>
    <div class="box box2"><span>2</span></div>
    <div class="box box3"><span>3</span></div>
    <div class="box box5"><span>HOVER ME</span></div>
    <div class="box box4"><span>4</span></div>
</div>

<br>

<div class="container">
    <div class="box box9"><span>HOVER ME</span></div>
    <div class="box box12"><span>HOVER ME</span></div>
    <div class="box box6"><span>6</span></div>
    <div class="box box7"><span>7</span></div>
    <div class="box box8"><span>8</span></div>
    <div class="box box10"><span>10</span></div>
    <div class="box box11"><span>11</span></div>
</div>

<br>

<div class="container">
    <div class="box box21"><span>HOVER ME</span></div>
    <div class="box box13"><span>13</span></div>
    <div class="box box14"><span>14</span></div>
    <div class="box box15"><span>15</span></div>
    <div class="box box16"><span>16</span></div>
    <div class="box box17"><span>17</span></div>
    <div class="box box18"><span>18</span></div>
    <div class="box box19"><span>19</span></div>
    <div class="box box20"><span>20</span></div>
</div>

jsFiddle


Una nota al margen: dos creencias obsoletas sobre CSS

Flexbox está rompiendo creencias arraigadas sobre CSS.

Una de esas creencias es que un selector de hermanos anterior no es posible en CSS.

Decir que esta creencia es general sería una subestimación. Aquí hay una muestra de preguntas relacionadas solo sobre el desbordamiento de pila:

Como se describió anteriormente, esta creencia no es del todo cierta. Un selector de hermanos anterior se puede simular en CSS utilizando la flexión order propiedad.

los z-index Mito

Otra creencia de larga data ha sido que z-index funciona solo en elementos posicionados

De hecho, la versión más actual de la especificación - el Borrador del editor de W3C - Todavía afirma que esto es cierto:

9.9.1 Especificación del nivel de pila: el z-index   propiedad

z-index

  • Valor: auto | | heredar
  • Inicial: auto
  • Se aplica a: elementos posicionados
  • Heredado: no
  • Porcentajes: N / A
  • Medios: visuales
  • Valor calculado: como se especifica

(énfasis añadido)

En realidad, sin embargo, esta información es obsoleta e inexacta.

Elementos que son flex artículos o elementos de rejilla puede crear contextos de apilamiento incluso cuando position es static.

4.3. Elemento flexible Pedido Z

Los elementos Flex pintan exactamente lo mismo que los bloques en línea, excepto que el orden de documento modificado por orden se utiliza en lugar de   orden del documento, y z-index valores distintos de auto crear un contexto de apilamiento incluso si position es static.

5.4. Orden del eje Z: el z-index propiedad

El orden de pintado de los elementos de la grilla es exactamente el mismo que el de los bloques en línea, excepto que el orden de los documentos modificados es   utilizado en lugar de orden de documento sin procesar, y z-index valores distintos de auto crear un contexto de apilamiento incluso si    position es static.

Aquí hay una demostración de z-index trabajando en elementos flexibles no posicionados: https://jsfiddle.net/m0wddwxs/


99
2018-03-20 18:49



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.


65
2017-11-30 16:40



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

float-right  + invertir 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;
} 
<div>
  <!-- Reverse the order of inner elements -->
  <span>5</span>
  <span>4</span>
  <span>3</span>
  <span>2</span>
  <span>1</span>
</div>


Padre con direction: rtl; + invertir el orden de los elementos internos

.inverse{
  direction: rtl;
  display: inline-block; /* inline-block to keep parent at the left of window */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
  background:gold;
}
Hover one span and see the previous elements being targeted!<br>

<div class="inverse">
  <!-- Reverse the order of inner elements -->
  <span>5</span>
  <span>4</span>
  <span>3</span>
  <span>2</span>
  <span>1</span>
</div>


20
2017-08-19 01:52



Otra solución flexbox

Puede usar el orden inverso de los elementos en HTML. Entonces además de usar 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 i.e. 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%;
}
<div class="flex">
  <div class="flex-item">5</div>
  <div class="flex-item">4</div>
  <div class="flex-item">3</div>
  <div class="flex-item">2</div>
  <div class="flex-item">1</div>
</div>


11
2018-01-14 17:33



¡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 ... (comprobar este enlace si te 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;
}
<p>The oranges elements are the previous sibling li selected using li:nth-child(-n+4)</p>

<div id="list">
  <span>1</span><!-- this will be selected -->
  <p>2</p><!-- this will be selected -->
  <p>3</p><!-- this will be selected -->
  <div>4</div><!-- this will be selected -->
  <div>5</div>
  <p>6</p>
  <p>7</p>
  <p>8</p>
  <p>9</p>
</div>

Limitaciones

  • No puede seleccionar elementos previos basados ​​en las clases de los siguientes elementos
  • Esto es lo mismo para las pseudo clases

11
2017-09-03 16:16



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

Puedes usar los dos hacha Selectores: ! y ?

Existen 2 selectores hermanos posteriores


11
2018-04-25 09:59



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

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

Que seleccionaría todo lis antes de la 3ra (por ejemplo, 1 ° y 2 °). 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.


4
2017-08-29 15:27



Desafortunadamente no hay un selector de hermanos "anterior", pero puedes posiblemente todavía obtiene el mismo efecto al usar 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/


2
2017-08-12 19:39