As consultas de contêiner chegaram!
Temos uma notícia incrível: um dos recursos mais solicitados para desenvolvedores está disponível nos navegadores da Web. A partir do Chromium 105 e do Safari 16, é possível criar consultas de contêiner baseadas em tamanho e usar valores de unidade de consulta de contêiner nesses navegadores. Para facilitar ainda mais o uso de consultas de contêiner baseadas em tamanho e unidades cq
, a equipe do Aurora no Chrome tem trabalhado muito para atualizar o Polyfill de consulta de contêiner para oferecer suporte a mais navegadores e casos de uso. Assim, você pode se sentir confiante para usar esse recurso avançado atualmente.
O que são consultas de contêiner?
As consultas de contêiner são um recurso CSS que permite escrever uma lógica de estilo que visa elementos de um elemento pai para estilizar os filhos dele. Você pode criar um design responsivo verdadeiramente baseado em componentes consultando o tamanho de um pai. Essas informações são muito mais detalhadas e úteis do que as consultas de mídia, que só fornecem informações de tamanho sobre a janela de visualização.
Com as consultas de contêiner, você pode escrever componentes reutilizáveis que aparecem de maneiras diferentes de acordo com o local em que ficam na página. Isso os torna muito mais resilientes e responsivos em todas as páginas e modelos.
Como usar consultas de contêiner
Digamos que você tenha algum HTML:
<!-- card parent -->
<div class=”card-parent”>
<div class=”card>
<!-- card contents -->
…
</div>
</div>
Para usar uma consulta de contêiner, primeiro você precisa definir a contenção no elemento pai que quer rastrear. Para 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 pai mais próximo. Para um design como a imagem acima, em que um cartão pode ir de uma para duas colunas, 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 deixar tudo mais simples 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 desta forma:
@container card-container (min-width: 300px) {
.card {
grid-template-columns: 1fr 1fr;
}
}
Unidades de consulta do contêiner
Para tornar as consultas de contêiner ainda mais úteis, você também pode usar valores de unidade com base 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 em linha de um contêiner de consulta |
cqb | 1% do tamanho do bloco de um contêiner de consulta |
cqmin | O menor valor de cqi ou cqb |
cqmax | O valor maior de cqi ou cqb |
Um exemplo de como você usaria 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 deixa o tamanho da fonte em 15% do tamanho inline do contêiner, o que significa que ele vai aumentar à medida que o tamanho da linha (largura) aumentar ou menor à medida que diminuir. Para levar isso ainda mais longe, use a função clamp()
para dar à sua tipografia um limite mínimo e máximo de tamanho, e dimensioná-la 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 do que 3rem
ou menor do que .5rem
, mas ocupará 15% do tamanho in-line do contêiner em qualquer lugar.
Essa demonstração vai um pouco mais além e atualiza os cards mais amplos para ter um intervalo de tamanho menor, porque eles aparecem em uma visualização de duas colunas.
O polyfill da consulta do contêiner
Como as consultas de contêiner são um recurso muito eficiente, queremos que você se sinta à vontade para incorporá-las aos seus projetos e que saiba que a compatibilidade com o navegador é uma parte importante disso. Por isso, estamos trabalhando para melhorar o Polyfill de consulta de contêiner. Esse polyfill é compatível de modo geral em:
- Firefox 69 ou superior
- Chrome 79 ou mais recente
- Edge 79+
- Safari 13.4 ou superior
Ela tem menos de 9 KB quando compactado e usa ResizeObserver com MutationObserver para oferecer suporte à sintaxe de consulta completa do @container, disponível atualmente em navegadores estáveis:
- Consultas discretas (
width: 300px
emin-width: 300px
). - Consultas de intervalo (
200px < width < 400px
ewidth < 400px
). - Unidades de tamanho relativo do contêiner (
cqw
,cqh
,cqi
,cqb
,cqmin
ecqmax
) nas propriedades e nos frames-chave.
Como usar o polyfill de consulta do contêiner
Para usar o polyfill, adicione esta tag de script ao cabeçalho do seu 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 enviar o polyfill condicionalmente com base em User-Agent
ou auto-hospedar na sua própria origem.
Para melhorar a experiência do usuário, recomendamos que você use inicialmente o polyfill apenas para conteúdo abaixo da dobra e faça consultas @supports
para substituí-lo temporariamente por um indicador de carregamento até que o polyfill esteja pronto para exibi-lo:
@supports not (container-type: inline-size) {
.container,
footer {
display: none;
}
.loader {
display: flex;
}
}
Em redes e dispositivos rápidos o suficiente ou em dispositivos que têm suporte nativo a consultas de contêiner, esse indicador de carregamento nunca será exibido.
Novos recursos do Polyfill
O polyfill atualizado é compatível com:
- 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)
, vai ser transmitido depois que o polyfill for carregado. - Suporte completo para a sintaxe CSS (não há mais problema em colocar comentários em qualquer lugar em que eles sejam sintaticamente válidos).
- Modos de escrita vertical (via modo de escrita).
- As unidades relativas do contêiner (
cqw
,cqh
etc.) são aceitas nas condições de consulta, nas declarações de propriedade e nos frames-chave de animação.rem
eem
são aceitos nas condições de consulta. - Sintaxe de consulta do contêiner expandido:
- 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
. - Navegadores sem
:is(...)
/:where(...)
são suportados por uma solução alternativa opcional - As consultas de recurso
orientation
easpect-ratio
. - Filtrar corretamente as consultas com base em recursos. Por exemplo, consultar
height
emcontainer: inline-size
não é permitido corretamente com um modo de gravação horizontal. - Mutação do DOM (por exemplo, remoção de elementos
<style>
e<link>
no momento da execução).
Limitações e avisos do Polyfill
Se você estiver usando o polyfill de consulta de contêiner, há alguns recursos ausentes a serem observados:
- O Shadow DOM ainda não é compatível.
- As unidades relativas do contêiner (por exemplo,
cqw
ecqh
) não são aceitas nas condições de consulta@media
.- Safari: as unidades relativas do contêiner não são compatíveis com frames-chave de animação anteriores à versão 15.4.
calc()
,min()
,max()
ou outras funções matemáticas ainda não são aceitas nas condições de consulta.- Esse polyfill só funciona com CSS inline e de mesma origem. Folhas de estilo de origem cruzada e folhas de estilo em iframes (a menos que um polyfill seja carregado manualmente) não são compatíveis.
- A contenção de
layout
estyle
exige suporte subjacente ao navegador:- Safari 15.4 ou superior
- No momento, o Firefox não é compatível com a contenção de estilos, mas está trabalhando nisso.
Avisos
- Para evitar o impacto de FID e CLS, o polyfill não garante quando o primeiro layout vai ocorrer, mesmo que seja carregado de forma síncrona, exceto que tenta evitar um atraso desnecessário na LCP. Em outras palavras, você nunca deve confiar nele para a primeira pintura.
- Gera
ResizeObserver Loop Errors
. O polyfill original também faz isso, mas é importante mencionar. Isso ocorre porque o tamanho do bloco de umcontainer-type: inline-size
provavelmente muda após a avaliação de uma consulta, masResizeObserver
não tem como dizer que não nos preocupamos com as mudanças no tamanho do bloco. - Esse polyfill é testado em testes da plataforma da Web e atingiu 70% de aprovação, já que alguns recursos, como as APIs JavaScript, não têm polyfill aplicado e, por isso, a taxa de aprovação fica intencionalmente mais perto de 70%.
- A solução alternativa
:where()
é necessária para 2,23% dos usuários de navegadores mais antigos que:- Safari 14
- Cromo 88
- Borda 88
- Samsung Internet 15
- Firefox 78