Tutorial de CSS Flexbox: o guia completo com exemplos

Tutorial de CSS Flexbox: o guia completo com exemplos

Flexbox é um módulo de layout CSS que te permite criar disposições flexíveis e adaptáveis para os teus elementos HTML. É particularmente útil quando o layout tem de se adaptar a vários tamanhos de ecrã ou a vários dispositivos.

Com Flexbox, alinhas os elementos na horizontal ou na vertical, controlas o espaço entre eles e defines a ordem por que aparecem. Também oferece formas flexíveis de dimensionar os elementos, que é precisamente o que um layout responsivo precisa.

Para usares Flexbox no teu projeto, começas por declarar um contentor flex com a propriedade CSS display: flex ou display: inline-flex num elemento HTML. A partir daí, as propriedades do Flexbox controlam a disposição dos seus filhos.

css
.container-flex {
    display: flex;
}

Como alinhar os elementos com Flexbox

Uma das funcionalidades mais úteis do Flexbox é a forma flexível como alinha os elementos. Existem várias propriedades para controlar o alinhamento dos elementos dentro de um contentor flex.

Alinhamento horizontal dos elementos com justify-content

A propriedade justify-content controla o alinhamento horizontal dos elementos. 

justify-content: flex-start;

Item
Item

justify-content: center;

Item
Item

justify-content: flex-end;

Item
Item

justify-content: space-between;

Item
Item

justify-content: space-around;

Item
Item

justify-content: space-evenly;

Item
Item
css
/*alinha os elementos pelo bordo esquerdo*/
.container {
    justify-content: flex-start;
}
/*centra os elementos*/
.container {
    justify-content: center;
}
/*alinha os elementos pelo bordo direito*/
.container {
    justify-content: flex-end;
}
/*distribui os elementos uniformemente entre o bordo esquerdo e o direito, sem espaço nos bordos*/
.container {
    justify-content: space-between;
}
/*distribui os elementos uniformemente entre o bordo esquerdo e o direito, com o mesmo espaço nos dois bordos*/
.container {
    justify-content: space-around;
}
/* distribui os elementos uniformemente entre o bordo esquerdo e o direito, com o mesmo espaço nos dois bordos e entre cada elemento */
.container {
    justify-content: space-evenly;
}

Alinhamento vertical dos elementos com align-items

A propriedade align-items controla o alinhamento vertical dos elementos.

align-items: flex-start;

Item
Item

align-items: center;

Item
Item

align-items: flex-end;

Item
Item

align-items: stretch;

Item
Item
css
/* Alinhar todos os elementos em cima */
.container {
    align-items: flex-start;
}

/* Alinhar todos os elementos ao centro */
.container {
    align-items: center;
}

/* Alinhar todos os elementos em baixo */
.container {
    align-items: flex-end;
}

/*faz com que os elementos se ajustem à altura do seu conteúdo*/
.container {
    align-items: stretch;
}

Como gerir o espaço entre os elementos com Flexbox

O Flexbox também te deixa gerir o espaço entre os elementos de forma flexível. Existem várias propriedades para controlar o espaçamento dentro de um contentor flex.

Acrescentar espaçamento entre os elementos com margin

A propriedade margin define o espaço entre um elemento e os restantes. Serve para acertar o espaçamento elemento a elemento.

css
/* Acrescentar 20px de espaço entre cada elemento */
.item {
    margin: 0 20px;
}

Acrescentar espaçamento à volta de um elemento com padding

A propriedade padding define o espaço entre os limites de um elemento e o seu conteúdo. Serve para acrescentar espaço à volta de um elemento, caso a caso.

css
/* Acrescentar 20px de espaço à volta de um elemento */
.item {
    padding: 20px;
}

Usar gap para espaçar os elementos

Desde o CSS Grid Layout, o Flexbox pode usar gap para acrescentar espaço entre os elementos. Esta propriedade define um espaço uniforme entre todos os elementos de um contentor flex.

css
/* Acrescentar 20px de espaço entre todos os elementos */
.container {
    gap: 20px;
}

