Validador de Seletor CSS
Verifica se um seletor CSS é válido e calcula sua especificidade (a,b,c). Lista classes, IDs e elementos detectados.
Validação de seletor CSS: da sintaxe à especificidade
Um seletor CSS é o padrão que escolhe nós do DOM para estilizar ou manipular. Validar envolve duas camadas: sintaxe (o seletor parseia?) e semântica (ele seleciona o que o autor pretendia?). A especificação W3C Selectors Level 4 padroniza a gramática; os navegadores implementam via WebKit (Safari), Blink (Chrome, Edge, Opera) e Gecko (Firefox). O teste em runtime é simples: document.querySelector(seletor) lança SyntaxError em entrada inválida, então qualquer validador pode envolver em try/catch.
Tipos de seletor e combinadores
- Elemento:
div,p,a— pelo nome da tag. - Classe:
.btn,.card— pelo atributoclass. - ID:
#main,#nav— peloid, deve ser único. - Atributo:
[type="text"],[href^="https"],[data-id]. - Pseudo-classe:
:hover,:focus,:nth-child(2n+1),:not(.x),:has(> img). - Pseudo-elemento:
::before,::after,::placeholder,::selection. - Descendente:
a b(qualquer profundidade) vs filho:a > b(filho direto). - Irmão adjacente:
a + b(imediatamente depois) vs irmão geral:a ~ b(qualquer irmão posterior).
Cálculo de especificidade
Quando duas regras atingem o mesmo elemento, vence a maior especificidade. A fórmula clássica é (a, b, c) lida como número de três dígitos: a = quantos IDs, b = classes + seletores de atributo + pseudo-classes, c = elementos + pseudo-elementos. Estilos inline somam um quarto campo mais alto; !important sobrepõe o cálculo todo, mas deve ser último recurso.
#main .card a:hover → (1, 2, 1) → 121
.btn.primary → (0, 2, 0) → 020
ul li → (0, 0, 2) → 002
div > .item::before → (0, 1, 2) → 012
Pegadinha comum: :not(), :is() e :where() mudam as regras. :where() contribui com zero de especificidade qualquer que seja o argumento — útil em resets que você quer fáceis de sobrescrever. :is() contribui com a especificidade do argumento mais específico.
Suporte em navegadores e :has()
A maioria do CSS Selectors Level 4 é estável nos navegadores modernos, mas alguns são recentes. :has() — o "seletor pai" — chegou no Chrome 105 (ago/2022), Safari 15.4 (mar/2022) e Firefox 121 (dez/2023). Antes de adotar em produção, confira a telemetria (caniuse.com/css-has) e proteja com @supports selector(:has(*)). :focus-visible, :focus-within e ::backdrop já estão seguros em todos os evergreen.
Usos além da estilização
- Consulta DOM em JS:
document.querySelector,querySelectorAll,element.matches,element.closest. - Testes E2E: Cypress (
cy.get('seletor')), Playwright (page.locator('seletor')), Puppeteer (page.$(seletor)). - Web scraping: Cheerio (Node), BeautifulSoup com
select()(Python), Goquery (Go). - jQuery legado: o engine Sizzle estendeu o CSS com pseudo-seletores não padronizados (
:contains,:visible) que não funcionam emquerySelector.
Performance e antipadrões
Navegadores casam seletores da direita para a esquerda, então a peça mais à direita (o key selector) dirige o filtro inicial. getElementById é a busca mais rápida; querySelector('#id') é marginalmente mais lento porque parseia o seletor antes. Cadeias longas de descendência como body > div > div > main > article > section > h2.title são frágeis — qualquer mudança no HTML quebra. A boa prática em testes E2E é usar atributos data como ganchos estáveis: [data-testid="botao-enviar"]. Eles desacoplam o teste do estilo e sobrevivem a refatorações.
Perguntas frequentes
Posso testar :has() neste validador? Sim, desde que rode em um navegador moderno. O validador delega para document.querySelector, então se o seu navegador suporta :has() o validador também suporta.
Como seleciono um elemento pai? Use :has(): div:has(> img) casa com divs que contêm uma imagem como filho direto. Antes do :has(), a única saída era percorrer o DOM em JavaScript (element.parentElement).
Em teste E2E, é melhor CSS ou XPath? CSS. Playwright, Cypress e o ferramental de QA moderno tratam CSS como cidadão de primeira classe; XPath é mais poderoso (busca por texto completo, eixo ancestor) mas verboso e lento. Use XPath só quando CSS não consegue expressar a consulta.
:scope funciona em querySelector? Sim. element.querySelectorAll(':scope > li') casa apenas com li que sejam filhos diretos de element, evitando o bug histórico em que o seletor começava do documento.
Por que meu seletor com aspas falha? Provavelmente aspas aninhadas. '[data-x="a"]' tudo bem; "[data-x=\"a\"]" precisa de escape. Em templates CSS-in-JS, prefira strings com aspas simples ou template literals para evitar sequências de escape.
Ferramentas Relacionadas
Validador de Regex Rust
Compila uma regex usando o subset de sintaxe da crate regex (Rust). Indica recursos não suportados (lookarounds, backrefs).
Validador de Cor CSS Nomeada
Valida se uma string é uma cor CSS nomeada padrão (red, rebeccapurple, …) e mostra o hex equivalente.
Validador BEM Naming
Valide classes CSS contra a convenção BEM (block, block__element, block--modifier, block__element--modifier) sinalizando violações.