- 1 Noções básicas
- 2 Flexbox
- 3 Grade e subgrade
- 4 Consultas de contêiner
- 5 Sobreposições nativas, posicionamento de âncora e contextos de empilhamento
- 6 Rastreamento de overflow e estabilidade do layout
- 7 Mecânica da janela de visualização e distribuição de faixas
- 8 faixas de grade (também conhecidas como alvenaria)
1 Conceitos básicos
Sempre que possível, use o mecanismo de layout do navegador para melhorar o desempenho. Use o dimensionamento intrínseco, as propriedades lógicas e aspect-ratio antes de recorrer a dimensões fixas ou consultas de mídia complicadas.
1.1 Qual modo de layout usar?
Percorra a árvore de decisão de cima para baixo e pare na primeira correspondência. Os layouts podem ser aninhados uns nos outros, e cada decisão é baseada no caso de uso do contêiner.
- É uma linha OU coluna simples de itens? Use o flexbox: 1D, prioriza o conteúdo, que é distribuído ao longo de um único eixo.
- Um elemento aninhado precisa se alinhar com as faixas da grade do elemento pai? Use subgrid: 2D, prioriza as relações, herda as faixas pai para que os netos possam se alinhar entre os irmãos.
- É uma estrutura complexa de página ou componente com linhas E colunas? Use grid: 2D, prioriza o layout, você define o esqueleto e o conteúdo o preenche.
- O conteúdo é um fluxo longo de prosa que precisa ser dividido em colunas equilibradas? Use várias colunas: fluxo 1D, estilo jornal.
- Os itens têm alturas variadas e precisam ser embalados de forma compacta? Use grid com
grid-auto-flow: densehoje. Use o masonry nativo (também conhecido como "faixas de grade") somente quando ele for enviado no seu destino Baseline (consulte §8). - Um elemento precisa flutuar acima da página e permanecer espacialmente vinculado a um acionador, mesmo em limites do DOM ou contextos de empilhamento? Use o posicionamento de âncora:
anchor-nameno acionador,position-anchorna sobreposição (consulte o §5).
1.2 Princípios de trabalho
- Use propriedades lógicas (
inline-size,block-size,margin-inline,padding-block,inset-inline-start) para dimensões e espaçamento de layout. Consulte CSS: Modern Architecture para uma cobertura completa. - Aplique o modelo mental de conteúdo primeiro x layout primeiro: flexbox quando os itens ditam o fluxo, grade quando você define o esqueleto primeiro.
- Use as abreviações de
place-*(place-content,place-items,place-self) para alinhar os dois eixos em uma única declaração. - Use o dimensionamento intrínseco (
min-content,max-content,fit-content()) e as faixas flexíveis (fr,minmax()) antes dewidth/heightfixos: menos consultas de mídia, layouts mais resilientes. - NÃO use
overflow: hiddenpara mascarar problemas de layout. Corrija-os na origem. Por exemplo, alguns elementos substituídos, como<canvas>,<img>,<svg>,<video>e<iframe>, usamdisplay: inlinepor padrão, o que pode adicionar um espaço em determinados layouts. Em vez de cortar o espaço comoverflow, remova-o aplicando um valor de exibição externa de bloco (por exemplo,display: block,grid,flexetc.). - Use
aspect-ratiopara reservar espaço para mídia e evitar mudanças de layout antes que os recursos sejam carregados.
.sidebar { inline-size: max-content; } /* Size to longest unbreakable token. */
.main-content { inline-size: fit-content; } /* Grow to available space, no further. */
.media { aspect-ratio: 16 / 9; inline-size: 100%; block-size: auto; }
body.centered { display: grid; place-content: center; min-block-size: 100dvb; }
Para
calc-size()e dimensionamento intrínseco com restrições, consulte Calcular com tamanhos intrínsecos.
2 Flexbox
Layout unidimensional: os itens fluem ao longo de um único eixo principal com alinhamento no eixo transversal. Use-o para barras de navegação, barras de ferramentas, linhas de itens e qualquer distribuição de linha ou coluna única.
O que fazer:
- Estabeleça um contexto com
display: flexe defina o eixo principal comflex-direction(padrãorow). - Use
flex-wrap: wrapsempre que houver possibilidade de transbordamento.nowrapsemoverflow: auto/hiddenvai transbordar em janelas de visualização estreitas. - Camada
flex-wrap: balanceapósflex-wrap: wrapem linhas agrupadas de itens compactos (como nuvens de tags, pílulas de filtro, grupos de botões ou links de navegação) para distribuir os itens de maneira uniforme entre as linhas e evitar um único item órfão na linha final. Os navegadores sem suporte usamwrap. - Use a abreviação
<grow> <shrink> <basis>deflex(por exemplo,flex: 1 1 250px) em itens em vez de definirflex-grow/flex-shrink/flex-basisindividualmente. - Use
gap(ou a forma completarow-gap/column-gap) para o espaçamento entre itens em vez de margens filhas. - Prefixe o alinhamento posicional com
safe(por exemplo,align-items: safe center) para que o conteúdo focalizável não seja cortado quando o contêiner for mais estreito que o conteúdo. - Envie um único item para a extremidade do eixo principal com
margin-inline-start: auto(oumargin-block-start: auto). Essa é a saída de emergência padrão. - Substitua o alinhamento entre eixos por item com
align-self. - Use
align-itemspara centralizar todos os itens no eixo transversal. Usemargin: autoem um único item para centralizá-lo nos dois eixos de forma independente. Usealign-contentsomente quando o contêiner tiver quebra de linha e espaço extra entre as linhas. - Defina
min-inline-size: 0(oumin-width: 0) em itens flexíveis que contêm conteúdo longo que não pode ser quebrado (URLs, código, strings longas). Por padrão, os itens flexíveis não diminuem abaixo do tamanho do conteúdo, o que causa estouro.
Não faça o seguinte:
- Não use
justify-selfem itens flexíveis. Ele só funciona em layouts de grade, bloco e posicionamento absoluto. Use margens automáticas. - Não use
orderouflex-direction: *-reversepara reordenar o conteúdo interativo. Eles mudam apenas a ordem visual. A ordem do DOM ainda determina o foco sequencial, então o fluxo de tabulação do teclado não vai corresponder ao que o usuário vê. - Não confunda
space-around(metade do espaçamento nas extremidades) comspace-evenly(espaçamentos iguais antes, entre e depois). - Não se esqueça da inversão de eixo: quando
flex-direction: column,justify-contentse alinha no eixo de bloco ealign-itemsse alinha no eixo inline, o oposto do padrão. - Não dimensione o contêiner e os filhos para que eles se preencham, porque isso é uma fonte comum de estouro e resultados surpreendentes. Defina um tamanho para um dos lados.
- Não defina
flex-basisewidth/inline-sizeno mesmo item.flex-basistem precedência em um contexto flexível, ewidthé ignorado. Useflex-basis(ou a abreviaçãoflex) como a única fonte de verdade para dimensionar itens flexíveis.
.card-grid { display: flex; flex-flow: row wrap; gap: 1rem; }
.card-item { flex: 1 1 250px; } /* grow, shrink, basis */
.card-item-action { margin-inline-start: auto; } /* Push to main-axis end. */
.toolbar { display: flex; align-items: safe center; }
.tag-list { display: flex; flex-wrap: wrap; flex-wrap: balance; gap: 0.5rem; }
3 Grade e subgrade
Layout bidimensional: defina linhas E colunas explicitamente ou deixe que o mecanismo as derive. A subgrade permite que uma grade aninhada herde as faixas da grade pai para que os netos se alinhem entre os irmãos.
Como escolher os recursos da grade:
- Você sabe exatamente de quantas colunas precisa?
- Sim: use faixas explícitas (
grid-template-columns: 200px 1fr,repeat(3, 1fr)etc.) - As colunas precisam de tamanhos diferentes (barra lateral + principal, cabeçalho abrangendo tudo)? → use
grid-template-areaspara regiões nomeadas e legíveis - Todas as colunas são uniformes ou posicionadas apenas pelo número da linha? → use
repeat(N, ...)ou linhas nomeadas - Não (responsivo, contagem de itens desconhecida): use
repeat(auto-fit, minmax(min, 1fr)). - Os itens na última linha devem ser esticados para preencher o espaço restante? →
auto-fit - As faixas vazias da última linha devem manter o tamanho mínimo (preservando os espaços fantasmas da coluna)? →
auto-fill
- Sim: use faixas explícitas (
- Você precisa colocar um item em um local específico?
- Sim: use
grid-column: <start> / <end>ougrid-area: <name> - Não (apenas abrangendo várias faixas, a posição do fluxo não importa): use
grid-column: span <n>
- Sim: use
- Os elementos filhos precisam herdar os tamanhos de faixa da grade pai (alinhamento de borda irregular entre irmãos)?
- Sim: use a subgrade no eixo afetado.
- O número de filhos por célula é variável? → subgrade apenas um eixo; use
grid-auto-rows/grid-auto-columnspara o outro - A contagem de filhos é fixa? → subgrid em ambos os eixos é aceitável
- Não: grade padrão, sem necessidade de subgrade
O que fazer:
- Estabeleça um contexto com
display: grid. - Use
grid-template-areaspara layouts complexos no nível da página. Os nomes das áreas são autodocumentados, e a declaração pode ser alinhada em linhas e colunas para facilitar a leitura. - Use
repeat(auto-fit, minmax(200px, 1fr))para grades de cards responsivas que esticam as faixas preenchidas para completar a linha ouauto-fillpara preservar as faixas repetidas vazias no tamanho mínimo. - Use
frpara distribuição proporcional de faixas eminmax(min, max)para faixas flexíveis, mas limitadas. - Posicione itens com
grid-column: span <n>para dimensionar entre faixas,grid-column: <start> / <end>para colocar em linhas específicas ougrid-area: <name>para regiões nomeadas. - Use a subgrade (
grid-template-columns: subgridougrid-template-rows: subgrid) para resolver o problema de "borda irregular" em listas de cards. Elementos internos, como títulos, metadados e CTAs, se alinham entre os irmãos. - Combine uma declaração de subgrade com uma declaração
grid-template-rows/-columnsexplícita anterior como um substituto de mesma cascata para navegadores mais antigos.
Não faça o seguinte:
- Não espere que o tamanho da faixa
auto-fit/auto-fillvenha do conteúdo do item. Ele vem do argumento de tamanhorepeat(). - Não use
grid-auto-flow: denseem conteúdo interativo. Ele agrupa os itens de forma eficiente, mas os reordena visualmente, quebrando o fluxo de tabulação do teclado na ordem do DOM. - Não aplique a subgrade aos dois eixos quando a contagem de filhos for variável. Os extras vão para a última faixa. Use
grid-auto-rows/grid-auto-columnspara o eixo implícito. - Não confunda
justify-items/align-items(alinha o conteúdo do item na faixa) comjustify-content/align-content(alinha as faixas da grade no contêiner). Usar o errado não tem efeito. - Não use
repeat(auto-fit/auto-fill, ...)sem uminline-sizedefinido no contêiner. Dentro dedisplay: inline-gridou de um item flexível sem tamanho, o contêiner não tem largura para dividir, o que torna as contagens de faixas imprevisíveis.
3.1 Exemplo de código: grade e subgrade
Shell da página: <main class="page-layout"> contém <header>, <aside>, um <section class="card-grid"> com <div class="card"> filhos e <footer>.
/* Align grid-template-areas in rows and columns for readability. */
.page-layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
gap: 1.5rem;
}
header { grid-area: header; }
aside { grid-area: sidebar; }
footer { grid-area: footer; }
.card-grid {
grid-area: main;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
grid-template-rows: auto 1fr; /* title block, body block */
gap: 1rem;
}
.card {
grid-row: span 2;
display: grid;
/* Same-cascade fallback: ignored when subgrid is supported. */
grid-template-rows: auto 1fr;
grid-template-rows: subgrid;
}
4 Consultas de contêiner
Consulte o tamanho (ou estilo computado) de um contêiner ancestral em vez da janela de visualização. Modelo mental: consultas de contêiner = contexto do componente; consultas de mídia = layout global da página e preferências do usuário (prefers-color-scheme, prefers-reduced-motion).
O que fazer:
- Estabeleça um contexto de contenção com
container-type: inline-size(consultas somente de largura) oucontainer-type: size(ambos os eixos) em um wrapper antes que os descendentes possam ser consultados. - Nomeie os contêineres com
container-name(ou a abreviaçãocontainer:container: card / inline-size) quando contextos aninhados puderem entrar em conflito. - Inclua unidades de consulta de contêiner no cálculo do tipo e do espaçamento fluidos:
cqi/cqb(inline/bloco lógico),cqw/cqh(físico),cqmin/cqmax. - Dê ao contêiner um
block-sizedefinido sempre quecontainer-type: sizefor usado. Sem isso, os descendentes vão ser recolhidos porque a contenção de tamanho força o contêiner a ignorar o conteúdo.
Não faça o seguinte:
- Não use
block-sizecomo um valor decontainer-type, porque ele não é válido. Usesizepara os dois eixos. - Não espere que o tamanho intrínseco dos filhos influencie o contêiner depois de declarar
container-type. O contêiner é calculado como se não tivesse filhos quando a contenção está ativa. - Não use unidades de consulta de contêiner em descendentes de um ancestral não qualificado. Elas vão usar a janela de visualização pequena (
svw/svh).
4.1 Exemplo de código: tipografia fluida usando unidades de consulta de contêiner
.card-wrapper {
container: card / inline-size; /* shorthand for container-name / container-type */
}
@container card (inline-size > 400px) {
.content {
display: flex;
gap: 2rem;
}
}
.title {
/* Fluid type bound to the container width, not the viewport. */
font-size: clamp(1rem, 4cqi, 2rem);
}
Para padrões de estilo responsivos orientados por componentes, consulte Estilo que considera o tamanho e Escalonamento fluido.
5 Sobreposições nativas, posicionamento de âncora e contextos de empilhamento
Quando usar cada primitiva de sobreposição:
- Use
popoverpara IU temporária e não modal (flyouts, toasts, dicas) que fica na camada superior, sem necessidade de gerenciamento dez-index. - Use
<dialog>com.showModal()para interações modais que exigem captura de foco e um plano de fundo inerte. - Não combine
popovere.showModal()no mesmo elemento, porque eles são estados de execução mutuamente exclusivos.
Posicionamento de âncora (layout espacial de sobreposições):
- Use
position-area(ouanchor()em inserções) eanchor-size()para posicionar e dimensionar uma sobreposição em relação ao acionador. - Use
position-try-fallbacks: flip-block(ouflip-inline) para permitir que o navegador reposicione quando a sobreposição ultrapassar a janela de visualização. - Não misture palavras-chave físicas e lógicas em um único valor
position-area. Escolha um sistema de coordenadas. - Detecte recursos com
@supports (anchor-name: --x)e forneça um substituto de posição absoluta.
Para detalhes completos de implementação, estratégias de polyfill e referência de valor de
popover, consulte Controle declarativo de caixas de diálogo e pop-overs e Dicas de ferramentas que consideram a posição. Para o posicionamento de âncora aplicado a menus suspensos, menus flutuantes e indicadores de guia, consulte Menus suspensos que consideram a janela de visualização e Sublinhado da guia de posicionamento de âncora.
6 Rastreamento de overflow e estabilidade do layout
Gerencie mudanças de layout, barras de rolagem e cortes de forma previsível.
O que fazer:
- Use
overflow: autopara que as barras de rolagem apareçam apenas quando o conteúdo realmente ultrapassar o limite. - Use
overflow: clippara cortar conteúdo sem estabelecer um contêiner de rolagem. Ative o transbordamento comoverflow-clip-margin. - Use
scrollbar-gutter: stablepara reservar espaço para barras de rolagem e evitar mudanças de layout quando o conteúdo aumenta. - Use
overscroll-behavior: contain(ounone) em regiões de rolagem aninhadas (como barras laterais, modais e listas) para impedir que as cadeias de rolagem se propaguem para a página, ouoverscroll-behavior: chainem wrappers de rolagem intermediários (como faixas de deslizar para revelar) quando o excesso de rolagem precisa ser propagado para um scroller ancestral sem acionar um efeito de elástico local. Use a tríade
-webkit-line-clamp+display: -webkit-box+-webkit-box-orient: verticalpara truncamento de várias linhas. Apesar do prefixo, esse padrão é totalmente especificado e não foi descontinuado. Declare a abreviaçãoline-clampsem prefixo ao lado dela. Os navegadores que ainda não são compatíveis com ela ignoram a propriedade sem causar danos. Não faça o seguinte:Não use
overflow: scrollquandoautofor suficiente.scrollforça as barras de rolagem mesmo quando não há nada para rolar.Não use
overflow: hiddenquando quiser apenas cortar. Ohiddenestabelece um contêiner de rolagem que pode ser rolado de forma programática.
.scrollable-list {
max-block-size: 400px;
overflow-y: auto;
scrollbar-gutter: stable; /* Reserve scrollbar space. */
overscroll-behavior: contain; /* No scroll chaining into the page. */
}
.snippet {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
line-clamp: 3; /* Ignored where unsupported. */
overflow: clip;
}
Para saber mais sobre
overflow: clipeoverflow-clip-margin, consulte Controle de corte de estouro. Para transferência de rolagem aninhada comoverscroll-behavior: chainna interface de deslizar para revelar, consulte Deslizar para revelar. Para saber mais sobre a cor, o tamanho e o tema da barra de rolagem, consulte Personalizar a cor ou a espessura de uma barra de rolagem, Modo escuro e Adaptar a barra de rolagem às preferências de alto contraste.
7 Mecânica da janela de visualização e distribuição de faixas
- Use
dvh/dvwpara contêineres de layout para dispositivos móveis que precisam considerar a mudança na interface do navegador (recolhimento/expansão da barra de URL). - Não use
100vwpara layout de largura total, porque ele ignora a largura da barra de rolagem e causa estouro horizontal. Use100%,100dvwou100svw.
Para o ponto de entrada do design responsivo (unidades de janela de visualização dinâmica, reserva de espaço para mídia, tipografia fluida), consulte Design responsivo.
8 faixas de grade (também conhecidas como masonry)
A especificação está em desenvolvimento com o nome "faixas de grade" (por exemplo, display: grid-lanes), enquanto os protótipos experimentais anteriores usavam grid-template-rows: masonry.
O que fazer:
- Use a grade com
grid-auto-flow: densepara compactação hoje, aceitando que a ordem do DOM pode não corresponder à ordem visual. - Use várias colunas (
columns: 3; column-gap: 1rem) para um fluxo semelhante a alvenaria com muito conteúdo quando os itens forem fragmentos de documentos, em vez de cards de peso igual. - Trate
grid-template-rows: masonryapenas como um aprimoramento progressivo: use@supportspara detectar recursos.
Não faça o seguinte:
- Não envie
grid-template-rows: masonrycomo um requisito rígido até que sua meta de referência seja alcançada.
.gallery { columns: 3 200px; column-gap: 1rem; }
.gallery > * { break-inside: avoid; margin-block-end: 1rem; }
@supports (grid-template-rows: masonry) {
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-template-rows: masonry;
gap: 1rem;
columns: unset;
}
}