blense.
InicioFrontendProgramaciónIANoticiasGuíasCheatsheetsAcerca de

Tecnología descifrada, siempre.

Una lectura curada sobre IA, producto y la cultura detrás del código. Sin ruido, sin hype.

blense.

Tecnología con foco. Historias sobre lo que la innovación realmente cambia.

Secciones

FrontendInteligencia artificialProgramación y desarrolloNoticias tech

Blense

Acerca deRSSPrivacidadTérminosCookies
© 2026 Blense · blense.fun
Frontend

CSS :where() y :is(): Especificidad, Resets y Mantenimiento

Muchos desarrolladores ignoran las pseudo-clases CSS :where() e :is(), viéndolas como "azúcar sintáctico". Este artículo revela cómo son cruciales para resolver el caos de la especificidad, permitiendo crear CSS escalable y mantenible. Entiende la diferencia y aplícala en resets, componentes y sistemas de diseño.

Gpor Genildo Souza23 mar4 min de lectura
CSS :where() y :is(): Especificidad, Resets y Mantenimiento

¿Ya has escrito el mismo bloque de CSS tres veces solo cambiando el selector? Ese es exactamente el problema que :is() y :where() resuelven — y la diferencia entre ambos es más importante de lo que parece.

Este CSS te resulta familiar:

TEXT
header a,footer a,nav a {  color: blue;  text-decoration: none;}

Repitiendo la misma regla para tres contextos diferentes. Ahora imagina que tienes diez contextos. Y que cada uno tiene tres variaciones de estado — :hover, :focus, :visited. El archivo CSS se convierte en una guía telefónica.

El CSS moderno tiene una respuesta para esto. Dos, de hecho — y parecen iguales pero se comportan diferente en un detalle que te salvará de errores sutiles.

:is() — agrupa selectores sin repetición

El :is() acepta una lista de selectores y aplica el estilo a cualquiera que coincida. El bloque anterior se convierte en:

TEXT
:is(header, footer, nav) a {  color: blue;  text-decoration: none;}

Una línea, mismo resultado. El navegador lo interpreta exactamente como la versión repetida — semánticamente son equivalentes.

Se vuelve más interesante cuando lo combinas con pseudo-clases:

TEXT
/* Antes — repetindo pra cada estado */button:hover,button:focus,button:active {  background: darkblue;}/* Depois — limpo */button:is(:hover, :focus, :active) {  background: darkblue;}

O para estilizar encabezados de una vez:

Arsenal del dev de élite.
Tailwind CSS v4: Cómo acelerar tus builds 100x con la nueva configuración CSS-first16 minEl fin de la transición: La estructura de diseño y desarrollo de productos para 20269 minAngular 22: Reemplace ControlValueAccessor con Signal Forms14 minDeja de arriesgar tu frontend: la arquitectura definitiva de Angular 2218 min
TEXT
/* Todos os headings dentro de article */article :is(h1, h2, h3, h4) {  font-family: Georgia, serif;  line-height: 1.3;}

:where() — idéntico, pero sin peso de especificidad

Aquí reside la diferencia importante.

La especificidad en CSS es el sistema de puntuación que decide qué regla prevalece cuando dos se contradicen. Un selector de ID vale más que una clase, que vale más que una etiqueta. Cuando usas :is(), la especificidad del selector más fuerte dentro de los paréntesis se propaga a toda la regla.

