O modo de layout "Caixa Flexível" ou "Flexbox" oferece uma alternativa aos Floats para definir a aparência geral de uma página web. Uma vez que floats só nos permite modificar o posicionamento horizontal das nossas caixas, flexbox nos dá um controle total sobre o alinhamento, direção, ordem e tamanho das nossas caixas.

Diagram: comparison of flexbox alignment, direction, order, and size properties

A web está passando por uma grande mudança, então uma pequena discussão sobre o status do mercado é necessário. Nos últimos anos, floats era a opção mais usada para desenvolver a aparência de uma página web complexa. Como resultado, esses layouts tinham bom suporte até menos em navegadores antigos, e os desenvolvedores tem usado para construir milhões de páginas web. Isso significa, que inevitavelmente você irá se deparar com floats em algum momento da sua carreira de desenvolvedor web (por isso que o capítulo anterior não foi um completo desperdício).

No entanto, floats tinham originalmente a intenção de serem utilizados nos layouts estilo revista que nós cobrimos na seção Conteúdos flutuantes. Apesar do que vimos no último capítulo, os tipos de layouts que você pode criar com floats são atualmente meio limitados. Até mesmo um simples layout com uma barra lateral é, tecnicamente falando, um pequeno hack. Flexbox foi inventado para acabar com essas limitações.

Nós finalmente alcançamos um ponto onde o suporte dos navegadores atingiu um massa crítica e os desenvolvedores podem começar a construir páginas web completas com flexbox. Nossa recomendação é de usar o flexbox para projetar suas páginas web tanto quanto for possível, reservando floats par quando você precisar do texto fluindo ao redor de uma caixa (ex. um layout estilo revista) ou quando você precisar de suporte nos navegadores antigos.

Diagram: CSS floats for text wrapping around a box versus flexbox for the rest of the page layout

Neste capítulo, nós vamos explorar todo o modelo de layout flexbox passo a passo. Você se sentirá confortável para construir virtualmente qualquer layout que um web designer poderia oferecer.

Configuração

O exemplo deste capítulo é relativamente simples, mas irá demonstrar de forma clara toda a importância das propriedades do flexbox. Nós vamos começar com algo que pareça como isso:

Web page with flexbox-based layout

Para começar, nós vamos precisar de um documento HTML vazio que não tenha nada além de um barra de menu. Crie um novo projeto no Atom chamado flexbox para registrar todos os arquivos de exemplos que iremos criar nesse capítulo. Depois, crie um arquivo flexbox.html e adicione o seguinte código a seguir:

<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='UTF-8'/>
    <title>Uma página web</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <div class='menu-container'>
      <div class='menu'>
        <div class='date'>Ago 14, 2016</div>
        <div class='signup'>Assinar</div>
        <div class='login'>Entrar</div>
      </div>
    </div>
  </body>
</html>

Agora, precisamos criar uma folha de estilo correspondente, styles.css. Isso não vai parecer muito, além de uma barra de menu espandida com uma caixa com borda branca. Perceba que nós estamos utilizando flexbox ao invés da nossa tradicional técnica do auto-margim para centralizar o menu.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  color: #fff;
  background-color: #5995DA;  /* Azul */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Para depurar */
  width: 900px;
}

E finalmente, baixe algumas imagens para utilizar na nossa página web de exemplo. Descompacte essas imagens dentro da pasta do projeto flexbox, mantendo a pasta pai images. Seu projeto deve estar parecendo como a imagem abaixo, antes de seguir:

Screenshot of project files

Visão geral da Flexbox

A Flexbox usa dois tipos de caixas que nunca vimos antes: contêineres flex e itens flex. O trabalho de um contêiner flex é agrupar um conjunto de itens flex juntos e definir como eles serão posicionados.

Diagram: flex container as a highlighted container wrapping grayed out elements versus flex items as highlighted boxes inside the container

