La serie Thinking tiene como objetivo transmitir una idea de programación que se puede implementar en 10 minutos.
Durante el desarrollo, encontré una solicitud de este tipo: un elemento de una clase específica ocupa una sola línea, y ahora es necesario agregar un logotipo correspondiente a su elemento hermano anterior para que ocupe todo el espacio restante en la línea.
En otras palabras: cómo seleccionar el elemento hermano anterior de una clase específica. ( Cómo seleccionar el elemento b
antes de cada elementoa
a continuación )
¡CSS no tiene un selector para seleccionar el elemento hermano anterior! ¡CSS no tiene un selector para seleccionar el elemento hermano anterior!
¿Por qué?
diseño de flujo
Elementos de bloque: colocados en la *dirección de flujo de bloque* según el orden de escritura de su elemento principal ( predeterminado: horizontal-tb): cada elemento de nivel de bloque comenzará una nueva línea debajo del elemento anterior. => de arriba a abajo
Elementos en línea: se organizan en la misma línea que otros elementos en línea, contenido de texto adyacente (o envuelto) si el ancho del elemento de nivel de bloque principal tiene suficiente espacio. Si no hay suficiente espacio, el texto o los elementos desbordados se moverán a una nueva línea. ==> de izquierda a derecha
pensar
Conociendo la forma de diseño de flujo normal del navegador (de izquierda a derecha, de arriba hacia abajo), podemos saber que la razón por la cual CSS no lo admite se debe a su diseño de flujo.
Si el elemento hermano anterior puede ser seleccionado por el elemento actual, ¡puede causar una operación de redibujado adicional!
CSS SIGUIENTE
:has( <forgiving-relative-selector-list> )
:has()
Representa un elemento que coincide con al menos un elemento si se pasa algún selector relativo como argumento , cuando está anclado a ese elemento. Esta pseudoclase proporciona una forma de seleccionar el padre o el hermano anterior de un elemento al que se hace referencia tomando una lista de selectores relativos tolerantes a fallas como argumento .
Especificación relevante: https://www.w3.org/TR/selectors-4/#relational
Dirección MDN: https://developer.mozilla.org/zh-CN/docs/Web/CSS/:has
Para lograr las demandas anteriores:
.a:has(+ .b) {
background-color: blue;
}
Su soporte de navegador actual no es particularmente ideal (Firefox tampoco lo soporta)
solución
El elemento hermano anterior no se puede seleccionar, lo que se debe al diseño de flujo. ¿Podemos cambiar el método de diseño para resolverlo?
Invierta las propiedades de flex flex-direction: row-reverse;
, por lo que la pregunta es: ¿ cómo seleccionar el siguiente elemento hermano de una clase específica?
div {
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
}
li {
display: inline-block;
width: 30px;
height: 30px;
margin-right: 10px;
background-color: gainsboro;
}
.b+.a {
background-color: blue;
}
Cabe señalar que el orden DOM debe invertirse en este momento.
<div>
<li class="b">b</li>
<li class="a">a</li>
<li class="b">b</li>
<li class="a">a</li>
<li class="a">a</li>
<li class="b">b</li>
<li class="a">a</li>
<li class="a">a</li>
<li class="a">a</li>
<li class="a">a</li>
</div>
¡Lo anterior se puede lograr!
Resumir
"Dado que no hay un selector para seleccionar el elemento hermano anterior", el diseño se invierte (de derecha a izquierda), por lo que la pregunta se convierte en "cómo seleccionar el siguiente elemento hermano".
La forma de resolver este problema no es difícil, pero vale la pena ampliar la idea.