Cuando hablamos de CSS, muchas veces nos quedamos en lo superficial: aplicar colores, márgenes y tipografías. Pero lo cierto es que detrás de esta hoja de estilo hay una potencia mucho mayor, especialmente si empezamos a explorar lo que el lenguaje nos ofrece en su versión más moderna. Hoy nos adentramos en un territorio menos conocido, pero enormemente útil: los selectores avanzados y pseudo-clases complejas.
Este artículo no es un manual de referencia ni un listado exhaustivo. Pretende ser una guía divulgativa, escrita con la intención de ayudarte a entender cuándo y por qué usar selectores que a menudo pasamos por alto, pero que pueden marcar una gran diferencia en la organización, legibilidad y eficiencia de tus hojas de estilo.
1. :not(): la lógica del «todo menos»
Empezamos con uno que sí es algo más conocido, pero que aún no se aprovecha del todo: :not(). Este selector permite excluir elementos de una regla, lo que puede ahorrarnos líneas de código y aumentar la expresividad de nuestras hojas de estilo.
button:not(.primario) {
background-color: transparent;
border: 1px solid #ccc;
}
En este ejemplo, todos los botones recibirán el estilo, excepto los que tengan la clase .primario. Hasta aquí bien. Pero lo interesante es que :not() puede anidarse y combinarse con otros selectores:
div:not(.oculto):not(.cerrado) {
display: block;
}
A partir de CSS Selectors Level 4, incluso puedes hacer cosas como:
li:not(:last-child)::after {
content: ", ";
}
Esto añade una coma después de cada elemento de lista, excepto el último. Útil, ¿verdad?
2. :nth-child() con parámetros avanzados
Todos conocemos :nth-child(even) o :nth-child(3n+1), pero lo que muchos desarrolladores desconocen es que se pueden filtrar por clase dentro de :nth-child(), utilizando una sintaxis más avanzada propuesta en CSS4:
li:nth-child(odd of .destacado) {
background-color: #f9f9f9;
}
Esto aplicaría el estilo solo a los elementos impares entre aquellos que tengan la clase .destacado. Es importante saber que este selector aún no está soportado por todos los navegadores, por lo que su uso en producción requiere precaución. Sin embargo, el concepto nos abre la puerta a un CSS más expresivo y semántico.
3. :has(): el selector «padre»
Este es, sin duda, uno de los selectores más esperados y revolucionarios. Hasta ahora, CSS no podía seleccionar elementos en función de su descendencia. Pero eso ha cambiado con :has(), ya soportado por navegadores como Safari y las versiones modernas de Chrome.
div:has(> img.destacada) {
border: 2px solid gold;
}
Este selector aplica estilos al div solo si contiene una imagen con la clase .destacada como hija directa. Por primera vez, CSS nos permite mirar hacia dentro del DOM desde arriba hacia abajo y aplicar estilos al contenedor. Esto tiene aplicaciones muy potentes en interfaces dinámicas:
form:has(input:invalid) {
border-color: red;
}
Este estilo marcará todo el formulario si alguno de sus campos es inválido, sin necesidad de añadir clases desde JavaScript.
4. Combinadores ~ y +: la posición importa
Los combinadores en CSS permiten seleccionar elementos en función de su posición relativa respecto a otros. Son menos usados que los selectores clásicos, pero su potencia es innegable.
El combinador adyacente +
h2 + p {
margin-top: 0;
}
Selecciona el primer <p> que sigue inmediatamente a un <h2>. Es útil para ajustar márgenes sin modificar todo el bloque.
El combinador de hermanos generales ~
input:checked ~ label {
font-weight: bold;
}
Esto aplica estilos a todos los label hermanos de un input marcado. Ideal para componentes como tabs o listas de selección donde se quiere que el resto del contenido reaccione al estado de un input.
5. ¿Cómo aplicar esto en proyectos reales?
Aquí van algunos consejos prácticos para incorporar estos selectores a tu flujo de trabajo:
- Haz tu CSS más declarativo. Usa selectores avanzados para evitar añadir clases innecesarias desde JavaScript.
- Mejora la accesibilidad visual con selectores como
:focus-visible, combinados con:not(). - Usa
:has()para detección de estado sin JS, como formularios con errores, tarjetas activas o sliders con contenido destacado. - Evita la repetición de reglas con
:not()y:nth-child().
6. Consideraciones de compatibilidad
:not()y combinadores (+,~) son ampliamente compatibles.:has()está en proceso de adopción, por lo que conviene usarlo con progresive enhancement.:nth-child(odd of .clase)pertenece a la especificación CSS Selectors Level 4 y aún tiene soporte limitado.
Consulta caniuse.com antes de implementar estas técnicas en producción.
Los selectores avanzados y las pseudo-clases poco conocidas pueden parecer detalles técnicos sin importancia, pero bien utilizados, nos permiten escribir CSS más limpio, expresivo y mantenible. Además, reducen la necesidad de JavaScript para gestionar estados y clases, lo que se traduce en interfaces más rápidas y accesibles.
La clave está en conocer estas herramientas, entender su propósito y aplicarlas con criterio. Porque dominar CSS no es solo saber alinear elementos: es entender el poder que nos da para crear interfaces inteligentes y elegantes.




Deja un comentario