Curso de CSS / Flexbox: alinhamento, wrap, gap, grow e shrink
O Flexbox combina alinhamento, quebra de linha e dimensionamento flexível para ajustar os itens ao espaço disponível. justify-content funciona ao longo do eixo principal, align-items atua ao longo do eixo transversal, e align-content distribui o conjunto de linhas de um contêiner com wrap quando há espaço livre no eixo transversal.
Associe as propriedades de alinhamento aos seus eixos
| Propriedade | Aplicável a | Condições a verificar |
|---|---|---|
| justify-content | Distribuição dos itens ao longo do eixo principal do contêiner | Espaço restante após definir o tamanho do item |
| align-items | Alinhamento no eixo transversal de cada item | Tamanho transversal do item e dimensão da linha flex |
| align-self | Alinhamento no eixo transversal de itens específicos | Alterar o alinhamento padrão do contêiner individualmente |
| align-content | Alinhamento do grupo de linhas | Contêineres que podem quebrar e espaço restante no eixo transversal |
| gap | Espaçamento entre itens/linhas adjacentes | Espaço e divisão adicionados pelo alinhamento |
Na escrita horizontal deste exemplo, com row, justify-content controla a direção horizontal, e align-items controla principalmente o vertical. Se você mudar para coluna, o eixo principal se torna vertical e a direção física das duas propriedades também muda. Em particular, deve haver espaço deixado na altura do contêiner para comparar o justify-content das colunas. Se a altura se ajustar perfeitamente ao conteúdo, quase não há espaço para mover, mesmo se você mudar para center ou space-between. A direção do eixo e a configuração de início do contêiner Flex podem ser verificadas em Fundamentos do Flexbox: Contêineres, Itens e Eixos.
justify-content: center coloca um grupo de itens no centro, e space-between coloca o primeiro e o último itens nas extremidades e divide o espaço entre eles. gap é o espaço especificado, e space-between distribui o espaço restante. Quando usados juntos, o gap real pode ser maior que o gap. Se o flex-grow de um item usar todo o espaço restante ou a margin automática na direção do eixo principal ocupar espaço, a mudança em justify-content pode não ser visível.
align-items: center alinha itens de diferentes alturas ao centro dentro de uma linha. align-content: center centraliza todas as linhas no eixo transversal. Você não deve pensar nos dois como a mesma função. align-content não tem efeito em contêineres com nowrap. Um contêiner com wrap pode ser afetado mesmo quando seus itens cabem numa única linha, e mesmo em contêineres com wrap, se o tamanho ocupado pelas linhas e a altura do contêiner forem iguais, não há espaço para comparação. Você pode verificar as condições de aplicação no guia de alinhamento Flexbox da MDN.
Compare o alinhamento de itens e o alinhamento de linhas
Salve o código abaixo como flex-align.html e abra-o. A primeira seção contém três itens de diferentes alturas, a segunda seção contém quatro itens em duas linhas quando .lines tem pelo menos 320px de largura externa. Abaixo disso, os itens podem ocupar quatro linhas. O exemplo fixa a altura em 280px para deixar espaço livre e tornar o deslocamento do conjunto visível.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>flex-align.html</title>
<style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.toolbar { display: flex; gap: 12px; justify-content: space-between; align-items: center;
width: 100%; max-width: 640px; min-height: 120px; border: 2px solid #789; padding: 12px; }
.toolbar > div { padding: 8px; background: #dceefa; }
.lines { display: flex; flex-wrap: wrap; gap: 12px; width: min(100%, 360px); height: 280px;
align-items: center; align-content: flex-start; border: 2px solid #789; padding: 12px; }
.lines > div { flex: 0 0 140px; padding: 8px; background: #e8f5de; }
.tall { min-height: 60px; }
</style>
</head>
<body>
<h1>Alignment on one line and multiple lines</h1>
<h2>Toolbar</h2><div class="toolbar"><div>Short item</div><div>Two-line item<br>Second line</div><div>Button position</div></div>
<h2>Line group</h2><div class="lines"><div>1</div><div class="tall">2<br>Second line</div><div>3</div><div class="tall">4<br>Second line</div></div>
</body>
</html>
- Altere o justify-content do .toolbar para center para ver se os três itens ficam juntos no centro. Também comparamos com flex-start e retornamos para space-between. Deixe o tamanho do item e o espaçamento como estão.
- Altere o align-items no .toolbar para flex-start para garantir que ele se alinhe na parte superior. Se você alterá-lo para stretch, os itens com tamanho automático no eixo transversal aumentarão. Após a comparação, ele é restaurado para center.
- Altere apenas o align-content de .lines para center. Um conjunto de duas linhas desce mantendo os relacionamentos dos itens em cada linha. Se você voltar para flex-start e apenas mudar align-items para flex-start, a posição dos itens curtos em cada linha vai mudar.
- Se você apenas mudar o flex-wrap em .lines para nowrap, tudo vai tentar ficar em uma linha, e os itens usam flex-shrink: 0 neste exemplo, fazendo com que ele transborde horizontalmente. Nesse estado, você não pode alinhar múltiplas linhas com align-content. Após a confirmação, restaure para wrap.
Entenda grow, shrink e basis
flex: 1 1 192px é grow, shrink e basis nessa ordem. basis é o tamanho padrão a partir do qual se inicia a distribuição espacial do eixo principal e não é um valor que garante a largura final. Grow é a proporção de aumento para o espaço restante, e shrink é a proporção de encolhimento quando o espaço é insuficiente. Como existe uma regra de valor omitido para números únicos ou auto em abreviação, três valores são especificados e comparados no exemplo de aprendizado.
| declaração | Quando sobra espaço | Quando acaba o espaço |
|---|---|---|
| flex: 0 1 192px | Manter tamanho padrão | Participar da redução |
| flex: 1 1 192px | O espaço restante é distribuído | Participar da redução |
| flex: 0 0 192px | Manter tamanho padrão | Sem redução. Se for nowrap, pode transbordar. |
Por exemplo, se um elemento pai com largura de conteúdo de 640px contiver três itens de tamanho base 100px e dois espaços (cada um de 20px), o espaço restante será 640 − 300 − 40 = 300px. Se a proporção de crescimento for 1:2:1, o espaço adicionado será 75px, 150px e 75px, e a largura final será 175px, 250px e 175px. Este é um cálculo de condições que não envolvem tamanho mínimo de conteúdo ou restrições min/max.
A quantidade de encolhimento não é distribuída de maneira uniforme com base apenas no número de encolhimento. Considere tanto a proporção de redução quanto o tamanho de referência. Se precisarmos reduzir 60px de dois itens com tamanhos padrão de 200px e 100px e ambos os encolhimentos forem 1, então, em condições simples sem restrições, reduziríamos 40px e 20px, resultando em larguras de 160px e 80px. Os resultados podem variar se houver preenchimento, bordas, tamanho mínimo do conteúdo, etc., então você deve realmente verificar os valores aplicados. A descrição de flex do MDN explica a forma abreviada e as condições de tamanho.
Distribua espaço e permita a mudança de linha dos cartões
Salve o seguinte código como flex-size.html. A área de cálculo corresponde ao cálculo acima, criando uma largura máxima de 640px sem qualquer preenchimento ou borda adicional. A lista de cartões usa uma largura de 192px como padrão para quebras de linha, mas preenche o espaço restante. Se uma lista com list-style: none estiver fora de nav, ela pode não ser reconhecida como uma lista na árvore de acessibilidade do Safari. No exemplo, ul especifica role="list" para definir o papel da lista. As condições de acessibilidade ao remover marcadores e espaçamento também são descritas em Estilos de parágrafos e listas com CSS.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>flex-size.html</title>
<style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.calc { display: flex; gap: 20px; width: min(100%, 640px); background: #eef2f6; }
.calc > div { flex: 1 1 100px; min-width: 0; height: 80px; background: #dceefa; }
.calc > div:nth-child(2) { flex-grow: 2; }
.cards { display: flex; flex-wrap: wrap; gap: 16px; list-style: none; padding: 0; }
.cards > li { flex: 1 1 192px; min-width: 0; padding: 16px; background: #e8f5de; overflow-wrap: anywhere; }
</style>
</head>
<body>
<h1>Flex values and space distribution</h1><div class="calc"><div>grow 1</div><div>grow 2</div><div>grow 1</div></div>
<h2>Wrapping card</h2><ul class="cards" role="list"><li>First card</li><li>Second card</li><li>Third card</li><li>Fourth card</li></ul>
</body>
</html>
- Expanda seu navegador para que o .calc tenha 640px de largura e use as Ferramentas de Desenvolvedor para verificar as larguras dos três itens. Será 175px·250px·175px. Se você alterar apenas o crescimento do segundo item para 1, os três itens se tornarão 200px cada. Após a comparação, restaure para 2.
- Basta mudar o crescimento em .cards > li para 0 para garantir que a última linha de cards não preencha a largura extra. Se você restaurar para 1, a última linha também receberá espaço.
- Reduza a tela para ver se menos cards cabem em uma linha. wrap determina em quais linhas colocar, e cada linha distribui o espaço restante separadamente. As larguras dos cards da última linha e da linha anterior não correspondem necessariamente.
- Para ver um transbordamento em uma única linha em vez de uma quebra de linha, defina flex-wrap: nowrap no contêiner e flex: 0 0 192px nos itens. Após verificar as duas condições, restaure o wrap original e 1 1 192px.
Verifique o tamanho mínimo automático e texto longo
A largura mínima automática dos itens Flex pode impedir que áreas contendo endereços ou identificadores longos sejam reduzidas. CSS Overflow, Quebra de Texto Longo e Reticências explica como min-width: 0 permite reduzir a caixa do item, enquanto overflow-wrap: anywhere permite que a própria string seja quebrada. Reduzir uma caixa não trunca automaticamente o texto dentro dela, então você precisa distinguir entre os dois problemas.
Salve o código abaixo como flex-long-text.html. O exemplo contém um identificador longo sem espaços, usado apenas para observar o layout. Mesmo que a tela seja reduzida, o texto ao lado da área de orientação é lido dividido em várias linhas. Você pode verificar as regras de quebra de linha na descrição de overflow-wrap do MDN.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>flex-long-text.html</title>
<style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.notice { display: flex; gap: 12px; max-width: 600px; border: 2px solid #789; padding: 12px; }
.icon { flex: 0 0 48px; background: #ffe4b5; }
.text { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; background: #dceefa; }
.text p { margin: 0; }
</style>
</head>
<body>
<h1>Long strings and minimum sizes</h1><div class="notice"><div class="icon">Notice</div><div class="text"><p>ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</p></div></div>
</body>
</html>
- Em .text, apenas altere overflow-wrap para normal. Mesmo que a largura do item seja reduzida, a string pode ultrapassar os limites. Restaure o valor anywhere.
- Para ver o impacto do min-width separadamente, remova min-width: 0 mantendo overflow-wrap: normal. Depois de determinar como o tamanho mínimo de strings longas afeta a colocação dos itens, restauramos ambas as declarações aos seus valores originais.
Se o alinhamento não for possível, primeiro verifique o eixo do elemento pai e o espaço restante. Se o tamanho não diminuir, verifique o tamanho mínimo do item e a string interna. Se você colocar overflow: hidden em todo o pai para esconder o problema, pode perder conteúdo ou a indicação de foco. É mais fácil julgar os resultados se o tamanho do layout e a exibição do conteúdo forem resolvidos separadamente.