Todo elemento HTML que é um filho direto de um contêiner flex é um "item". Itens flex podem ser manipulados individualmente, mas para a maior parte, é responsabilidade do contêiner determinar o layout. O objetivo principal dos itens flex são deixar seus conteiner saberem quantas coisas precisam ser posicionadas.

Assim como layouts baseados em floats, projetar páginas web complexas com a flexbox é sobre aninhamento de caixas. Você alinha um monte de itens flex dentro de um conteiner, e, por sua vez, esses itens podem ser utilizados como um conteiner flex para seus próprios itens. Enquanto você trabalha com esses exemplos nesse capítulo, lembre-se que o objetivo fundamental de projetar uma página não mudou: continuamos movendo um monte de caixas aninhadas de um lado para o outro.

Contêineres Flex

O primeiro passo para utilizar a flexbox é transformar um dos nossos elementos HTML em um conteiner flex. Faremos isso com a propriedade display, que já deve ser familiar do capítulo Modelo de Caixa CSS. Ao dar um valor de flex, nós estamos dizendo para o navegador que tudo na caixa deve ser renderizado com a flexbox ao invés do modelo de caixa padrão.

Adicione a seguinte linha de código a nossa regra .menu-container para transformar ele em um conteiner flex:

.menu-container {
  /* ... */
  display: flex;
}

Isso habilita o modo layout flexbox—sem isso, o navegador irá ignorar todas as propriedades da flexbox que estamos prestes a introduzir. Definir explicitamente um conteiner flex significa que você pode combinar a flexbox com outros modelos de layout (ex. floats e tudo que nós vamos aprender em Posicionamento Avançado).

Diagram: Mixing and matching flexbox layout with block boxes and floats

Ótimo! Nós já temos um conteiner flex com um item flex dentro dele. No entanto nossa página não tem nada de diferente, por que não dissemos ao conteiner como mostrar seus itens.

Alinhando um Item Flex

Depois que fizemos um conteiner flex, seu próximo trabalho é definir o alinhamento horizontal dos seus itens. É pra isso que a propriedade justify-content é usada. Nós podemos centralizar nosso .menu, assim:

.menu-container {
  /* ... */
  display: flex;
  justify-content: center;    /* Adicione isso */
}

Isso terá o mesmo efeito como quando adicionamos a declaração margin: 0 auto ao elemento .menu. Mas, note como fizemos isso adicionando uma propriedade ao elemento pai (do item flex) ao invés de fazer diretamente ao elemento que nós queremos centralizar (no caso o item flex). Manipular itens através dos seus conteineres, como fizemos agora, é um tema comum em flexbox, e é um pouco diferente de como estávamos fazendo com as caixas até o momento.

Diagram: flex-start (3 left-aligned boxes), center (3 center-aligned boxes), flex-end (3 right-aligned boxes)

Outros valores para justify-content podem ser vistos abaixo:

  • center
  • flex-start
  • flex-end
  • space-around
  • space-between

Tente mudar justify-content para flex-start e flex-end. Isso deve alinhar o menu a esquerda e direita da janela do navegador, respectivamente. Garanta que você mudou de volta para o center antes de continuar. As duas últimas opções são úteis somente quando temos múltiplos itens flex em um conteiner.

Distribuindo Múltiplos Itens Flex

“Grande coisa..”, você deve estar pensando: nós podemos fazer alinhamento à esquerda/direita com float e centralizar com o auto-margins. Verdade! A Flexbox não mostra seu real potencial até que nós tenhamos mais que um item em um container. A propriedade justify-content também permite que você distribua os itens igualmente em um conteiner.

Diagram: space-around (3 boxes with equal space between them and their container), space-between (3 boxes with spaces between them, but not between their container)

Mude nossa regra .menu para ficar como abaixo:

.menu {
  border: 1px solid #fff;
  width: 900px;
  display: flex;
  justify-content: space-around;
}

Isso vai transformar nosso .menu em um conteiner flex aninhado, e o valor space-around espalhará seus itens pelo espaço da largura. Você deve ver algo como isso:

Web page showing menu bar <li> elements laid out with space-between

