Usando CSS :has para estilizar um elemento pai no foco de um elemento filho
Há um bom tempo, uma enxurrada de artigos sobre a pseudo classe :has
pipocam na internet. A maioria deles, porém, usa péssimos exemplos de aplicação — como estes apresentados na documentação da MDN. A distância destes exemplos em relação às necessidades reais do dia a dia de um programador desestimula a adoção do :has
, que acaba sendo rebaixado a um recurso periférico e secundário.
Diferente daquilo que você encontra aos montes pela internet afora, o caso de uso apresentado neste post é bastante corriqueiro, já que se baseia em uma lista de elementos que contêm um link como elemento filho.
Veja o que acontece quando se navega pelos links desta lista usando a tecla Tab:
Links sendo destacados pelo contorno padrão aplicado pelo Browser
Se quiséssemos destacar todo o item da lista no momento em que o link recebe foco, dando a ele a aparência de card, ao invés do destaque padrão do próprio link, precisaríamos recorrer ao JavaScript até pouco tempo atrás. Removeríamos o estilo de outline padrão do link, definiríamos listeners para os eventos de foco e desfoque do link, e então adicionaríamos uma classe CSS ao pai do link no momento do foco, removeando-a no momento do desfoque. Uma trabalheira danada.
Uma outra opção seria embrulhar todo o conteúdo do item com o link, antes restrito apenas ao título do post. Mas se por um lado esta opção elimina o trabalho pesado com JavaScript, por outro, traz alguns desconfortos a nível de CSS, já que os estilos padrão de link, como o sublinhado, seriam aplicados ao excerto e à data do post, exigindo alguns ajustes adicionais de estilo. Além disso, esta estratégia faria com que o clique em qualquer parte do item da lista disparasse a navegação em direção ao respectivo post, um comportamento que poderia soar contra-intuitivo.
Com o advento da pseudo classe :has
, que conta atualmente com suporte global de mais de 93%, este trabalho se tornou infinitamente mais simples, demandando agora apenas algumas linhas de CSS:
li {
padding: 20px;
box-shadow: 0 0 0 0 #29303D;
border-radius: 12px;
box-sizing: border-box;
transition: all 300ms ease-out;
}
li a {
outline: 0;
}
li:has(h2 > a:focus) {
box-shadow: 0 0 0 6px #29303D;
}
O último seletor definido no código acima explicita a seguinte condição: quando o link contido no elemento h2
receber foco, aplique os seguintes estilos ao item da lista li
.
Destaque do item da lista a partir do foco sobre o link contigo nele
Mão na massa: Neste Gist você tem acesso, em um único arquivo HTML, a todo o código necessário para rodar localmente o exemplo apresentado neste post.
Saiba mais: Se você curtiu este post, talvez se interesse em saber como usar CSS flexbox para fazer um elemento ocupar todo o espaço restante disponível.