Um padrão de design que pode ser complicado em design responsivo é uma barra lateral que fica alinhada com algum conteúdo. Onde há espaço de janela de visualização, esse padrão funciona muito bem, mas onde o espaço é condensado, esse layout rígido pode se tornar problemático.
O modelo de layout de caixa flexível (flexbox) é um modelo de layout projetado para conteúdo unidimensional. Ele se destaca em pegar vários itens de tamanhos diferentes e retornar o melhor layout para esses itens.
Este é o modelo de layout ideal para este padrão de barra lateral. O Flexbox não apenas ajuda a colocar a barra lateral e o conteúdo em linha, mas onde não há espaço suficiente restante, a barra lateral se quebra em uma nova linha. Em vez de definir dimensões rígidas para o navegador seguir, com o flexbox, você pode fornecer limites flexíveis para sugerir como o conteúdo pode ser exibido.
O que você pode fazer com um layout flexível?
Os layouts flexíveis possuem os seguintes recursos, que você poderá explorar neste guia.
- Eles podem ser exibidos como uma linha ou coluna.
- Eles respeitam o modo de escrita do documento.
- Eles são uma linha por padrão, mas podem ser solicitados a quebrar em várias linhas.
- Os itens no layout podem ser reordenados visualmente, longe de sua ordem no DOM.
- O espaço pode ser distribuído dentro dos itens, de forma que eles fiquem maiores e menores de acordo com o espaço disponível em seus pais.
- O espaço pode ser distribuído ao redor dos itens e linhas flexíveis em um layout encapsulado, usando as propriedades do Alinhamento de caixa.
- Os próprios itens podem ser alinhados no eixo transversal.
O eixo principal e o eixo transversal
A chave para entender o flexbox é entender o conceito de eixo principal e eixo transversal. O eixo principal é aquele definido por sua propriedade flex-direction
Se for row
seu eixo principal está ao longo da linha, se for column
seu eixo principal está ao longo da coluna.
Os itens flexíveis se movem como um grupo no eixo principal. Lembre-se: temos um monte de coisas e estamos tentando obter o melhor layout para eles como um grupo.
O eixo cruzado corre na direção oposta ao eixo principal, portanto, se flex-direction
for row
o eixo cruzado corre ao longo da coluna.
Você pode fazer duas coisas no eixo transversal. Você pode mover os itens individualmente ou como um grupo para que eles se alinhem uns com os outros e com o contêiner flexível. Além disso, se você encapsulou as linhas flexíveis, pode tratar essas linhas como um grupo para controlar como o espaço é atribuído a essas linhas. Você verá como tudo isso funciona na prática ao longo deste guia, por enquanto, apenas tenha em mente que o eixo principal segue sua flex-direction
.
Criação de um contêiner flexível
Vamos ver como o flexbox se comporta pegando um grupo de itens de diferentes tamanhos e usando o flexbox para distribuí-los.
<div class="container" id="container">
<div>One</div>
<div>Item two</div>
<div>The item we will refer to as three</div>
</div>
Para usar o flexbox, você precisa declarar que deseja usar um contexto de formatação flexível e não bloco regular e layout embutido. Faça isso alterando o valor da propriedade display
flex
.
.container {
display: flex;
}
Como você aprendeu no guia de layout, isso lhe dará uma caixa em nível de bloco, com filhos de itens flexíveis. Os itens flex imediatamente começam a exibir algum comportamento do flexbox, usando seus valores iniciais.
Os valores iniciais significam que:
- Os itens são exibidos como uma linha.
- Eles não se enrolam.
- Eles não crescem para encher o recipiente.
- Eles se alinham no início do contêiner.
Controlando a direção dos itens
Mesmo que você não tenha adicionado uma flex-direction
ainda, os itens são exibidos como uma linha porque o valor inicial de flex-direction
é row
. Se você quiser uma linha, não precisa adicionar a propriedade. Para alterar a direção, adicione a propriedade e um dos quatro valores:
row
: os itens são dispostos como uma fileira.row-reverse:
os itens são dispostos como uma linha a partir do final do contêiner flexível.column
: os itens são dispostos como uma coluna.column-reverse
: os itens são dispostos como uma coluna a partir do final do contêiner flexível.
Você pode experimentar todos os valores usando nosso grupo de itens na demonstração abaixo.
Reverter o fluxo de itens e acessibilidade
Você deve ter cuidado ao usar quaisquer propriedades que reordenem a exibição visual de como as coisas estão ordenadas no documento HTML, pois isso pode afetar negativamente a acessibilidade. Os column-reverse
row-reverse
coluna são um bom exemplo disso. O reordenamento só acontece para a ordem visual, não para a ordem lógica. É importante entender isso porque a ordem lógica é a ordem em que um leitor de tela lerá o conteúdo e qualquer pessoa que navegue usando o teclado a seguirá.
Você pode ver no vídeo a seguir como, em um layout de coluna invertido, a tabulação entre os links se desconecta, pois a navegação do teclado segue o DOM e não a exibição visual.
Qualquer coisa que possa alterar a ordem dos itens no flexbox ou na grade pode causar esse problema. Portanto, qualquer reordenamento deve incluir testes completos para verificar se isso não tornará o seu site difícil de usar para algumas pessoas.
Para mais informações, veja:
Modos e direção de escrita
Os itens flexíveis são dispostos como uma linha por padrão. Uma linha segue na direção em que as frases fluem em seu modo de escrita e na direção do script. Isso significa que se você estiver trabalhando em árabe, que tem uma direção de script da direita para a esquerda (rtl), os itens serão alinhados à direita. A ordem das tabulações também começa à direita, pois é assim que as frases são lidas em árabe.
Se você estiver trabalhando com um modo de escrita vertical, como algumas fontes japonesas, uma linha será exibida verticalmente, de cima para baixo. Tente mudar a flex-direction
neste demo que está usando um modo de escrita vertical.
Portanto, a maneira como os flex items se comportam por padrão está vinculada ao modo de escrita do documento. A maioria dos tutoriais é escrita em inglês ou outro modo de escrita horizontal, da esquerda para a direita. Isso tornaria mais fácil presumir que os itens flexíveis se alinham à esquerda e rodam horizontalmente.
Com o eixo principal e cruzado mais o modo de escrita a ser considerado, o fato de falarmos sobre início e fim em vez de topo, base, esquerda e direita no flexbox pode ser mais fácil de entender. Cada eixo tem um início e um fim. O início do eixo principal é conhecido como início principal. Portanto, nossos itens flexíveis inicialmente se alinham do main-start. O fim desse eixo é o fim principal. O início do eixo cruzado é um início cruzado e o final um final cruzado.
Envolvendo itens flexíveis
O valor inicial da propriedade flex-wrap
nowrap
. Isso significa que, se não houver espaço suficiente no contêiner, os itens transbordarão.
Os itens exibidos com os valores iniciais serão reduzidos o máximo possível, até o min-content
antes que ocorra o estouro.
Para fazer com que os itens embrulhem, adicione flex-wrap: wrap
ao contêiner flexível.
.container {
display: flex;
flex-wrap: wrap;
}
Quando um contêiner flexível é enrolado, ele cria várias linhas flexíveis. Em termos de distribuição de espaço, cada linha atua como um novo contêiner flexível. Portanto, se você estiver agrupando linhas, não é possível fazer com que algo na linha 2 se alinhe com algo acima dela na linha 1. Isso é o que significa que o flexbox é unidimensional. Você pode controlar o alinhamento em um eixo, uma linha ou uma coluna, não os dois juntos como podemos fazer na grade.
A abreviação do flex-flow
Você pode definir as propriedades flex-direction
e flex-wrap
usando a abreviação flex-flow
. Por exemplo, para definir flex-direction
para column
e permitir que os itens sejam agrupados:
.container {
display: flex;
flex-flow: column wrap;
}
Controlando o espaço dentro dos itens flexíveis
Supondo que nosso contêiner tenha mais espaço do que o necessário para exibir os itens, os itens se alinham no início e não crescem para preencher o espaço. Eles param de crescer em seu tamanho máximo de conteúdo. Isso ocorre porque o valor inicial das flex-
é:
flex-grow: 0
: os itens não crescem.flex-shrink: 1
: os itens podem encolher até menos do que suaflex-basis
.flex-basis: auto
: os itens têm um tamanho base deauto
.
Isso pode ser representado por um valor de palavra-chave flex:initial
. A flex
shorthand, ou as longhands de flex-grow
, flex-shrink
e flex-basis
são aplicadas aos filhos do contêiner flexível.
Para fazer com que os itens cresçam, enquanto permite que itens grandes tenham mais espaço do que os pequenos, use flex:auto
. Você pode tentar fazer isso usando a demonstração acima. Isso define as propriedades para:
flex-grow: 1
: os itens podem crescer mais do que suaflex-basis
.flex-shrink: 1
: os itens podem encolher até menos do que suaflex-basis
.flex-basis: auto
: os itens têm um tamanho base deauto
.
Usar flex: auto
significará que os itens terão tamanhos diferentes, já que o espaço que é compartilhado entre os itens é compartilhado depois que cada item é disposto como tamanho máximo do conteúdo. Portanto, um item grande ganhará mais espaço. Para forçar todos os itens a terem um tamanho consistente e ignorar o tamanho do conteúdo, altere flex:auto
para flex: 1
na demonstração.
Isso descompacta para:
flex-grow: 1
: os itens podem crescer mais do que suaflex-basis
.flex-shrink: 1
: os itens podem encolher até menos do que suaflex-basis
.flex-basis: 0
: os itens têm um tamanho base de0
.
Usando flex: 1
diz que todos os itens têm tamanho zero, portanto, todo o espaço no contêiner flexível está disponível para ser distribuído. Como todos os itens têm um fator de flex-grow
1
, todos eles crescem igualmente e o espaço é compartilhado igualmente.
Permitindo que os itens cresçam em taxas diferentes
Você não precisa dar a todos os itens um fator de flex-grow
1
. Você pode dar aos seus itens flexíveis diferentes fatores de flex-grow
. Na demonstração abaixo, o primeiro item tem flex: 1
, o segundo flex: 2
e o terceiro flex: 3
. Conforme esses itens crescem de 0
o espaço disponível no contêiner flexível é dividido em seis. Uma parte é dada ao primeiro item, duas partes ao segundo, três partes ao terceiro.
Você pode fazer a mesma coisa em uma flex-basis
de auto
, embora seja necessário especificar os três valores. O primeiro valor sendo flex-grow
, o segundo flex-shrink
e o terceiro flex-basis
.
.item1 {
flex: 1 1 auto;
}
.item2 {
flex: 2 1 auto;
}
Este é um caso de uso menos comum, pois a razão para usar uma flex-basis
do auto
é permitir que o navegador descubra a distribuição do espaço. Se você quiser que um item cresça um pouco mais do que o algoritmo decide, pode ser útil.
Reordenando itens flexíveis
Os itens em seu contêiner flexível podem ser reordenados usando a propriedade order
Esta propriedade permite a ordenação de itens em grupos ordinais. Os itens são dispostos na direção ditada pela flex-direction
, os valores mais baixos primeiro. Se mais de um item tiver o mesmo valor, ele será exibido com os outros itens com esse valor.
O exemplo abaixo demonstra essa ordem.
Check your understanding
Test your knowledge of flexbox
The default flex-direction
is
column
row
By default, a flex container wraps children.
A flex child item appears squished, which flex property helps mitigate this?
flex-shrink
flex-grow
flex-basis
Visão geral do alinhamento Flexbox
O Flexbox trouxe consigo um conjunto de propriedades para alinhar itens e distribuir espaço entre os itens. Essas propriedades foram tão úteis que, desde então, foram movidas para suas próprias especificações, você também as encontrará no Layout de grade. Aqui você pode descobrir como eles funcionam quando você está usando o flexbox.
O conjunto de propriedades pode ser colocado em dois grupos. Propriedades para distribuição espacial e propriedades para alinhamento. As propriedades que distribuem o espaço são:
justify-content
: distribuição do espaço no eixo principal.align-content
: distribuição de espaço no eixo transversal.place-content
: uma abreviação para definir as duas propriedades acima.
As propriedades usadas para alinhamento no flexbox:
align-self
: alinha um único item no eixo cruzadoalign-items
: alinha todos os itens como um grupo no eixo cruzado
Se você estiver trabalhando no eixo principal, as propriedades começam com justify-
. No eixo transversal, eles começam com align-
.
Distribuindo espaço no eixo principal
Com o HTML usado anteriormente, os itens flexíveis dispostos como uma linha, há espaço no eixo principal. Os itens não são grandes o suficiente para encher completamente o recipiente flexível. Os itens se alinham no início do contêiner flexível porque o valor inicial de justify-content
é flex-start
. Os itens se alinham no início e qualquer espaço extra fica no final.
Adicione a justify-content
ao contêiner flexível, atribua a ele um valor flex-end
e os itens se alinham no final do container e o espaço livre é colocado no início.
.container {
display: flex;
justify-content: flex-end;
}
Você também pode distribuir o espaço entre os itens com justify-content: space-between
.
Experimente alguns dos valores da demonstração e consulte o MDN para obter o conjunto completo de valores possíveis.
Com flex-direction: column
Se você alterou sua flex-direction
para column
, justify-content
funcionará na coluna. Para ter espaço livre em seu contêiner ao trabalhar como uma coluna, você precisa dar a ele uma height
ou block-size
. Caso contrário, você não terá espaço livre para distribuir.
Experimente os diferentes valores, desta vez com um layout de coluna flexbox.
Distribuindo espaço entre as linhas flexíveis
Com um contêiner flexível encapsulado, você pode ter espaço para distribuir no eixo transversal. Nesse caso, você pode usar a align-content
com os mesmos valores que justify-content
. Ao contrário de justify-content
que alinha itens para flex-start
por padrão, o valor inicial de align-content
é stretch
. Adicione a propriedade align-content
ao contêiner flexível para alterar esse comportamento padrão.
.container {
align-content: center;
}
Experimente na demonstração. O exemplo tem linhas quebradas de itens flexíveis e o contêiner tem um block-size
para que tenhamos algum espaço livre.
A abreviatura de place-content
Para definir justify-content
e align-content
você pode usar place-content
com um ou dois valores. Um único valor será usado para ambos os eixos, se você especificar que o primeiro é usado para align-content
e o segundo para justify-content
.
.container {
place-content: space-between;
/* sets both to space-between */
}
.container {
place-content: center flex-end;
/* wrapped lines on the cross axis are centered,
on the main axis items are aligned to the end of the flex container */
}
Alinhando itens no eixo cruzado
No eixo cruzado, você também pode alinhar seus itens dentro da linha flexível usando align-items
e align-self
. O espaço disponível para este alinhamento dependerá da altura do contêiner flexível, ou linha flexível no caso de um conjunto de itens envolvidos.
O valor inicial de align-self
é stretch
, que é o motivo pelo qual os itens flexíveis em uma linha se estendem até a altura do item mais alto por padrão. Para mudar isso, adicione a align-self
a qualquer um dos seus itens flex.
.container {
display: flex;
}
.item1 {
align-self: flex-start;
}
Use qualquer um dos seguintes valores para alinhar o item:
flex-start
flex-end
center
stretch
baseline
Veja a lista completa de valores no MDN.
A próxima demonstração tem uma única linha de flex items com flex-direction: row
. O último item define a altura do contêiner flexível. O primeiro item possui a align-self
com um valor de flex-start
. Tente alterar o valor dessa propriedade para ver como ela se move dentro do seu espaço no eixo cruzado.
A align-self
é aplicada a itens individuais. A align-items
pode ser aplicada ao contêiner flexível para definir todas as propriedades individuais do align-self
como um grupo.
.container {
display: flex;
align-items: flex-start;
}
Na próxima demonstração, tente alterar o valor de align-items
para alinhar todos os itens no eixo cruzado como um grupo.
Por que não há justify-self no flexbox?
Os itens flexíveis atuam como um grupo no eixo principal. Portanto, não existe o conceito de separar um item individual desse grupo.
No layout de grade, as propriedades justify-self
e justify-items
funcionam no eixo em linha para fazer o alinhamento dos itens naquele eixo dentro de sua área de grade. Devido à maneira como os layouts flexíveis tratam os itens como um grupo, essas propriedades não são implementadas em um contexto flexível.
Vale a pena saber que o flexbox funciona muito bem com margens automáticas. Se você encontrar a necessidade de separar um item de um grupo, ou separar o grupo em dois grupos, pode aplicar uma margem para fazer isso. No exemplo abaixo, o último item tem uma margem esquerda auto
. A margem automática absorve todo o espaço na direção em que é aplicada. Isso significa que ele empurra o item para a direita, dividindo os grupos.
Como centralizar um item vertical e horizontalmente
As propriedades de alinhamento podem ser usadas para centralizar um item dentro de outra caixa. A justify-content
alinha o item no eixo principal, que é a linha. A align-items
no eixo cruzado.
.container {
width: 400px;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
}
Check your understanding
Test your knowledge of flexbox
.container { display: flex; direction: ltr; }
To vertically align with flexbox, use
.container { display: flex; direction: ltr; }
To horizonally align with flexbox, use
.container { display: flex; direction: ltr; }
By default, flex items are aligned to stretch
. If you want content
size used for child items, which of the following styles would you use?
align-items: flex-start
align-content: start
justify-content: flex-start
height: auto
Recursos
- Layout de caixa flexível CSS do MDN inclui uma série de guias detalhados com exemplos.
- Guia de dicas de CSS para Flexbox
- O que acontece quando você cria um contêiner Flexbox Flex
- Tudo o que você precisa saber sobre alinhamento no Flexbox
- Qual é o tamanho dessa caixa flexível?
- Casos de uso para Flexbox