O conteiner flex distribuirá automaticamente o espaço horizontal extra para cara lado de cada item. O valor space-between é similar, mas só adiciona esse espaço extra entre os itens. Isso é o que queremos para nossa página de exemplo, então vamos lá e adicione a linha justify-content:

justify-content: space-between;

É claro, você também pode usar center, flex-start, flex-end aqui se você quiser empurrar todos os itens de um lado para outro, mas vamos deixar assim com space-between.

Agrupando Itens Flex

Conteineres flex só sabem como posicionar os elemento que estão um nível abaixo (ex. seus elementos filhos). Eles não se importam nenhum pouco com o que tem dentro dos seus itens flex. Isso significa que agrupar itens flex é outra arma no nosso arsenal de criação de layout. Empacotar um monte de itens em um <div> extra resulta em um página diferente totalmente diferente.

Diagram: wrapping two flex items in a <div> to eliminate one of the flex items

Por exemplo, vamos dizer que você quer que ambos os links para Sign Up e Login fiquem no lado direito da página, como na imagem abaixo. Tudo que precisamos fazer é colocá-los em outro <div>:

<div class='menu'>
  <div class='date'>Ago 14, 2016</div>
  <div class='links'>
    <div class='signup'>Assinar</div>      <!-- Isto está aninhado agora -->
    <div class='login'>Entrar</div>         <!-- Isso também! -->
  </div>
</div>

Ao invés de ter três itens, nosso conteiner flex .menu agora tem somente dois (.date e .links). Sobre o comportamento existente do space-between, eles se ajustarão ao lado esquerdo e direito da página.

Web page showing two menu bar <li> items wrapped in a container <div>

Mas, agora nós precisamos ajustar o elemento .links por que ele está usando o modo de bloco padrão. A solução: mais conteineres flex aninhados! Adicione uma nova regra ao nosso arquivo styles.css que transformará o elemento .links em um conteiner flex:

.links {
  border: 1px solid #fff;  /* Para depurar */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

Isso colocará nossos links na direita onde queremos. Note que a margem continua funcionando como feito no Modelo de Caixa CSS. E, como um modelo de caixas normal, auto-margins tem um significado especial dentro da flexbox (no entanto vamos deixar isso para o final do capítulo).

Web page <li> elements laid out with nested flexbox containers

Não mais precisamos dessas bordas brancas, então você pode apagá-las se você quiser.

Alinhamento em Eixo Cruzado (Vertical)

Até agora, estivemos manipulando o alinhamento horizontal, mas conteineres flex também podem definir o alinhamento vertical para seus itens. Isso é algo que simplesmente não é possível com floats.

Diagram: justify-content (left and right), align-items (top and bottom)

Para explorar isso, vamos precisar adicionar um cabeçalho embaixo do nosso menu. Adicione a seguinte marcação ao nosso flexbox.html depois do elemento .menu-container:

<div class='header-container'>
  <div class='header'>
    <div class='subscribe'>Subscribe &#9662;</div>
    <div class='logo'><img src='images/awesome-logo.svg'/></div>
    <div class='social'><img src='images/social-icons.svg'/></div>
  </div>
</div>

Agora, adicione uma estilização básica para fazer o alinhamento com nosso elemento .menu:

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
}

Isso deve ser bem familiar; no entanto, o cenário é um pouco diferente do nosso menu. Uma vez que .header tem uma altura explícita, os itens podem ser posicionados verticalmente dentro dela. A especificação oficial chama isso de alinhamento de “eixo cruzado”‐cross-axis (já vamos ver por que daqui a pouco), mas para nosso propósito ele pode ser chamado de alinhamento “vertical”.

Web page showing heading and icons vertically centered in a header container via the align-items property

Alinhamento vertical é definido adicionando uma propriedade align-items em um conteiner flex. Vamos fazer nossa página de exemplo parecer como a imagem acima com a linha abaixo:

.header {
  /* ... */
  align-items: center;  /* Adicione isso */
}