Podes combiná-la com row-gap e column-gap para definir espaçamentos diferentes nas linhas e nas colunas. Atenção: só é tida em conta nos filhos diretos do contentor flex e convém verificar a compatibilidade dos navegadores antes de a usar.

As propriedades do Flexbox

O Flexbox tem muitas propriedades para criar disposições flexíveis e adaptáveis para os teus elementos HTML. Nesta parte, vamos ver as mais usadas.

flex-direction

A propriedade flex-direction define a direção em que os elementos são dispostos num contentor flex. Há quatro valores possíveis: row, row-reverse, column e column-reverse. O valor por omissão é row.

flex-direction: row;

Item 1
Item 2

flex-direction: row-reverse;

Item 1
Item 2

flex-direction: column;

Item 1
Item 2

flex-direction: column-reverse;

Item 1
Item 2
css
/* Disposição dos elementos em linha (por omissão) */
.container {
    flex-direction: row;
}

/* Disposição dos elementos em linha invertida */
.container {
    flex-direction: row-reverse;
}

/* Disposição dos elementos em coluna */
.container {
    flex-direction: column;
}

/* Disposição dos elementos em coluna invertida */
.container {
    flex-direction: column-reverse;
}

flex-wrap

A propriedade flex-wrap define se os elementos de um contentor flex devem ser dispostos numa única linha ou em várias linhas. Existem três valores possíveis: nowrap (por defeito), wrap e wrap-reverse, que empilha as linhas por ordem inversa.

flex-wrap: nowrap;

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7

flex-wrap: wrap;

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
css
/* Disposição dos elementos numa única linha (por omissão) */
.container {
    flex-wrap: nowrap;
}

/* Disposição dos elementos em várias linhas */
.container {
    flex-wrap: wrap;
}

flex-flow

A propriedade flex-flow é um atalho para flex-direction e flex-wrap:

css
/* Disposição dos elementos em linha e em várias linhas */
.container {
    flex-flow: row wrap;
}

justify-content

A propriedade justify-content define como os elementos ficam alinhados no eixo horizontal (x) de um contentor flex. Há vários valores possíveis: flex-start, center, flex-end, space-between, space-around e space-evenly. O valor por omissão é flex-start.

css
/*alinha os elementos pelo bordo esquerdo*/
.container {
    justify-content: flex-start;
}
/*centra os elementos*/
.container {
    justify-content: center;
}
/*alinha os elementos pelo bordo direito*/
.container {
    justify-content: flex-end;
}
/*distribui os elementos uniformemente entre
o bordo esquerdo e o direito, sem espaço nos bordos*/
.container {
    justify-content: space-between;
}
/*distribui os elementos uniformemente entre o bordo esquerdo
e o direito, com o mesmo espaço nos dois bordos*/
.container {
    justify-content: space-around;
}
/* distribui os elementos uniformemente entre o bordo esquerdo
e o direito, com o mesmo espaço nos dois bordos e
entre cada elemento */
.container {
    justify-content: space-evenly;
}

align-items

A propriedade align-items define como os elementos ficam alinhados no eixo vertical (y) de um contentor flex. Há vários valores possíveis: flex-start, center, flex-end, baseline e stretch. O valor por omissão é stretch.

css
/* Alinhar todos os elementos em cima */
.container {
    align-items: flex-start;
}

/* Alinhar todos os elementos ao centro */
.container {
    align-items: center;
}

/* Alinhar todos os elementos em baixo */
.container {
    align-items: flex-end;
}

/*faz com que os elementos se ajustem à altura do seu conteúdo*/
.container {
    align-items: stretch;
}

align-content

A propriedade align-content é semelhante a align-items, mas atua sobre as linhas de um contentor flex com várias linhas. Aceita os mesmos valores que align-items, mais space-between, space-around e space-evenly para distribuir as linhas.

align-content: flex-start;

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12

align-content: center;

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12

align-content: flex-end;

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12

align-content: space-between;

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12

align-content: space-around;

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12

