Quiero escribir un Selector DRY CSS.
El selector debe hacer coincidir elementos dentro de un grupo, pero no elementos dentro de un grupo que sea hijo del grupo dado.
Los elementos solo pueden aparecer como hijos directos de un grupo dado, o están envueltos en un elemento adicional.
Para el DOM dado, el selector estándar sería: .grp.A > .el, .grp.A > * > .el
Esto se puede hacer más SECO usando: :is(.grp.A, .grp.A > *) * .el
Para mí, la solución DRYest sería algo como esto: .grp.A:is(*, * > *) > .el . Pero no funciona. ¿Tiene alguna sugerencia sobre cómo mejorar aún más este selector?
console.log([...document.querySelectorAll(".grp.A > .el, .grp.A > * > .el")]); console.log([...document.querySelectorAll(":is(.grp.A, .grp.A > *) > .el")]); console.log([...document.querySelectorAll(".grp.A:is(*, * > *) > .el")]); <div class="grp A"> <div class="cont"> <div class="grp B"> <div class="el noooooo"></div> </div> </div> <div class="el yes1"></div> <div> <div class="el yes2"></div> </div> </div>Cuando se trata de selectores de CSS, priorizaría la legibilidad sobre la concisión. El primer selector que muestra es el más legible
.grp.A > .el, .grp.A > * > .el
En cuanto a su tercer intento, para citar la especificación CSS Nivel 4 :
Las declaraciones de espacios de nombres predeterminados no afectan al selector compuesto que representa el sujeto de cualquier selector dentro de una pseudoclase :is(), a menos que ese selector compuesto contenga un selector universal explícito o un selector de tipo.
Tuve que leer esto muchas veces, pero entiendo que :is() tiene un alcance global y los selectores que contiene no pueden combinarse en función de lo que hay de antemano.
He agregado un ejemplo adicional en el que un selector compuesto dentro de :is no funciona según lo que hay de antemano.
// Direct child .el of .grp.A or direct child .el of any direct child of .grp.A console.log([...document.querySelectorAll(".grp.A > .el, .grp.A > * > .el")]); // Direct child .el of .grp.A or direct child .el of any direct child of .grp.A console.log([...document.querySelectorAll(":is(.grp.A, .grp.A > *) > .el")]); // Direct child .el of .grp.A that is any element, or // that is any element that's a direct child of any element console.log([...document.querySelectorAll(".grp.A:is(*, * > *) > .el")]); //.grp.A satisfies criteria of being anything, all equating to .grp.A > .el // Additional example that compounds don't work for :is() // Only .A of the two arguments in the :is list works console.log([...document.querySelectorAll(".grp:is(.A, .A > *) > .el")]); <div class="grp A"> <div class="cont"> <div class="grp B"> <div class="el noooooo"></div> </div> </div> <div class="el yes1"></div> <div> <div class="el yes2"></div> </div> </div>