TEXT
/* :is() herda a especificidade do #header — alta */:is(#header, .nav, footer) a {  color: blue;}/* ↑ esse seletor tem especificidade de ID   por causa do #header, mesmo que o elemento   seja .nav ou footer */

El :where() funciona igual en comportamiento — pero tiene especificidad cero. Siempre. No importa lo que pongas dentro.

TEXT
/* :where() — especificidade zero */:where(#header, .nav, footer) a {  color: blue;}/* ↑ fácil de sobrescrever — qualquer seletor   de classe ou tag já ganha */

En la práctica, esto significa que :where() es ideal para estilos base y resets — defines sin bloquear al desarrollador que personalizará después.

La diferencia en la vida real

Problema con :is()
TEXT
/* base.css */:is(article, section) p {  color: gray;}/* theme.css — não vai funcionar */p {  color: black;}/* :is(article, section) p tem   especificidade maior que p */
Solución con :where()
TEXT
/* base.css */:where(article, section) p {  color: gray;}/* theme.css — funciona */p {  color: black;}/* :where() tem especificidade zero   qualquer p ganha na sobreposição */
ℹ️

El reset CSS moderno usa :where() por esta razón. Tailwind, Open Props y varios resets populares usan :where() para definir estilos base que nunca bloquean al desarrollador. La intención es: "este es el estándar, pero cualquier cosa tuya lo sobrescribe fácilmente."

Un ejemplo que une ambos

En un sistema de diseño, usarías ambos en capas diferentes:

TEXT
/* Camada base — :where() pra não travar ninguém */:where(h1, h2, h3, h4, h5, h6) {  margin: 0 0 0.5em;  line-height: 1.2;}/* Camada de componente — :is() pra contextos específicos */.card :is(h2, h3) {  font-size: 1.25rem;  color: var(--color-heading);}/* Estados interativos — :is() porque precisa de peso */.btn:is(:hover, :focus-visible) {  outline: 2px solid currentColor;  outline-offset: 2px;}
⚠️

Cuidado con los selectores inválidos dentro de :is(). Si colocas un selector inválido en una lista separada por comas en CSS tradicional, la regla entera se ignora. Con :is() y :where(), los selectores inválidos se descartan silenciosamente — los otros siguen funcionando. Esto es una ventaja, pero puede ocultar errores tipográficos.

Lo que queda después de leer esto
  • 1:is() agrupa selectores y hereda la especificidad del más fuerte de la lista.
  • 2:where() hace lo mismo pero con especificidad cero — siempre sobrescribible.
  • 3Usa :where() en resets y estilos base que no deben bloquear la personalización.
  • 4Usa :is() en componentes y estados de interacción donde el peso importa.
  • 5Ambos eliminan la repetición de selectores — tu CSS es más pequeño y legible.
  • 6Soporte en navegadores: todos los modernos. Sin preocupación de compatibilidad.
Destacado
¿Quieres profundizar en este tema?

Si quieres explorar este tema desde otro ángulo, he preparado lecturas relacionadas con ejemplos y aplicaciones prácticas.

Explorar

#CSS#Tailwind

Arsenal del dev de élite.

Guía de estrategias de carga HTML que acelerará sus tiempos de carga
Frontend

Guía de estrategias de carga HTML que acelerará sus tiempos de carga

Descubre cómo optimizar la carga de scripts con defer y async para eliminar bloqueos de renderizado y mejorar la velocidad de tu sitio web.

Genildo Souza · 24 jun · 9 min
Tailwind CSS v4: Cómo acelerar tus builds 100x con la nueva configuración CSS-first
Frontend

Tailwind CSS v4: Cómo acelerar tus builds 100x con la nueva configuración CSS-first

Descubre cómo Tailwind CSS v4 revoluciona el desarrollo frontend con builds ultrarrápidos y una nueva configuración CSS-first sin complicaciones.

Genildo Souza · 20 jun · 16 min
Zustand + TanStack Query: La dupla poderosa para la gestión de estado en React
Frontend

Zustand + TanStack Query: La dupla poderosa para la gestión de estado en React

Descubre por qué Zustand y TanStack Query son la combinación ideal para separar el estado de cliente del servidor y simplificar tu código en React.

Genildo Souza · 18 jun · 11 min
En este artículo
  • :is() — agrupa selectores sin repetición
  • :where() — idéntico, pero sin peso de especificidad
  • La diferencia en la vida real
  • Un ejemplo que une ambos