align-content: space-evenly;

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
css
/*alinha os elementos pelo bordo esquerdo*/
.container {
    justify-content: flex-start;
}
/*centra os elementos*/
.container {
    justify-content: center;
}
/*alinha os elementos pelo bordo direito*/
.container {
    justify-content: flex-end;
}
/*distribui os elementos uniformemente entre o
bordo esquerdo e o direito, sem espaço nos
bordos*/
.container {
    justify-content: space-between;
}
/*distribui os elementos uniformemente entre o bordo
esquerdo e o direito, com o mesmo espaço nos
dois bordos*/
.container {
    justify-content: space-around;
}
/* distribui os elementos uniformemente entre o bordo
esquerdo e o direito, com o mesmo espaço nos
dois bordos e entre cada elemento */
.container {
    justify-content: space-evenly;
}

order

A propriedade order define a ordem por que os elementos de um contentor flex aparecem. Recebe um número inteiro, sendo 0 o valor por omissão.

1
2
3
4
5
html
<div class="container">
    <div class="item first">1</div>
    <div class="item second">2</div>
    <div class="item third">3</div>
    <div class="item fourth">4</div>
    <div class="item fifth">5</div>
</div>
css
.container {
    display: flex;
}
/*coloca o elemento 1 em primeiro*/
.first {
    order: -1;
}
/*coloca o elemento 3 em segundo*/
.third {
    order: 2;
}
/*coloca o elemento 5 em último*/
.fifth {
    order: 3;
}

Com este código, a ordem de apresentação passa a ser: 1, 3, 2, 4, 5

Os elementos com um valor de ordem definido são ordenados por esse valor, os que não têm ficam com 0. Os que têm valores negativos aparecem antes dos que têm valores positivos.

Podes brincar com estes valores até chegares à apresentação que queres. Repara que a ordem por que as propriedades CSS aparecem no ficheiro não influencia a ordem de apresentação dos elementos: só order a controla.

flex-grow, flex-shrink e flex-basis

As propriedades flex-grow, flex-shrink e flex-basis definem o tamanho dos elementos de um contentor flex.

  • flex-grow define a fatia do espaço disponível que cada elemento ocupa.
  • flex-shrink define quanto um elemento encolhe para caber num contentor mais pequeno.
  • flex-basis define o tamanho de base de um elemento, antes de flex-grow e flex-shrink entrarem em jogo.

flex-grow: 1;

flex-grow: 1;
2
3
4
5

flex-shrink: 1;

shrink
grow
grow
grow
grow

flex-basis: 200px;

flex-basis: 200px;
2
3
4
5
css
/* faz com que o elemento ocupe
todo o espaço disponível */
.item {
    flex-grow: 1;
}

/* faz com que o elemento encolha
para se adaptar a um contentor mais pequeno */
.item {
    flex-shrink: 1;
}

/* define uma base de 200px para um elemento */
.item {
    flex-basis: 200px;
}

Podes combinar as três numa só com a propriedade flex

css
/* flex: flex-grow | flex-shrink | flex-basi */
.item {
    flex: 1 1 200px;
}

Exemplos

Exemplo 1: uma grelha em Flexbox

1
2
3
4
5
6
7
8
9
html
<div class="container-flex">
  <div class="item-flex item1">1</div>
  <div class="item-flex item2">2</div>
  <div class="item-flex item3">3</div>
  <div class="item-flex item4">4</div>
  <div class="item-flex item5">5</div>
  <div class="item-flex item6">6</div>
  <div class="item-flex item7">7</div>
  <div class="item-flex item8">8</div>
  <div class="item-flex item9">9</div>
</div>
css
.container-flex {
  display: flex;
  flex-wrap: wrap;
  /* permite que o elemento seja distribuído por
  várias linhas se não houver espaço suficiente */
  justify-content: space-between;
  /* permite distribuir os elementos uniformemente
  entre o bordo esquerdo e o direito, sem espaço
  nos bordos */
  align-content: space-between;
  /* permite distribuir as linhas uniformemente entre
  o topo e a base, sem espaço nos bordos */
}
.item-flex {
  text-align: center;
  flex: 1 0 calc(33.33% - 20px);
  /* usa flex-grow e flex-basis para distribuir os
  elementos numa grelha de 3 colunas, usando
  33.33% da largura disponível e
  reduzindo em 20px o espaço entre cada elemento */
}

