Propriedade align-content: Alinhando linhas de itens (com flex-wrap)

Controle o espaçamento entre as linhas de itens quando há quebra.

Você já aprendeu que align-items alinha os Itens Flex individualmente ao longo do eixo cruzado. No entanto, quando você tem um Contêiner Flex com flex-wrap: wrap; (ou wrap-reverse;) e os itens quebram em múltiplas linhas (ou colunas), align-items não controla o espaçamento entre essas linhas.

É aí que entra a propriedade align-content. Ela é aplicada ao Contêiner Flex e controla como as múltiplas linhas de Itens Flex são alinhadas e como o espaço extra é distribuído ao longo do eixo cruzado do contêiner.

Pense no align-content como o "organizador de prateleiras" em uma estante. Se você tem várias prateleiras (flex-lines) dentro de uma estante (flex-container), o align-content decide se essas prateleiras ficam no topo, na base, no centro, ou se o espaço extra é distribuído entre elas.

[[google images: CSS align-content analogy]]

Pré-requisito para align-content

Para que align-content tenha qualquer efeito, duas condições devem ser atendidas:

  1. O Contêiner Flex deve ter flex-wrap: wrap; ou flex-wrap: wrap-reverse;. Se flex-wrap: nowrap;, não haverá múltiplas linhas para alinhar.
  2. Deve haver espaço extra no contêiner ao longo do eixo cruzado para que as linhas possam ser distribuídas. Isso geralmente significa que o contêiner precisa ter uma height definida (se flex-direction: row;) ou uma width definida (se flex-direction: column;) que seja maior do que a soma das alturas (ou larguras) das linhas de itens.

Valores da Propriedade align-content

A propriedade align-content aceita valores muito semelhantes aos de justify-content, mas opera nas linhas de itens, não nos itens individuais:

  1. stretch (padrão):

    • As linhas são "esticadas" para ocupar o espaço restante no eixo cruzado. Cada linha terá a mesma altura (ou largura, se flex-direction: column;).
  2. flex-start:

    • As linhas são agrupadas no início do eixo cruzado.
    • Se flex-direction: row;, as linhas ficam no topo.
    • Se flex-direction: column;, as linhas ficam à esquerda.
  3. flex-end:

    • As linhas são agrupadas no fim do eixo cruzado.
    • Se flex-direction: row;, as linhas ficam na parte inferior.
    • Se flex-direction: column;, as linhas ficam à direita.
  4. center:

    • As linhas são agrupadas no centro do eixo cruzado.
  5. space-between:

    • As linhas são distribuídas uniformemente ao longo do eixo cruzado. A primeira linha fica no início e a última linha fica no fim. O espaço restante é distribuído igualmente entre as linhas.
  6. space-around:

    • As linhas são distribuídas uniformemente ao longo do eixo cruzado, com espaço igual ao redor de cada linha. O espaço antes da primeira linha e depois da última linha é metade do espaço entre as linhas.
  7. space-evenly:

    • As linhas são distribuídas uniformemente ao longo do eixo cruzado, com espaço igual entre as linhas e nas extremidades. O espaço antes da primeira linha, entre as linhas e depois da última linha é exatamente o mesmo.

Exemplo Prático:

<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <title>Align-content</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
      background-color: #f4f4f4;
    }

    .flex-container {
      display: flex;
      flex-wrap: wrap; /* Essencial para align-content funcionar */
      background-color: #e0e0e0;
      border: 2px solid #333;
      padding: 10px;
      height: 300px; /* Altura fixa para o contêiner para ver o alinhamento das linhas */
      width: 300px; /* Largura limitada para forçar a quebra */
      margin-bottom: 20px;
    }

    .flex-item {
      background-color: lightblue;
      border: 1px solid blue;
      padding: 15px;
      margin: 5px;
      color: #333;
      font-weight: bold;
      text-align: center;
      width: 100px; /* Largura fixa para os itens */
      height: 60px; /* Altura fixa para os itens */
      line-height: 60px; /* Para centralizar texto verticalmente */
      flex-shrink: 0; /* Impede que os itens encolham */
    }

    /* --- Exemplos de align-content --- */

    .container-stretch {
      align-content: stretch; /* Padrão */
    }

    .container-start {
      align-content: flex-start;
    }

    .container-end {
      align-content: flex-end;
    }

    .container-center {
      align-content: center;
    }

    .container-space-between {
      align-content: space-between;
    }

    .container-space-around {
      align-content: space-around;
    }

    .container-space-evenly {
      align-content: space-evenly;
    }

    /* Exemplo com flex-direction: column */
    .container-column {
      flex-direction: column;
      flex-wrap: wrap;
      width: 400px; /* Largura fixa para o contêiner para ver o alinhamento das colunas */
      height: 300px; /* Altura limitada para forçar a quebra */
      align-content: space-around; /* Exemplo de align-content em coluna */
    }
  </style>
</head>
<body>
  <h1>Propriedade `align-content`</h1>

  <h2>`align-content: stretch` (Padrão)</h2>
  <div class="flex-container container-stretch">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
  </div>
  <p>Linhas esticadas para preencher o espaço restante no eixo cruzado.</p>

  <h2>`align-content: flex-start`</h2>
  <div class="flex-container container-start">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
  </div>
  <p>Linhas agrupadas no início do eixo cruzado (topo).</p>

  <h2>`align-content: flex-end`</h2>
  <div class="flex-container container-end">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
  </div>
  <p>Linhas agrupadas no fim do eixo cruzado (base).</p>

  <h2>`align-content: center`</h2>
  <div class="flex-container container-center">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
  </div>
  <p>Linhas agrupadas no centro do eixo cruzado.</p>

  <h2>`align-content: space-between`</h2>
  <div class="flex-container container-space-between">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
  </div>
  <p>Linhas distribuídas uniformemente, com a primeira no início e a última no fim.</p>

  <h2>`align-content: space-around`</h2>
  <div class="flex-container container-space-around">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
  </div>
  <p>Linhas distribuídas uniformemente, com espaço igual ao redor de cada linha.</p>

  <h2>`align-content: space-evenly`</h2>
  <div class="flex-container container-space-evenly">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
  </div>
  <p>Linhas distribuídas uniformemente, com espaço igual entre as linhas e nas extremidades.</p>

  <h2>`align-content` com `flex-direction: column`</h2>
  <div class="flex-container container-column">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
  </div>
  <p>Colunas distribuídas horizontalmente com `space-around`.</p>
</body>
</html>

Resultado:

  • Você verá como as múltiplas linhas de itens se alinham e o espaço é distribuído de diferentes maneiras ao longo do eixo cruzado, tanto na direção row quanto na column.

Boas Práticas:

  • Pré-requisito flex-wrap: Lembre-se que align-content só funciona se flex-wrap estiver definido como wrap ou wrap-reverse.
  • Espaço Extra no Eixo Cruzado: Para que align-content tenha efeito, o Contêiner Flex precisa ter espaço extra ao longo do eixo cruzado (ex: height para row, width para column).
  • align-items vs align-content:
    • align-items alinha os itens individuais dentro de cada linha.
    • align-content alinha as linhas inteiras umas em relação às outras.
    • Se houver apenas uma linha de itens (ou seja, flex-wrap: nowrap; ou os itens cabem em uma linha), align-content não terá efeito, e align-items controlará o alinhamento dos itens dentro dessa única linha.

Dominar align-content é fundamental para criar layouts Flexbox complexos e responsivos que envolvem múltiplas linhas de itens, garantindo que o espaçamento e o alinhamento entre essas linhas sejam precisos e controlados.