blense.
InícioFrontendProgramaçãoIANotíciasGuiasCheatsheetsSobre

Tecnologia decodificada, sempre.

Uma leitura curada sobre IA, produto e a cultura por trás do código. Sem ruído, sem hype.

blense.

Tecnologia com foco. Histórias sobre o que a inovação realmente muda.

Seções

FrontendInteligência ArtificialProgramação & DevNotícias Tech

Blense

SobreRSSPolítica de privacidadeTermosCookies
© 2026 Blense · blense.fun
Frontend

CSS :where() e :is(): Especificidade, Resets e Manutenção

Muitos desenvolvedores ignoram as pseudo-classes CSS :where() e :is(), vendo-as como "syntax sugar". Este artigo revela como elas são cruciais para resolver o caos da especificidade, permitindo criar CSS escalável e manutenível. Entenda a diferença e aplique em resets, componentes e design systems.

Gpor Genildo Souza29 de jan.4 min de leitura
CSS :where() e :is(): Especificidade, Resets e Manutenção

Você já escreveu o mesmo bloco de CSS três vezes só mudando o seletor? Essa é exatamente a dor que :is() e :where() resolvem — e a diferença entre os dois é mais importante do que parece.

Esse CSS te parece familiar:

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

Repetindo a mesma regra pra três contextos diferentes. Agora imagina que você tem dez contextos. E que cada um tem três variações de estado — :hover, :focus, :visited. O arquivo CSS vira uma lista telefônica.

O CSS moderno tem uma resposta pra isso. Duas, na verdade — e elas parecem iguais mas se comportam diferente num detalhe que vai te salvar de bugs sutis.

:is() — agrupe seletores sem repetição

O :is() aceita uma lista de seletores e aplica o estilo pra qualquer um que bater. O bloco acima vira:

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

Uma linha, mesmo resultado. O navegador interpreta isso exatamente como a versão repetida — semanticamente são equivalentes.

Fica mais interessante quando você combina com pseudo-classes:

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

Ou pra estilizar headings de uma vez:

Arsenal do dev de elite.
Você está dimensionando elementos do jeito errado. E o CSS já tem a solução há anos.13 minComo unificar design e código: a estrutura exata para acelerar suas entregas em 2026. 9 minMicrofrontends com Angular e Nx: o que ninguém conta16 minNext.js 16 PPR: Elimine o tradeoff entre estático e dinâmico e alcance Edge TTFB com dados atualizados15 min
TEXT
/* Todos os headings dentro de article */article :is(h1, h2, h3, h4) {  font-family: Georgia, serif;  line-height: 1.3;}

:where() — igualzinho, mas sem peso de especificidade

Aqui mora a diferença que importa.

Especificidade em CSS é o sistema de pontuação que decide qual regra vence quando duas se contradizem. Um seletor de ID vale mais que uma classe, que vale mais que uma tag. Quando você usa :is(), a especificidade do seletor mais forte dentro dos parênteses se propaga pra regra inteira.

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 */

O :where() funciona igual em comportamento — mas tem especificidade zero. Sempre. Não importa o que você colocar dentro.

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

Na prática isso significa que :where() é ideal pra estilos base e resets — você define sem travar o desenvolvedor que vai customizar depois.

A diferença na vida real

Problema com :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 */
Solução com :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 */
ℹ️

CSS reset moderno usa :where() por esse motivo. O Tailwind, o Open Props e vários resets populares usam :where() pra definir estilos base que nunca travam o desenvolvedor. A intenção é: "esse é o padrão, mas qualquer coisa sua sobrescreve facilmente."

Um exemplo que junta os dois

Num design system, você usaria os dois em camadas 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 com seletores inválidos dentro do :is(). Se você colocar um seletor inválido numa lista separada por vírgula no CSS tradicional, a regra inteira é ignorada. Com :is() e :where(), seletores inválidos são silenciosamente descartados — os outros continuam funcionando. Isso é uma vantagem, mas pode esconder typos.

O que fica depois de ler isso
  • 1:is() agrupa seletores e herda a especificidade do mais forte da lista.
  • 2:where() faz o mesmo mas com especificidade zero — sempre sobrescrevível.
  • 3Use :where() em resets e estilos base que não devem travar customização.
  • 4Use :is() em componentes e estados de interação onde o peso importa.
  • 5Os dois eliminam repetição de seletores — seu CSS fica menor e mais legível.
  • 6Suporte nos navegadores: todos os modernos . Sem preocupação de compatibilidade.
Destaque
Quer aprofundar este assunto?

Se você quiser explorar esse assunto por outro ângulo, separei leituras relacionadas com exemplos e aplicações práticas.

Explorar

#CSS#Tailwind

Arsenal do dev de elite.

Next.js 15 + React 19: Guia de Implementação Full-Stack
Frontend

Next.js 15 + React 19: Guia de Implementação Full-Stack

Aprenda a implementar padrões de alta performance com Next.js 15 e React 19, reduzindo o bundle e otimizando a comunicação entre cliente e servidor.

Genildo Souza · 19 de jun. · 11 min
Como unificar design e código: a estrutura exata para acelerar suas entregas em 2026.
Frontend

Como unificar design e código: a estrutura exata para acelerar suas entregas em 2026.

Chega de perder tempo entre equipes. Aprenda a estrutura de 2026 para unificar design e código e construir produtos digitais sem atritos.

Genildo Souza · 18 de jun. · 9 min
Lazy Loading: carregar menos para entregar mais
Frontend

Lazy Loading: carregar menos para entregar mais

A web nunca foi tão rápida, e nunca engoliu tantos megabytes. A saída não é acelerar a entrega, mas adiar o que não importa agora.

Genildo Souza · 12 de jun. · 13 min
Neste artigo
  • :is() — agrupe seletores sem repetição
  • :where() — igualzinho, mas sem peso de especificidade
  • A diferença na vida real
  • Um exemplo que junta os dois