As opções disponíveis para align-items são similares a justify-content:

  • center
  • flex-start   (top)
  • flex-end      (bottom)
  • stretch
  • baseline
Diagram: flex-start (boxes at top of container), center (boxes in center of container), flex-end (boxes at bottom of container, stretch (boxes filling height of container)

A maioria deles é bastante simples. A opção strech vale a pena brincar um pouco por que ela nos permite mostrar o fundo de cada elemento. Vamos dar uma olhada nela adicionando o seguinte código ao nosso styles.css:

.header {
  /* ... */
  align-items: stretch;    /* Mude isso */
}

.social,
.logo,
.subscribe {
  border: 1px solid #5995DA;
}

A caixa para cada item estende a altura total do conteiner flex, independente de quanto conteúdo ele contém. Um uso comum para esse comportamento é criar colunas com alturas iguais com uma conjunto variável de conteúdo em cada um—algo muito difícil de fazer com floats.

Tenha certeza de que apagou as mudanças acima e centralizar verticalmente nosso conteúdo dentro do .header antes de continuar.

Encapsulando Itens Flex

Flexbox é uma alternativa mais poderosa que grades baseadas em floats. Ela não somente renderiza os itens como uma grade—ela pode mudar seu alinhamento, direção, ordem e tamanho também. Para criar uma grade, precisamos usar a propriedade flex-wrap.

Diagram: no wrapping (boxes flowing outside of container), with wrapping (boxes wrapping to next line in container)

Adicione uma linha de fotos ao nosso flexbox.html para que tenhamos algo com que trabalhar. As fotos devem estar dentro de <body>, depois do elemento .header-container:

<div class='photo-grid-container'>
  <div class='photo-grid'>
    <div class='photo-grid-item first-item'>
      <img src='images/one.svg'/>
    </div>
    <div class='photo-grid-item'>
      <img src='images/two.svg'/>
    </div>
    <div class='photo-grid-item'>
      <img src='images/three.svg'/>
    </div>
  </div>
</div>

De novo, a CSS correspondente já deve ser familiar da seção anterior:

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: flex-start;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}

Isso deve funcionar como esperado, mas preste atenção no que acontece quando adicionamos mais itens do que cabem dentro do container flex. Insira umas duas fotos a mais no código .photo-grid:

<div class='photo-grid-item'>
  <img src='images/four.svg'/>
</div>
<div class='photo-grid-item last-item'>
  <img src='images/five.svg'/>
</div>

Por padrão, elas ultrapassam o limite da página:

Web page with messed up layout due to no flexbox wrapping

Se você estiver tentando construir um hero banner que deixa o usuário rolar horizontalmente através de um monte de fotos, esse deve ser o comportamento esperado, mas não é o que nós queremos agora. Adicionando a propriedade flex-wrap força os itens que não couberem naquela linha pularem para próxima:

.photo-grid {
  /* ... */
  flex-wrap: wrap;
}

Agora, nossos itens flex se comportam muito como caixas flutuantes, exceto que a flexbox nos dá muito mais controle sobre como os itens “extra” são alinhados na última linha através da propriedade justify-content. Por exemplo, a última linha está alinhada à esquerda. Tente centralizar modificando nossa regra .photo-grid, assim:

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;    /* Mude isso */
  flex-wrap: wrap;
}

Alcançar isso com em um layout baseado em floats> é extremamente complicado.

Web page showing grid created from correct flexbox wrapping

Direcionando Contêineres Flex

A “direção” indica se um conteiner irá renderizar seus itens horizontalmente ou verticalmente. Até agora, todos os conteineres que vimos tem utilizado o padrão de direção horizontal, o que significa que os itens são desenhados um após o outro na mesma linha antes de pular para a próxima coluna quando ficam sem espaço.

Diagram: row (3 horizontal boxes), column (3 vertical boxes)

Uma das coisas mais incríveis sobre a flexbox é sua habilidade de transformar linhas em colunas utilizando uma única linha de CSS. Tente adicionar a seguinte declaração flex-direction a nossa regra .photo-grid:

.photo-grid {
  /* ... */
  flex-direction: column;
}

Isso muda a direção do conteiner do valor padrão de linha. Ao invés de uma grade, nossa página agora tem uma simples coluna vertical:

Web page with grid turned into a vertical column of boxes

Um ponto importante de design responsivo é apresentar a mesma marcação HTML para ambos os usuários de dispositivos móveis quanto de desktop. Isso pode ser um problema, como muitos dos layouts móveis são uma simples coluna, enquanto a maioria dos layouts desktop empilham elementos horizontalmente. Você pode imaginar como será útil a propriedade flex-direction assim que começarmos a construir layouts responsivos.

Considerações sobre Alinhamento

Note que a coluna está abraçando o lado esquerdo do conteiner flex mesmo usando a declaração justify-content: center;. Quando você rotaciona a direção de um conteiner, também pode rotacionar a direção da propriedade justify-content. Ela agora se refere ao alinhamento vertical do conteiner—não ao seu alinhamento horizontal.

Diagram: axes flipped when flex-direction is equal to column

Para centralizar horizontalmente nossa coluna, precisamos definir uma propriedade align-items no nosso código .photo-grid:

.photo-grid {
  /* ... */
  flex-direction: column;
  align-items: center;      /* Adicione isso */
}

Ordenação do Conteiner Flex

Até agora, nós tínhamos uma correlação entre a ordem dos nossos elementos HTML e a forma como a caixa é renderizada em uma página web. Seja com floats como com as técnicas da flexbox nós vimos que até agora, a única forma de que podemos fazer que uma caixa apareça antes ou depois de outra é movendo ela através da HTML. Isso vai mudar.

Diagram: row (left to right), row-reverse (right to left), column (top to bottom), column-reverse (bottom to top)

A propriedade flex-direction também oferece um controle sobre a ordem com que os itens aparecem, através das propriedades row-reverse e column-reverse. Para ver isso em ação, vamos transformar nossa coluna de volta em uma grade, mas dessa vez vamos reverter a ordem de tudo:

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  flex-direction: row-reverse;  /* <--- Isso é muito maneiro!! */
  align-items: center;
}

Ambas as linhas agora estão renderizadas da direita para esquerda ao invés do contrário. Mas, note como isso só muda a ordem em uma linha: a primeira linha não começa em 5, mas sim em 3. Esse é um comportamento útil para vários padrões de design comuns (o column-reverse particularmente nos dá várias opções quando usado em layouts para dispositivos móveis). Vamos aprender como ter mais granularidade no controle na próxima seção.

Web page with grid rows displayed backwards (3, 2, 1 in first row and 5, 4 in second row)

Reordenar elementos a partir de um folha de estilo é bastante coisa. Antes da flexbox, desenvolvedores web tinham que recorrer a hacks em JavaScript para alcançar esses tipos de coisas. No entanto, não abuse das suas novas habilidades. Como já discutimos nos primeiros capítulos desse tutorial, você deve sempre separar o conteúdo da apresentação. Mudar a ordem assim é puramente apresentação—seu HTML deve fazer sentido mesmo sem esses estilos aplicados a ele.

Ordenando de Item Flex

Esse capítulo inteiro foi sobre posicionamento de itens flex através dos seus conteineres pais, mas também é possível manipular itens individualmente. O resto desse capítulo vai mudar o foco dos conteineres flex para os itens que eles contém.

Diagram: setting the order of a flex item individual with the order property

Adicionando uma propriedade order em um item flex define sua ordem no conteiner sem afetar os itens ao redor dele. Seu valor padrão é 0, e ao aumentar ou diminuir move o item para a direita ou para a esquerda, respectivamente.

Isso pode ser utilizado, por exemplo, para trocar a ordem dos elementos .first-item e .last-item na sua grade. Também devemos mudar o valor de row-reverse da seção anterior de volta para row pois irá fazer com que nossas edições se tornem um pouco mais fácil de ver:

