As consultas em contêiner já estão disponíveis
Temos uma notícia incrível: um dos recursos mais pedidos pelos desenvolvedores começou a ser lançado nos navegadores da Web. A partir do Chromium 105 e do Safari 16, agora é possível criar consultas de contêiner com base no tamanho e usar valores de unidade de consulta de contêiner nesses navegadores. Para facilitar ainda mais o uso de consultas de contêiner com base no tamanho e unidades cq
, a equipe do Aurora no Chrome trabalhou muito para atualizar o polyfill de consulta de contêiner e oferecer suporte a mais navegadores e casos de uso. Assim, você pode usar esse recurso poderoso hoje mesmo.
O que são consultas de contêiner?
As consultas de contêiner são um recurso do CSS que permite escrever uma lógica de estilo que segmenta os recursos de um elemento pai para estilizar os filhos. É possível criar um design responsivo baseado em componentes reais consultando o tamanho de um elemento pai. Essas informações são muito mais granulares e úteis do que consultas de mídia, que fornecem apenas informações de tamanho sobre a viewport.
Com as consultas de contêiner, é possível escrever componentes reutilizáveis que podem aparecer de maneira diferente com base no local em que estão na página. Isso torna os sites e modelos muito mais resilientes e responsivos.
Como usar consultas de contêiner
Digamos que você tenha um HTML:
<!-- card parent -->
<div class=”card-parent”>
<div class=”card>
<!-- card contents -->
…
</div>
</div>
Para usar uma consulta de contêiner, primeiro é necessário definir a contenção no elemento pai que você quer rastrear. Para fazer isso, defina a propriedade container-type
ou use a abreviação container
para definir o tipo e o nome do contêiner ao mesmo tempo.
.card-parent {
/* query the inline-direction size of this parent */
container-type: inline-size;
}
Agora, você pode usar a regra @container
para definir estilos com base no elemento pai mais próximo. Para um design como a imagem acima, em que um card pode passar de uma coluna para duas, escreva algo como:
@container (min-width: 300px) {
.card {
/* styles to apply when the card container (.card-parent in this case) is >= 300px */
/* I.e. shift from 1-column to 2-column layout: */
grid-template-columns: 1fr 1fr;
}
}
Para ser mais organizado e explícito, dê um nome ao contêiner do elemento pai:
.card-parent {
container-type: inline-size;
/* set name here, or write this in one line using the container shorthand */
container-name: card-container;
}
Em seguida, reescreva o código anterior como:
@container card-container (min-width: 300px) {
.card {
grid-template-columns: 1fr 1fr;
}
}
Unidades de consulta de contêiner
Para tornar as consultas de contêiner ainda mais úteis, você também pode usar valores de unidade baseados em contêiner. A tabela a seguir mostra os possíveis valores de unidade de contêiner e como eles correspondem ao tamanho de um contêiner:
unidade | em relação a |
---|---|
cqw | 1% da largura de um contêiner de consulta |
cqh | 1% da altura de um contêiner de consulta |
cqi | 1% do tamanho inline de um contêiner de consulta |
cqb | 1% do tamanho do bloco de um contêiner de consulta |
cqmin | O valor menor de cqi ou cqb |
cqmax | O valor maior de cqi ou cqb |
Um exemplo de como usar unidades baseadas em contêiner é a tipografia responsiva. As unidades baseadas na janela de visualização (como vh
, vb
, vw
e vi
) podem ser usadas para dimensionar qualquer elemento na tela.
.card h2 {
font-size: 15cqi;
}
Esse código vai fazer com que o tamanho da fonte seja 15% do tamanho inline do contêiner, ou seja, ele vai aumentar conforme o tamanho inline (largura) aumenta ou diminuir conforme ele diminui. Para ir ainda mais longe, use a função clamp()
para definir um limite mínimo e máximo de tamanho para a tipografia e dimensione de forma responsiva com base no tamanho do contêiner:
.card h2 {
font-size: clamp(1.5rem, 15cqi, 3rem);
}
Agora o cabeçalho nunca vai ficar maior que 3rem
ou menor que .5rem
, mas vai ocupar 15% do tamanho inline do contêiner em qualquer lugar entre eles.
Esta demonstração vai além e atualiza os cards mais largos para ter um tamanho menor, já que eles aparecem em uma visualização de duas colunas.
O polyfill de consulta de contêiner
Como as consultas de contêiner são um recurso muito poderoso, queremos que você se sinta à vontade para incorporá-las aos seus projetos e saiba que o suporte do navegador é uma parte importante disso. Por isso, estamos trabalhando para melhorar o polyfill de consulta de contêiner. Esse polyfill tem suporte geral em:
- Firefox 69 ou mais recente
- Chrome 79 ou mais recente
- Edge 79 ou versões mais recentes
- Safari 13.4 ou mais recente
Ele tem menos de 9 KB quando compactado e usa ResizeObserver com MutationObserver para oferecer suporte à sintaxe completa da consulta @container, que está disponível nos navegadores estáveis:
- Consultas discretas (
width: 300px
emin-width: 300px
). - Consultas de intervalo (
200px < width < 400px
ewidth < 400px
). - Unidades de comprimento relativas do contêiner (
cqw
,cqh
,cqi
,cqb
,cqmin
ecqmax
) em propriedades e keyframes.
Como usar o polyfill de consulta de contêiner
Para usar o polyfill, adicione esta tag de script ao cabeçalho do documento:
<script type="module">
if (!("container" in document.documentElement.style)) {
import("https://unpkg.com/container-query-polyfill@^0.2.0");
}
</script>
Você também pode usar um serviço para fornecer condicionalmente o polyfill com base em User-Agent
ou hospedar o polyfill na sua própria origem.
Para oferecer a melhor experiência do usuário, recomendamos que você use inicialmente apenas o polyfill para conteúdo abaixo da dobra e use consultas @supports
para substituí-lo temporariamente por um indicador de carregamento até que o polyfill esteja pronto para ser exibido:
@supports not (container-type: inline-size) {
.container,
footer {
display: none;
}
.loader {
display: flex;
}
}
Em redes e dispositivos suficientemente rápidos ou que oferecem suporte nativo a consultas de contêineres, esse indicador de carregamento nunca será exibido.
Novos recursos de preenchimento
O polyfill atualizado oferece suporte a:
- Regras
@container
aninhadas. - É possível aninhar regras
@container
em consultas@supports
e@media
, e vice-versa. - O CSS condicional, como
@supports (container-type: inline-size)
, será transmitido depois que o polyfill for carregado. - Suporte completo à sintaxe CSS (não há mais problemas ao colocar comentários em qualquer lugar em que eles sejam sintaticamente válidos).
- Modos de escrita vertical (usando o writing-mode).
- As unidades relativas ao contêiner (
cqw
,cqh
etc.) são compatíveis com condições de consulta, declarações de propriedade e keyframes de animação.rem
eem
são compatíveis com condições de consulta. - Sintaxe de consulta de contêiner expandida:
- Sintaxe de intervalo (por exemplo,
(200px < width < 400px)
). - Consultas de igualdade (por exemplo,
(width = 200px)
).
- Sintaxe de intervalo (por exemplo,
- Pseudoelementos como
::before
e::after
. - Os navegadores sem
:is(...)
/:where(...)
têm suporte por uma solução alternativa opcional - As consultas de recursos
orientation
easpect-ratio
. - Filtragem correta de consultas com base em recursos. Por exemplo, a consulta
height
emcontainer: inline-size
é corretamente proibida com um modo de gravação horizontal. - Mutação do DOM (por exemplo, elementos
<style>
e<link>
sendo removidos no momento da execução).
Limitações e avisos de preenchimento polido
Se você estiver usando o polyfill de consulta de contêiner, há alguns recursos ausentes:
- O Shadow DOM ainda não é compatível.
- As unidades relativas do contêiner (por exemplo,
cqw
ecqh
) não são compatíveis com as condições de consulta@media
.- Safari: as unidades relativas ao contêiner não são compatíveis com keyframes de animação anteriores à versão 15.4.
calc()
,min()
,max()
ou outras funções matemáticas ainda não são compatíveis com as condições de consulta.- Esse polifill só funciona com CSS inline e de mesma origem. Não há suporte para folhas de estilo entre origens e em iframes, a menos que um polyfill seja carregado manualmente.
- A contenção de
layout
estyle
requer suporte do navegador:- Safari 15.4 ou mais recente
- O Firefox não oferece suporte à contenção de estilo no momento, mas está trabalhando nisso.
Avisos
- Para evitar impactos no FID e no CLS, o polifill não garante quando o primeiro layout vai ocorrer, mesmo que seja carregado de forma síncrona, exceto que ele tenta evitar o atraso excessivo do LCP. Em outras palavras, nunca confie nele para a primeira pintura.
- Gera
ResizeObserver Loop Errors
. O polyfill original também faz isso, mas vale a pena destacar. Isso ocorre porque o tamanho do bloco de umcontainer-type: inline-size
provavelmente vai mudar após a avaliação de uma consulta, mas oResizeObserver
não tem como informar que não nos importamos com as mudanças no tamanho do bloco. - Esse polyfill foi testado nos testes da plataforma da Web e alcançou 70% de aprovação, já que alguns recursos, como APIs JavaScript, não são polifilados. Por isso, a taxa de aprovação está intencionalmente mais próxima de 70%.
- A solução alternativa
:where()
é necessária para os 2,23% de usuários de navegadores mais antigos que:- Safari 14
- Chromium 88
- Edge 88
- Samsung Internet 15
- Firefox 78