1001Ferramentas
🎨Validadores

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 atributo class.
  • ID: #main, #nav — pelo id, 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 em querySelector.

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