.photo-grid {
  /* ... */
  flex-direction: row;  /* Atualize isso */
  align-items: center;
}

.first-item {
  order: 1;
}

.last-item {
  order: -1;
}

Diferentemente de row-reverse e column-reverse em um conteiner flex, order funciona além dos limites da linha/coluna. O trecho acima irá trocar nosso primeiro item com o último, mesmo que ele apareça em uma linha diferente.

Flex Item Alignment

Podemos fazer a mesma coisa com o alinhamento vertical. E se quiséssemos que aquela ligação Assinar e os ícones de media social fossem para a parte mais baixa do cabeçalho ao invés do centro? Alinhe-os individualmente! É assim que a propriedade align-self funciona. Adicionando isso a um item flex sobreescreve o valor de align-items do seu conteiner:

.social,
.subscribe {
  align-self: flex-end;
  margin-bottom: 20px;
}

Isso deve enviar eles para a parte mais baixa do .header. Note que as margens (preenchimento, também) funcionam como esperado.

Web page showing bottom-aligned icons via the align-self property

Você pode alinhar elementos de outras formas utilizando os mesmos valores assim como a propriedade align-items, listadas abaixo por conveniência.

  • center
  • flex-start   (top)
  • flex-end      (bottom)
  • stretch
  • baseline

Itens Flex

Todos os nossos exemplos giraram em todos de itens fixos ou com tamanhos de conteúdos fixos. Isso nos permitiu focar nos aspectos do posicionamento usando flexbox, mas também significa que nós temos ignorado literalmente a natureza de “caixa flexível”. Itens Flex são flexíveis: eles podem diminiur ou esticar para caber no tamanho dos seus conteineres.

A propriedade flex define a largura dos itens individualmente em um conteiner flex. Ou, mais precisamente, permite que ele tenham tamanhos flexíveis. Isso funciona como um peso que diz ao conteiner flex como distribuir o espaço extra de cada item. Por exemplo, um item com um valor flex de 2 vai aumentar duas vezes o seu tamanho do que itens com o valor padrão 1.

Diagram: no flex (3 square boxes), equal flex (3 rectangle boxes), unequal flex (2 smaller boxes, one stretched out box)

Primeiro nós precisamos de um rodapé, para experimentar isso. Cola isso depois do nosso elemento .photo-grid-container:

<div class='footer'>
  <div class='footer-item footer-one'></div>
  <div class='footer-item footer-two'></div>
  <div class='footer-item footer-three'></div>
</div>

E depois, algum CSS:

.footer {
  display: flex;
  justify-content: space-between;
}

.footer-item {
  border: 1px solid #fff;
  background-color: #D6E9FE;
  height: 200px;
  flex: 1;
}

Aquela linha flex: 1; vai dizer para o item para esticar até caber na largura do .footer. Uma vez que todos eles tem o mesmo peso, todos vão esticar igualmente:

Web page with three equal boxes that stretch to fill the footer

Aumentando o peso de um dos itens vai fazer ele aumentar mais rápido que os outros. Por exemplo, podemos fazer o terceiro item aumentar duas vezes mais rápido do que os outros dois com a seguinte regra:

.footer-three {
  flex: 2;
}

Compare isso com a propriedade justify-content, que distribui o espaço extra entre os itens. Isso é similar, mas agora estamos distribuindo aquele espaço dentro dos próprios itens. O resultado é um controle total sobre como os itens flex se posicionam dentro do seu próprio conteiner.

Itens com Largura Estáticas

Podemos até misturar caixas flexíveis com outra de largura fixa. flex: initial volta a propriedade width explicita do item. Isso permite combinar caixas estáticas com flexíveis de formas mais elaboradas.

Diagram: fixed-width box (flex: initial), flexible box (flex: 1)

Nós vamos fazer um rodapé que se comporta como o diagrama acima. O item central é flexível, mas os outros ao redor tem sempre o mesmo tamanho. Tudo que precisamos fazer é adicionar a seguinte linha a nossa folha de estilo:

