@container e :has(): duas novas APIs responsivas e poderosas que chegam ao Chromium 105

Consultas de contêiner e :has() são uma correspondência feita de forma reativa. Felizmente, esses dois recursos estão chegando juntos no Chromium 105. Este é um grande lançamento com dois recursos muito solicitados para interfaces responsivas!

Consultas de contêiner: um resumo rápido

Com as consultas em contêiner, os desenvolvedores podem consultar um seletor pai em busca das informações de tamanho e estilo, possibilitando que um elemento filho tenha a própria lógica de estilo responsiva, independentemente de onde ele esteja na página da Web.

Em vez de depender da janela de visualização para definir o estilo da entrada, como o espaço disponível, agora os desenvolvedores também podem consultar o tamanho dos elementos in-page. Esse recurso significa que um componente tem a própria lógica de estilo responsivo. Isso torna o componente muito mais resiliente porque a lógica de estilo é anexada a ele, não importa onde ele apareça na página.

Como usar consultas de contêiner

Para criar com consultas de contêiner, primeiro você precisa definir a contenção em um elemento pai. Para fazer isso, defina um container-type no contêiner pai. É possível que você tenha um card com uma imagem e um conteúdo de texto como este:

Cartão único de duas colunas.

Para criar uma consulta de contêiner, defina container-type no contêiner do cartão:

.card-container {
  container-type: inline-size;
}

Definir a container-type como inline-size consulta o tamanho da direção in-line do pai. Em idiomas latinos, como o inglês, essa seria a largura do cartão, já que o texto flui inline da esquerda para a direita.

Agora, podemos usar esse contêiner para aplicar estilos a qualquer um dos filhos usando @container:

.card {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

@container (max-width: 400px) {
  .card {
    grid-template-columns: 1fr;
  }
}

O seletor pai :has()

A pseudoclasse CSS :has() permite que os desenvolvedores verifiquem se um elemento pai contém filhos com parâmetros específicos.

Por exemplo, p:has(span) indica um seletor de parágrafo (p), que tem um span dentro dele. Você pode usar esse recurso para estilizar o próprio parágrafo pai ou qualquer elemento dele. Um exemplo útil é usar figure:has(figcaption) para definir o estilo de um elemento figure que contenha uma legenda. Você pode ver muito mais sobre :has() neste artigo de Jhey Tompkins.

Consultas de contêiner e :has()

É possível combinar as capacidades de seleção mãe de :has() com as capacidades de consulta mãe de consultas de contêiner para criar alguns estilos intrínsecos realmente dinâmicos.

Vamos analisar o primeiro exemplo com a carta do foguete. E se você tiver um cartão sem imagem? Talvez você queira aumentar o tamanho do título e ajustar o layout de grade para uma coluna única para que ele pareça mais intencional sem a imagem.

Texto maior no card, sem a imagem, e mostrado em uma coluna.

Neste exemplo, o cartão com uma imagem tem um modelo de grade de duas colunas, enquanto o cartão sem a imagem tem um layout de coluna única. Além disso, o cartão sem a imagem tem um cabeçalho maior. Para escrever isso usando :has(), use o seguinte CSS.

.card:has(.visual) {
  grid-template-columns: 1fr 1fr;
}

Você está procurando um elemento com uma classe visual para aplicar o estilo de duas colunas acima. Outra função CSS interessante é :not(). Isso faz parte da mesma especificação que :has(), mas existe há muito mais tempo e tem melhor suporte a navegadores. Você pode até mesmo combinar :has() e :not(), desta forma:

.card:not(:has(.visual)) h1 {
  font-size: 4rem;
}

No código acima, você está escrevendo um seletor que define o estilo de um h1 em um cartão que não contém uma classe visual. É assim que você pode ajustar claramente o tamanho da fonte.

Como tudo funciona em conjunto

A demonstração acima mostra uma combinação de :has(), :not() e @container, mas as consultas de contêiner realmente se destacam quando você pode ver o mesmo elemento usado em vários lugares. Vamos dar um toque de estilo e mostrar esses cards em grade lado a lado.

(link em inglês)

Agora você pode realmente ver o poder do CSS moderno. Somos capazes de escrever estilos claros usando estilos direcionados que desenvolvem uma lógica sobre a lógica e criam componentes realmente robustos. Com esses dois recursos avançados chegando ao Chromium 105 e ganhando impulso no suporte entre navegadores, é um momento muito empolgante para ser um desenvolvedor de interface.