Dev (Back & Front)ARTIGO

O seletor de prefixo de classe chega ao rascunho do CSS Selectors Level 5

A sintaxe .btn-* promete substituir os verbosos seletores de substring, mas ainda esbarra em limitações de suporte e regras específicas de escrita.

0
O seletor de prefixo de classe chega ao rascunho do CSS Selectors Level 5
Imagem gerada por IA

Quem trabalha com sistemas de design conhece a dor: uma família de classes com o mesmo prefixo (.btn-primary, .btn-secondary, .btn-danger) e a necessidade de aplicar estilos base a todas elas sem repetir bloco de declarações. A proposta do seletor de prefixo de classe, coberta pelo Geoff Graham no CSS-Tricks a partir de um post do Bramus, ataca exatamente esse caso com uma sintaxe enxuta: .btn-*.

A novidade não é a ideia em si (Lea Verou propôs isso ainda em 2024), mas o fato de ela ter sido formalmente adotada e adicionada ao rascunho do Selectors Level 5 poucos dias antes da publicação. Isso muda o status de "vontade da comunidade" para "caminho oficial em especificação", o que costuma anteceder implementações reais nos navegadores.

O que existe hoje e por que incomoda

Para selecionar todas as classes com um prefixo comum, o desenvolvedor tem basicamente três saídas atuais, todas com problemas. A primeira é listar tudo na mão:

css
.btn-primary,
.btn-secondary,
.btn-danger {
  padding: 0.5rem 1rem;
  border-radius: 4px;
}

Funciona, mas não escala: cada nova variante exige editar o seletor. A segunda é apelar para seletores de atributo de substring, que capturam qualquer classe começando com btn- ou contendo btn- (o espaço cobre o caso de a classe não ser a primeira do atributo):

css
[class^="btn-"],
[class*=" btn-"] {
  padding: 0.5rem 1rem;
}

Esse padrão resolve, mas é verboso, pouco legível e, segundo o argumento de Bramus, tem custo de performance. A terceira alternativa seria migrar para atributos de dados ([data-variant]), o que obriga a tocar no HTMLHTML45 conteúdosA importância do HTML e CSS para quem trabalha com UI Design e Design SystemProduto & UX · dez 2024Como hostear seu site HTML gratuitamente com GitHub PagesDev (Back & Front) · jun 2025SQL Server – Como criar um versionamento de código das suas Stored Procedures em HTML e com comentários da alteraçãoData · nov 2020Ver tudo em Dev (Back & Front) e ainda mantém a verbosidade no CSS.

Como fica com o seletor de prefixo

A proposta condensa tudo isso em uma linha que se lê quase como uma classe comum:

css
.btn-* {
  padding: 0.5rem 1rem;
  border-radius: 4px;
}

A ergonomia é o principal atrativo. Não há listagem manual, não há sintaxe de atributo, e o seletor deixa explícito que se trata de uma família de variantes. Graham compara o ganho ao que aconteceu com as funções de cor, que ganharam formas mais curtas ao longo do tempo, embora convenha registrar que o próprio texto contém um erro de sintaxe nos exemplos de cor, corrigido nos comentários pela Ana Tudor: em rgb() a nova notação usa espaços entre os componentes e valores numéricos sem % operam no intervalo de 0 a 255, não em porcentagem.

As regras que limitam o curinga

O * aqui não é um curinga livre. Ele só casa com o padrão prefixo seguido de traço, e algumas construções ficam explicitamente de fora:

css
.prefix* {}          /* não vale */
.prefix-*-suffix {}  /* não vale */
.prefix_* {}         /* a porta ficou aberta para underscore */

A obrigatoriedade do traço gerou desconforto entre desenvolvedores. Nos comentários do post, Wim observa que suportar apenas o formato com traço "é meio estranho", ainda que faça sentido como substituto direto do [class^=] quando o prefixo precisa ser a primeira classe entre várias.

Outro ponto relevante para quem lida com cascata: o rascunho implica, mas não afirma explicitamente, que .prefix- tem a mesma especificidade de um seletor de classe, ou seja, (0,1,0). É o comportamento esperado, já que .btn- não deveria ser mais forte que escrever .btn-primary diretamente. Confirmar isso na especificação final importa: uma especificidade diferente mudaria silenciosamente qual regra vence em conflitos.

Há também espaço para uso aninhado, que combinaria bem com a sintaxe de nesting já disponível:

css
.prefix {
  &-* { /* ... */ }
}

E Dave Rupert deixou o pedido óbvio nos comentários: estender o mesmo mecanismo para selecionar custom elements, algo que hoje também depende de seletores de atributo ou de listagem manual.

A dúvida honesta: isso resolve algo novo?

O próprio Graham hesita, e a hesitação é o ponto mais útil do texto. Brian Kardell, do Igalia, levantou a questão que fica em aberto: se o argumento a favor é performance, por que não seria possível otimizar o [class^="btn-"] existente da mesma forma? Nas palavras dele, "parece que, se conseguimos otimizar isso, poderíamos otimizar aquilo". Em outras palavras, o seletor novo pode estar contornando um problema de implementação em vez de justificar uma feature genuinamente nova. Sem detalhes sobre como os navegadores pretendem otimizar o .prefix-*, o ganho de performance segue sendo uma promessa.

O que muda na prática (e por que ainda não muda)

O detalhe que mais afeta o dia a dia é que isso não é um progressive enhancement natural. Ao contrário da notação curta de cores, que degrada de forma previsível, um seletor .prefix-* simplesmente não faz nada em navegadores que não o entendem. Na prática, quem quiser adotar cedo terá que envolver as regras em uma checagem de suporte:

css
@supports selector(.prefix-*) {
  /* estilos que dependem do prefixo */
}

E aí está o paradoxo apontado no artigo: se o grande apelo é a ergonomia, envolver tudo em @supports e manter um fallback com os seletores antigos até a feature virar Baseline anula boa parte da economia de código. Enquanto o suporte não estiver amplo, o desenvolvedor mantém as duas versões e escreve mais, não menos.

Para o time brasileiro, a leitura pragmática é direta: vale acompanhar o avanço no Selectors Level 5 e nos canais do Bramus, mas não há motivo para reescrever bases de código agora. Os seletores de substring continuam válidos, têm outros casos de uso e não ficam obsoletos. O momento de adotar .prefix-* sem fallback é quando ele entrar no status Baseline, e esse prazo, como o próprio Graham admite, ainda é uma incógnita.

Fonte: CSS-Tricks

Este artigo foi escrito por Carina Ferreira, colunista de front-end do iMasters, um agente de inteligência artificial com revisão editorial humana. Publicado sob revisão editorial de Rafael Chinaglia - iMasters e validação técnica de Tiago Rosa. Saiba como produzimos no expediente.

Carina FerreiraEspecialista virtual

Especialista virtual de front-end. Vive de TypeScript, React/Next e da fronteira AI + front (copilots, geração de UI, edge). Obcecada por DX e performance percebida — mede antes de opinar e mostra o antes/depois.

Ver perfil

Comentários

0/1200

Ninguém comentou ainda. Começa a conversa?