Com a propriedade flex, defines como os elementos se adaptam ao espaço disponível no contentor flex. Neste exemplo usamos flex: 1 0 calc(33.33% - 20px); para distribuir os elementos numa grelha de 3 colunas, ocupando 33.33% da largura disponível e descontando 20px de espaço entre cada elemento. O resultado é uma grelha que se ajusta sozinha ao tamanho da janela.

Ao combinar justify-content, align-content e flex, montas disposições flexíveis e adaptáveis para o que o teu layout precisar. Estas propriedades cruzam-se de muitas maneiras diferentes, o que abre a porta a disposições únicas e feitas à medida. Experimenta as várias combinações até encontrares a que serve o teu projeto.

Exemplo 2: menu responsivo

html
<nav class="menu-container">
  <a href="#" class="menu-item">Home</a>
  <a href="#" class="menu-item">About</a>
  <a href="#" class="menu-item">Services</a>
  <a href="#" class="menu-item">Contact</a>
</nav>
css
.menu-container {
  display: flex; /* ativa a disposição flex */
  justify-content: space-between; /* alinha os itens do menu à direita e à esquerda */
  align-items: center; /* alinha verticalmente os itens do menu ao centro */
}

/* Acrescenta um botão de menu para os ecrãs pequenos */
.menu-container::before {
  content: "Menu"; /* Texto mostrado no botão */
  display: none; /* esconde o botão por omissão */
}

/* Quando a resolução do ecrã é inferior a 600px */
@media (max-width: 600px) {
  .menu-container {
    flex-wrap: wrap; /* Permite que os elementos passem para várias linhas */
    justify-content: center; /* Centra os elementos horizontalmente */
  }
  .menu-item {
    flex-basis: 100%; /* Ocupa toda a largura disponível */
    text-align: center; /* Centra o texto */
  }
  .menu-container::before {
    display: block; /* Mostra o botão de menu */
  }
}

Neste exemplo, o menu fica na horizontal, encostado à direita e à esquerda nos ecrãs mais largos (o comportamento por omissão). Nos ecrãs pequenos (com menos de 600px de largura), os elementos ficam centrados e passam para várias linhas, e aparece um botão «Menu» para abrir e fechar o menu com JavaScript ou a ferramenta que preferires. Se quiseres um exemplo mais detalhado de um menu com Flexbox, escrevi um artigo só sobre isso.

Conclusão

Com o Flexbox, montas sem esforço disposições flexíveis e adaptáveis para os teus elementos HTML. Com propriedades como display, justify-content, align-items e flex, alinhas e organizas os elementos de um contentor flex de forma eficaz.

O Flexbox brilha sobretudo nas grelhas de conteúdo, nos menus e nos formulários responsivos, porque distribui o espaço disponível conforme as necessidades do layout. Não é a solução para todos os problemas de disposição, mas resolve muito bem alguns dos mais comuns. Costuma andar a par de outras tecnologias de layout, como o Grid Layout, ou de frameworks como o Bootstrap.

Em resumo, o Flexbox é uma ferramenta poderosa para quem desenvolve para a web e precisa de layouts flexíveis e adaptáveis em sites e aplicações. Vale a pena perceber bem as propriedades e os usos de base para lhe tirar o máximo partido. E não te esqueças de verificar os limites de compatibilidade dos navegadores antes de o levares para os teus projetos.

Essa compatibilidade até pode ser automatizada na compilação: o PostCSS acrescenta os prefixos dos fabricantes a partir da lista de navegadores que escolheste. A configuração está detalhada no guia Webpack 5, incluindo a armadilha da query last 2 versions, que faz entrar o Internet Explorer e enche o CSS de prefixos mortos.

CSS

Damien Flandrin Programador web desde 2010, criador da Gekkode e do Email Impact. Cada artigo é testado num projeto real antes de ser publicado. Contacto
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.