Funciones de CSS moderno: nesting, :has(), container queries y subgrid
Funciones de CSS moderno con demos en vivo
CSS moderno: nesting, :has(), container queries y subgrid | We.Inc
Demos editables en vivo de nesting nativo en CSS, el selector :has(), container queries, subgrid, @layer, :is(), color-mix() y text-wrap: balance, con una tabla de soporte Baseline.
El CSS puro ya hace tareas que antes requerían Sass o JavaScript. El nesting nativo agrupa reglas relacionadas, :has() estiliza un padre según sus hijos, las container queries adaptan un componente a su propio ancho y subgrid alinea los elementos anidados con la cuadrícula exterior. Las cuatro llegaron a Baseline en 2023, así que los navegadores actuales las soportan.
Las funciones principales de un vistazo
Función
Sustituye a
Baseline desde
Nesting
El anidamiento al estilo Sass en un preprocesador
:has()
JavaScript que activa una clase en el padre
Container queries de tamaño
Media queries de viewport dentro de componentes
Subgrid
Alturas fijas para alinear filas de tarjetas
Cada función de abajo tiene una demo que puedes editar, y la tarjeta de container queries responde a un deslizador para que veas cómo cambia de diseño sin redimensionar la ventana. La tabla de soporte indica el año en que cada función pasó a Baseline, es decir, que funciona en las últimas versiones de Chrome, Edge, Firefox y Safari.
Arrastra el deslizador de ancho de la demo de container queries y observa cómo la tarjeta pasa de apilada a lado a lado.
Edita cualquier ejemplo de la izquierda. El resultado aislado de la derecha se vuelve a dibujar mientras escribes.
Consulta la tabla de soporte antes de publicar. Baseline significa los cuatro motores principales, no versiones antiguas.
Copia el fragmento que necesites. Ninguno requiere un paso de compilación ni una biblioteca.
Mantén el nesting poco profundo. Dos niveles suelen bastar, y el anidamiento profundo produce selectores largos y de alta especificidad, igual que pasaba en Sass.
Las container queries necesitan un contenedor: pon primero container-type: inline-size en el padre, o la regla @container no coincidirá con nada.
Envuelve las reglas :has() con @supports selector(:has(*)) si los navegadores antiguos importan para tu público, para que tengan un respaldo limpio.
Usa :where() para estilos de bibliotecas o de reset. No añade especificidad, así que cualquiera puede sobrescribirlo con una sola clase.
Preguntas frecuentes
¿Sigo necesitando Sass para el nesting?
No solo para el nesting. El nesting nativo cubre el patrón habitual de reglas dentro de reglas más el selector &. Sass sigue ofreciendo mixins, bucles y funciones, aunque las custom properties y color-mix() han asumido gran parte de lo que la gente hacía con él.
¿Cuál es la diferencia entre container queries y media queries?
Una media query pregunta por el viewport, normalmente el ancho de la ventana. Una container query pregunta por un elemento ancestro elegido. Eso permite que un mismo componente de tarjeta muestre un diseño compacto en una barra lateral estrecha y un diseño ancho en la columna principal de la misma página.
¿Es lento :has()?
Los motores de los navegadores lo optimizaron antes de lanzarlo y el uso normal no da problemas. Los selectores muy amplios como body:has(*) en páginas enormes obligan a más trabajo de coincidencia, así que ancla :has() a una clase de componente concreta siempre que puedas.
¿Qué significa Baseline?
Baseline es una etiqueta de la comunidad de la plataforma web que indica que una función funciona en las versiones actuales de Chrome, Edge, Firefox y Safari. Newly available es la fecha en que el último de ellos la incorporó. Widely available llega unos treinta meses después.
¿Cuándo debo usar subgrid en lugar de una cuadrícula anidada?
Usa subgrid cuando los hijos de un elemento de la cuadrícula deben alinearse con las pistas de la cuadrícula exterior, como títulos, textos y botones a lo largo de una fila de tarjetas. Una cuadrícula anidada normal tiene sus propias pistas independientes, así que el contenido de distinta longitud se desalinea.
Cómo funciona el selector & en el nesting
Dentro de un bloque anidado, & representa el selector exterior. &:hover aplica la pseudoclase al propio padre, & + & apunta a un hermano del mismo tipo y .theme-dark & coloca al padre dentro de otro contexto.
Un selector anidado sin & se trata como descendiente, así que .card { p { } } significa .card p. Los navegadores publicados a partir de 2023 también aceptan un nombre de elemento sin más, como p, al inicio de una regla anidada.
Cascade layers en la práctica
@layer reset, base, components, utilities; declara un orden de antemano. Una capa posterior gana a una anterior sea cual sea la especificidad, lo que acaba con la mayoría de las peleas entre una biblioteca de componentes y tus propias sobrescrituras.
Los estilos fuera de cualquier capa ganan a todos los estilos en capas. Eso es útil al llevar una hoja de estilos antigua a una configuración con capas: deja al principio las reglas heredadas sin capa y luego muévelas una a una.
Qué adoptar primero
Si tus usuarios usan navegadores actuales, el nesting y :is() son ventajas gratuitas que solo acortan tu hoja de estilos. Las container queries compensan cuando tienes componentes reutilizables que aparecen con distintos anchos. Subgrid importa sobre todo en cuadrículas de tarjetas y formularios con etiquetas.
Nesting nativo en CSS
Una tarjeta estilizada con reglas anidadas
El hover, el título y la variante oscura están todos dentro de .card. & se refiere al propio .card.
El selector de padre :has()
Resaltar un campo cuando su casilla está marcada
En este marco no se ejecuta ningún script. La etiqueta se estiliza sola porque contiene un input marcado.
Cambiar el diseño de una tarjeta solo cuando contiene una imagen
Las tarjetas sin imagen mantienen el diseño de una columna; las que tienen una pasan a dos columnas.
Container queries
El CSS detrás de la demo del deslizador
container-type hace que .shelf se pueda medir; luego la regla @container cambia la tarjeta a una fila cuando .shelf mide al menos 420px de ancho.
Subgrid
Filas de tarjetas que se alinean sea cual sea la longitud del texto
Cada tarjeta ocupa tres filas de la cuadrícula exterior y usa subgrid para sus propias filas, así que todos los títulos, textos y botones comparten línea.
@layer, :is(), :where(), color-mix() y text-wrap
Las cascade layers deciden el ganador por orden
El selector de ID está en una capa anterior, así que la clase simple de la capa posterior sigue ganando.
:is() y :where() acortan las listas de selectores
:is() toma la especificidad de su argumento más fuerte, :where() siempre cuenta como cero.
color-mix() para tonos y sombras de hover
Mezclar con blanco o negro en el espacio oklab da tonos uniformes a partir de un solo color de marca.
text-wrap: balance para títulos
El segundo título reparte sus palabras de forma uniforme entre las líneas en lugar de dejar una palabra sola. Los navegadores limitan el equilibrado a bloques cortos de unas pocas líneas.
Soporte en navegadores (Baseline)
Estado Baseline (últimas versiones de Chrome, Edge, Firefox y Safari), comprobado en MDN en octubre de 2026
Función
Baseline
Notas
:is() y :where()
Widely available
@layer (cascade layers)
Widely available
Container queries de tamaño (@container, container-type)
Las container style queries son aparte y aún no son Baseline; consulta caniuse
color-mix()
Subgrid
CSS nesting
Los selectores de elemento sin más al inicio de una regla anidada necesitan versiones de 2023 o posteriores
:has()
text-wrap: balance
Los navegadores antiguos lo ignoran y ajustan las líneas con normalidad
Demo de container queries
La tarjeta de abajo responde al ancho de su contenedor gris, no al de tu ventana. Al pasar de 420px cambia a un diseño de dos columnas.
Ancho del contenedor:
Lámpara de escritorio de nogal
Luz cálida, interruptor de latón, pantalla hecha a mano.