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 no Safari 16, será possível criar consultas de contêiner com base 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 da Aurora no Chrome trabalhou duro para atualizar a Polyfill de consulta de contêiner para oferecer suporte a mais navegadores e casos de uso, para que você possa usar esse recurso eficiente com confiança.
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. Você pode criar um design responsivo verdadeiramente baseado em componentes consultando o tamanho de um pai. Essas informações são muito mais granulares e úteis do que algo como media queries, que fornecem apenas informações de tamanho sobre a viewport.
Com consultas de contêiner, é possível criar componentes reutilizáveis que podem aparecer de maneiras diferentes com base no local em que residem na página. Isso os torna muito mais resilientes e responsivos em páginas e modelos.
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 ficar mais claro 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 do 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 em linha 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 maior valor 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 diminui. Para ir além, use a função clamp()
para definir um limite de tamanho mínimo e máximo para a tipografia e dimensione-a 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.
Essa demonstração vai um pouco além e atualiza os cards mais amplos para ter um intervalo de tamanho menor, já que eles são apresentados 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á-la aos seus projetos, e saiba que o suporte ao navegador é grande parte 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 superior
- Edge 79 ou mais recente
- Safari 13.4 ou mais recente
Ele tem menos de 9 KB quando compactado e usa o ResizeObserver com o 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 entregar condicionalmente o polyfill com base em User-Agent
ou auto-hospedá-lo na sua própria origem.
Para ter a melhor experiência do usuário, recomendamos que, inicialmente, você use o polyfill apenas 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 exibição:
@supports not (container-type: inline-size) {
.container,
footer {
display: none;
}
.loader {
display: flex;
}
}
Em redes e dispositivos suficientemente rápidos ou dispositivos que suportam nativamente consultas de contêiner, esse indicador de carregamento nunca será exibido.
Novos recursos do polyfill
O polyfill atualizado oferece suporte a:
- Regras
@container
aninhadas. - É possível aninhar regras
@container
nas 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 as 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
. - Filtrar corretamente as consultas com base nos recursos. Por exemplo, a consulta de
height
emcontainer: inline-size
não é permitida com o modo de escrita horizontal. - Mutação do DOM (por exemplo, elementos
<style>
e<link>
sendo removidos 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:
- O Shadow DOM ainda não é compatível.
- As unidades relativas ao contêiner (por exemplo,
cqw
ecqh
) não são compatíveis com as condições de consulta@media
.- Safari: as unidades relativas do 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
exige suporte subjacente a um navegador:- Safari 15.4 ou mais recente
- O Firefox não oferece suporte à contenção de estilos 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 nela para a first paint.
- Gera
ResizeObserver Loop Errors
. O polyfill original também faz isso, mas vale a pena destacar. Isso ocorre porque o tamanho do bloco de umacontainer-type: inline-size
provavelmente vai mudar após a avaliação de uma consulta, masResizeObserver
não tem como dizer 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
- Borda 88
- Samsung Internet 15
- Firefox 78