O CSS não tinha uma maneira de selecionar diretamente um elemento pai com base nos filhos. Esse é um dos principais pedidos dos desenvolvedores há muitos anos. O seletor :has()
, que agora tem suporte de todos os principais navegadores, resolve esse problema. Antes :has()
, você normalmente encadenava seletores longos ou adicionava classes para ganchos de estilo. Agora é possível definir estilos com base na relação de um elemento com os descendentes dele. Leia mais sobre o seletor :has()
em CSS Wrapped 2023 e 5 snippets de CSS que todo desenvolvedor de front-end precisa conhecer.
Embora esse seletor pareça pequeno, ele pode permitir um grande número de casos de uso. Este artigo mostra alguns casos de uso que as empresas de e-commerce desbloquearam com o seletor :has()
.
:has()
faz parte da Linha de base recém-disponível.
Confira a série completa (em inglês) da qual este artigo faz parte, que discute como as empresas de e-commerce melhoraram os sites usando novos recursos de CSS e interface.
Policybazaar
Com o seletor
:has()
, foi possível eliminar a validação baseada em JavaScript da seleção do usuário e substituí-la por uma solução CSS que funciona perfeitamente para nós com a mesma experiência de antes.—Aman Soni, líder de tecnologia, Policybazaar
A equipe de investimentos da Policybazaar aplicou habilmente o seletor :has()
para fornecer uma indicação visual clara aos usuários que estão comparando planos. A imagem a seguir mostra dois tipos de planos na interface de comparação (amarelo e azul). Cada plano só pode ser comparado com o próprio tipo. Ao usar :has()
, quando um usuário seleciona um tipo de plano, o outro tipo não pode ser selecionado.
:has()
para estilizar o elemento pai e os filhos dele para criar uma funcionalidade de seleção vinculada a uma categoria.Código
O :has()
dá acesso aos elementos pai de estilo e aos filhos deles. O código abaixo verifica se um contêiner pai tem uma classe .disabled-group
definida. Se isso acontecer, o card ficará esmaecido, e o botão "Adicionar" não reagirá a cliques ao definir pointer-events
como none
.
.plan-group-container:has(.disabled-group) { opacity: 0.5; filter: grayscale(100%); } .plan-group-container:has(.disabled-section) .button { pointer-events: none; border-color: #B5B5B5; color: var(--text-primary-38-color); background: var(--input-border-color); }
A equipe de saúde da Policybazaar implementou um caso de uso um pouco diferente. Eles têm um teste inline para o usuário e usam :has()
para verificar o status da caixa de seleção da pergunta e saber se ela foi respondida. Se for, uma animação será aplicada para fazer a transição para a próxima pergunta.
Código
No exemplo de comparação de planos, :has()
foi usado para verificar a presença de uma classe. Também é possível verificar o estado de um elemento de entrada, como uma caixa de seleção, usando :has(input:checked)
. No recurso visual que mostra o teste, cada pergunta no banner roxo é uma caixa de seleção. O Policybazaar verifica se a pergunta foi respondida usando :has(input:checked)
e, se sim, aciona uma animação usando animation: quesSlideOut 0.3s 0.3s linear forwards
para deslizar até a próxima pergunta. Confira como isso funciona no código a seguir.
.segment_banner__wrap__questions { position: relative; animation: quesSlideIn 0.3s linear forwards; } .segment_banner__wrap__questions:has(input:checked) { animation: quesSlideOut 0.3s 0.3s linear forwards; } @keyframes quesSlideIn { from { transform: translateX(50px); opacity: 0; } to { transform: translateX(0px); opacity: 1; } } @keyframes quesSlideOut { from { transform: translateX(0px); opacity: 1; } to { transform: translateX(-50px); opacity: 0; } }
Tokopedia
A Tokopedia usou :has()
para criar uma imagem de sobreposição se a miniatura do produto contiver um vídeo. Se a miniatura do produto contiver uma classe .playIcon
, uma sobreposição CSS será adicionada. Aqui, o seletor :has() é usado com o seletor de aninhamento &
na classe .thumbnailWrapper
principal, que se aplica a todas as miniaturas. Isso cria um CSS mais modular e legível.

:has()
.Código
O código a seguir usa os seletores e combinatores de CSS (&
e >
) e aninhamento com :has()
para definir o estilo da miniatura. Para navegadores que não oferecem suporte, a regra de classe CSS adicional regular é usada como substituto. A regra @supports selector(:has(*))
também é usada para verificar o suporte do navegador. Portanto, a experiência geral é a mesma em todas as versões do navegador.
export const thumbnailWrapper = css` padding: 0; margin-right: 7px; border: none; outline: none; background: transparent; > div { width: 64px; height: 64px; overflow: hidden; cursor: pointer; border-color: ; position: relative; border: 2px solid ${NN0}; border-radius: 8px; transition: border-color 0.25s; &.active { border-color: ${GN500}; } @supports selector(:has(*)) { &:has(.playIcon) { &::after { content: ''; display: block; background: rgba(0, 0, 0, 0.2); position: absolute; top: 0; left: 0; right: 0; bottom: 0; } } } & > .playIcon { position: absolute; top: 25%; left: 25%; width: 50%; height: 50%; text-align: center; z-index: 1; } } `;
Considerações ao usar :has()
Combine :has()
com outros seletores para criar uma condição mais complexa. Confira alguns exemplos em has() o seletor de família.
Recursos:
- CSS Wrapped 2023
- :has(): o seletor de família
- Demonstrações de :has()
- Quer informar um bug ou solicitar um novo recurso? Queremos saber sua opinião.
Confira os outros artigos desta série que falam sobre como as empresas de e-commerce se beneficiaram com o uso de novos recursos de CSS e interface, como animações com base no rolagem, transições de visualização, popovers e consultas de contêiner.