.footer-one,
.footer-three {
  background-color: #5995DA;
  flex: initial;
  width: 300px;
}

Sem essa linha flex: initial;, a declaração de flex: 1; deve ser herdada da regra .footer-item fazendo com que a propriedade width seja ignorada. initial fixa isso, e assim temos um layout flexível que também contém itens com largura fixa. Quando redimensionamos a janela do navegador, você verá que somente a caixa do meio do rodapé será redimensionada.

Web page with two static-width boxes on either side of a flexible box stretching to fill the footer

Esse é um layout bem comum, e não só para rodapés. Atualmente muitas páginas web tem barras laterais com largura fixa (ou múltiplas barras) e um bloco de conteúdo flexível contendo o texto principal da página. Isso é basicamente uma versão maior do que acabamos de fazer com nosso rodapé.

Itens Flex e Auto-Margins

Margens automáticas auto-margins na flexbox são especiais. Elas podem ser utilizadas como uma alternativa a <div> extra quando precisamos alinhas um grupo de items para a esquerda/direita de um conteiner. Pense em auto-margins como um “divisor” para itens flex no mesmo conteiner.

Vamos dar uma olhada nivelando nossos itens no .menu para que ele fique como o seguinte:

<div class='menu-container'>
  <div class='menu'>
    <div class='date'>Aug 14, 2016</div>
    <div class='signup'>Sign Up</div>
    <div class='login'>Login</div>
  </div>
</div>

Ao atualizar a página ela deve fazer com que os itens se distribuam de forma igual no nosso menu, como fizemos no começo do capítulo. Podemos replicar o layout desejado colocando um auto-margin entre os itens que desejamos separar, assim:

.signup {
  margin-left: auto;
}

Auto-margin irá consumir todo o espaço extra em um conteiner flex, então ao invés de distribuir os itens igualmente, ela move o .signup e qualquer item seguinte (.login) para o lado direito do conteiner. Isso te dará exatamente o mesmo layout que tínhamos antes, mas sem aquela <div> extra aninhada para agrupa-los. É bom deixar sua HTML bonito.

Resumo

Flexbox nos dá um tonelada de novas e incríveis ferramentas para desenvolver o layout de uma página web. Compare essas técnicas com o que podíamos fazer com floats, e deve ficar bem claro que a flexbox é uma opção mais limpa para o desenvolver layouts modernos para páginas web:

  • Use display: flex; para criar um conteiner flex.
  • Use justify-content para definir o alinhamento horizontal dos itens.
  • Use align-items para definir o alinhamento vertical dos itens.
  • Use flex-direction se você precisar de colunas ao invés de linhas.
  • Use os valores de row-reverse ou column-reverse para mudar a ordem do item.
  • Use order para customizar a ordem de elementos individuais.
  • Use align-self para verticalmente alinhar itens individuais.
  • Use flex para criar caixas flexíveis que podem encolher ou aumentar.

Lembre-se que essas propriedades flexbox são somente uma linguagem que deixa você dizer ao navegador como organizar esse monte de elementos HTML. A parte difícil não é escrever o código HTML e CSS, é descobrir, conceitualmente (em um pedaço de papel), o comportamente de todas as caixas necessárias para criar um determinado layout.

Quando um desinger te entrega um mockup para implementar, sua primeira tarefa é desenhar um monte de caixas dentro uma das outras e determinar como elas supostamente devem ser organizadas, aumentar e diminuir para alcançar o design desejado. Uma vez que você tenha conseguido isso, deve ser bem fácil codificar usando as novas técnicas da flexbox.

O modo de layout da flexbox deve ser utilizado para suas páginas web, mas para algumas coisas elas não são boas, como gentilmente ajustar os posicionamentos dos elementos e previni-los de interagir com o resto da página. Depois de estudarmos essas técnicas de posicionamento avançados no próximo capítulo, você será um mestre na arte do posicionamento da HTML e CSS.