Podcast do CSS - 010: Flexbox
Um padrão de design que pode ser complicado no design responsivo é uma barra lateral alinhada com algum conteúdo. Onde há espaço da janela de visualização, esse padrão funciona muito bem, mas quando o espaço é condensado, o layout rígido pode ser problemático.
O modelo de layout de caixa flexível (flexbox) é um modelo de layout projetado para conteúdo unidimensional. Ela é excelente em pegar vários itens com tamanhos diferentes e retornar o melhor layout para eles.
Esse é o modelo de layout ideal para esse padrão de barra lateral. O flexbox não só ajuda a posicionar a barra lateral e o conteúdo inline, mas quando não houver espaço suficiente, a barra lateral vai ser quebrada 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 têm os recursos a seguir, que você poderá explorar neste guia.
- Eles podem aparecer como uma linha ou coluna.
- Elas respeitam o modo de escrita do documento.
- Por padrão, eles são de uma única linha, mas podem ser solicitados para serem quebrados em várias linhas.
- Os itens no layout podem ser reordenados visualmente, fora da ordem no DOM.
- O espaço pode ser distribuído dentro dos itens, para que eles se tornem maiores e menores de acordo com o espaço disponível no pai.
- O espaço pode ser distribuído ao redor dos itens e das linhas flexíveis em um layout encapsulado, usando as propriedades de alinhamento de caixa.
- Os próprios itens podem ser alinhados no eixo cruzado.
Eixo principal e eixo cruzado
A chave para entender o flexbox é entender os conceitos de eixo principal e eixo cruzado.
O eixo principal é aquele definido pela propriedade flex-direction
.
Se for row
, o eixo principal estará ao longo da linha.
Se for column
, o eixo principal estará ao longo da coluna.
Os itens flexíveis se movem como um grupo no eixo principal. Lembre-se: temos várias coisas e estamos tentando obter o melhor layout para elas como grupo.
O eixo cruzado é executado na outra direção em relação ao eixo principal.
Se flex-direction
for row
, o eixo cruzado vai ao longo da coluna.
Você pode fazer duas coisas no eixo cruzado.
É possível mover os itens individualmente ou em grupo, para que eles se alinhem entre si e no contêiner
flexível. Além disso, se você tiver linhas flexíveis unidas, poderá tratar essas linhas como um grupo para controlar como o espaço é atribuído a essas linhas.
Você vai conferir como tudo isso funciona na prática ao longo deste guia.
Por enquanto, lembre-se de que o eixo principal segue a flex-direction
.
Como criar um contêiner flexível
Para ver como o flexbox se comporta, use um grupo de itens de tamanhos diferentes e use o flexbox para dispor os itens.
<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, é necessário declarar que você quer usar um contexto de formatação flexível, e não um layout
in-line e de bloco normal.
Para isso, altere o valor da propriedade display
para flex
.
.container {
display: flex;
}
Como você aprendeu no guia de layout, isso vai fornecer uma caixa no nível de bloco, com filhos de itens flexíveis. Os itens flexíveis começam a exibir imediatamente algum comportamento do flexbox, usando os valores iniciais.
Os valores iniciais significam que:
- Os itens são mostrados em uma linha.
- Eles não se unem.
- Elas não crescem para preencher o contêiner.
- Eles ficam alinhados no início do contêiner.
Como controlar a direção dos itens
Mesmo que você ainda não tenha adicionado uma propriedade flex-direction
,
os itens serão mostrados como uma linha, porque o valor inicial de flex-direction
é row
.
Se você quiser uma linha, não vai precisar adicionar a propriedade.
Para mudar a direção, adicione a propriedade e um dos quatro valores:
row
: os itens são dispostos como uma linha.row-reverse:
os itens são dispostos como uma linha do final do contêiner flexível.column
: os itens dispostos como uma coluna.column-reverse
: os itens são dispostos como uma coluna no final do contêiner flexível.
Teste todos os valores usando nosso grupo de itens na demonstração abaixo.
Reversão do fluxo de itens e da acessibilidade
Tenha cuidado ao usar propriedades que reordenam a exibição visual
fora da ordem no documento HTML,
porque isso pode afetar negativamente a acessibilidade.
Os valores row-reverse
e column-reverse
são um bom exemplo disso.
A reordenação acontece apenas para a ordem visual, não para a ordem lógica.
É importante entender isso, já que a ordem lógica é a ordem em que um leitor de tela vai ler
o conteúdo,
e qualquer pessoa que navegue usando o teclado vai seguir essa ordem.
Veja no vídeo a seguir como, em um layout de linha invertido, a guia entre links se desconecta à medida que a navegação pelo teclado segue o DOM, e não a exibição visual.
Qualquer coisa que possa mudar a ordem dos itens no flexbox ou na grade pode causar esse problema. Portanto, qualquer reordenação precisa incluir testes completos para verificar se não vai dificultar o uso do site para algumas pessoas.
Para mais informações, veja:
Modos e direção de escrita
Por padrão, os itens flexíveis são dispostos em uma linha. Uma linha é executada na direção que as frases fluem em seu modo de escrita e direção de 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 de tabulação também começa à direita, porque é assim que as frases são lidas em árabe.
Se você estiver trabalhando com um modo de escrita vertical,
como algumas famílias tipográficas japonesas, uma linha será executada verticalmente, de cima para baixo.
Tente mudar o flex-direction
nesta demonstração que está usando o modo de gravação vertical.
Portanto, o modo como os itens flexíveis se comportam por padrão está vinculado ao modo de escrita do documento. A maioria dos tutoriais é escrita em inglês ou em outro modo horizontal, da esquerda para a direita. Isso facilitaria presumir que os itens flexíveis se alinham à esquerda e são executados horizontalmente.
Considerando os eixos principal e transversal e o modo de escrita, o fato de falarmos sobre start e end em vez de cima, de baixo, da esquerda e da 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 é chamado de main-start. Então, nossos itens flexíveis inicialmente se alinham do main-start. O final desse eixo é main-end. O início do eixo cruzado é cross-start, e o final é cross-end.
Como unir 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 vão estourar.
Os itens exibidos usando os valores iniciais vão ser reduzidos o máximo possível,
até o tamanho de min-content
antes que ocorra o estouro.
Para fazer com que os itens sejam unidos, adicione flex-wrap: wrap
ao contêiner flexível.
.container {
display: flex;
flex-wrap: wrap;
}
Quando um contêiner flexível é encapsulado, 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 quebrando linhas, não será possível alinhar algo da linha 2 com algo acima dela na linha 1. Isso é o que significa o flexbox ser unidimensional. É possível controlar o alinhamento em um eixo, em uma linha ou em uma coluna, não em ambos juntos, como podemos fazer na grade.
A abreviação flexflow
É possível definir as propriedades flex-direction
e flex-wrap
usando a abreviação flex-flow
.
Por exemplo, para definir flex-direction
como column
e permitir que os itens sejam agrupados:
.container {
display: flex;
flex-flow: column wrap;
}
Como controlar o espaço dentro de itens flexíveis
Supondo que o contêiner tenha mais espaço do que o necessário para mostrar os itens,
eles ficam enfileirados no início e não crescem para preencher o espaço.
Eles param de crescer com o tamanho máximo de conteúdo.
Isso ocorre porque o valor inicial das propriedades flex-
é:
flex-grow: 0
: os itens não crescem.flex-shrink: 1
: os itens podem ser reduzidos para menos que seuflex-basis
.flex-basis: auto
: os itens têm um tamanho base deauto
.
Isso pode ser representado por um valor de palavra-chave de flex: initial
.
A propriedade abreviada flex
,
ou os longos de flex-grow
, flex-shrink
e flex-basis
, são aplicados aos filhos do
contêiner flexível.
Para fazer com que os itens cresçam,
ao permitir que itens grandes tenham mais espaço do que os pequenos, use flex:auto
.
Teste isso usando a demonstração acima.
Isso define as propriedades como:
flex-grow: 1
: os itens podem ultrapassar oflex-basis
.flex-shrink: 1
: os itens podem ser menores que oflex-basis
.flex-basis: auto
: os itens têm um tamanho base deauto
.
Usar flex: auto
significa que os itens têm tamanhos diferentes,
já que o espaço compartilhado entre os itens é compartilhado depois que cada item é definido como
tamanho máximo de conteúdo.
Portanto, um item grande vai ocupar mais espaço.
Para forçar todos os itens a ter um tamanho consistente e ignorar o tamanho do conteúdo, mude
flex:auto
para flex: 1
na demonstração.
Ele é descompactado para:
flex-grow: 1
: os itens podem ultrapassar oflex-basis
.flex-shrink: 1
: os itens podem ser menores que oflex-basis
.flex-basis: 0
: os itens têm um tamanho base de0
.
O uso de flex: 1
informa que todos os itens têm tamanho zero.
Portanto, todo o espaço no contêiner flexível está disponível para distribuição.
Como todos os itens têm um fator de flex-grow
de 1
, todos crescem igualmente e o espaço é compartilhado igualmente.
Permitir que os itens cresçam em taxas diferentes
Não é necessário atribuir a todos os itens um fator flex-grow
de 1
.
É possível atribuir diferentes fatores flex-grow
aos itens flexíveis.
Na demonstração abaixo, o primeiro item tem flex: 1
, o segundo flex: 2
e o terceiro flex: 3
.
À medida que esses itens crescem de 0
, o espaço disponível no contêiner flexível é compartilhado em seis.
Uma parte é dada ao primeiro item,
duas partes para o segundo e
três partes para o terceiro.
Você pode fazer o mesmo em um flex-basis
de auto
, embora precise especificar os três
valores.
O primeiro valor é flex-grow
, o segundo flex-shrink
e o terceiro flex-basis
.
.item1 {
flex: 1 1 auto;
}
.item2 {
flex: 2 1 auto;
}
Esse é um caso de uso menos comum, porque o motivo para usar um flex-basis
de auto
é para permitir que o navegador descubra a distribuição do espaço.
Se você quiser fazer com que um item cresça um pouco mais do que o algoritmo decide, de maneira
útil.
Como reordenar itens flexíveis
Os itens no contêiner flexível podem ser reordenados usando a propriedade order
.
Essa propriedade permite a ordenação de itens em grupos ordinais.
Os itens são dispostos na direção determinada por 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.
Teste seu conhecimento
Teste seus conhecimentos sobre flexbox
O flex-direction
padrão é
row
column
Por padrão, um contêiner flexível encapsula os filhos.
flex-wrap: wrap
com display: flex
para unir filhosUm item filho flexível aparece amassado. Qual propriedade flexível ajuda a minimizar esse problema?
flex-grow
flex-shrink
flex-basis
Visão geral do alinhamento do Flexbox
O Flexbox trouxe com ele um conjunto de propriedades para alinhar itens e distribuir espaço entre os itens. Essas propriedades eram tão úteis que desde então foram movidas para a própria especificação que você as encontrará no layout de grade também. Aqui você pode descobrir como eles funcionam quando você usa o flexbox.
O conjunto de propriedades pode ser dividido em dois grupos. Propriedades para distribuição do espaço e propriedades para alinhamento. As propriedades que distribuem o espaço são:
justify-content
: distribuição de espaço no eixo principal.align-content
: distribuição de espaço no eixo cruzado.place-content
: uma abreviação para definir as duas propriedades acima.
Propriedades usadas para alinhamento em flexbox:
align-self
: alinha um único item no eixo cruzado.align-items
: alinha todos os itens como um grupo no eixo cruzado.
Se você estiver trabalhando no eixo principal, as propriedades vão começar com justify-
.
No eixo cruzado, eles começam com align-
.
Distribuição de 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 preencher completamente o contêiner flexível.
Os itens ficam alinhados no início do contêiner flexível porque o valor inicial de justify-content
é flex-start
.
Os itens ficam alinhados no início, e qualquer espaço extra fica no final.
Adicione a propriedade justify-content
ao contêiner flexível, atribua a ele o valor de flex-end
e os itens se alinham no final do contêiner e o espaço extra é colocado no início.
.container {
display: flex;
justify-content: flex-end;
}
Também é possível distribuir o espaço entre os itens usando justify-content: space-between
.
Teste alguns dos valores na demonstração e consulte o MDN para ver o conjunto completo de valores possíveis.
Com flex-direction: column
Se você alterou flex-direction
para column
, justify-content
funcionará na coluna.
Para ter espaço livre no contêiner ao trabalhar como uma coluna, atribua a ele um height
ou block-size
.
Caso contrário, você não terá espaço livre para distribuir.
Teste os diferentes valores, desta vez com um layout de coluna flexbox.
Distribuir espaço entre as linhas flexíveis
Com um contêiner flexível encapsulado, pode haver espaço para distribuir no eixo cruzado.
Nesse caso, é possível usar a propriedade align-content
com os mesmos valores que justify-content
.
Ao contrário de justify-content
, que alinha os itens a flex-start
por padrão,
o valor inicial de align-content
é stretch
.
Adicione a propriedade align-content
ao contêiner flexível para mudar esse comportamento padrão.
.container {
align-content: center;
}
Teste isso na demonstração.
O exemplo tem linhas encapsuladas de itens flexíveis, e o contêiner tem um block-size
para que haja espaço livre.
A abreviação place-content
Para definir justify-content
e align-content
, use place-content
com um
ou dois valores.
Um único valor será usado para os dois eixos,
se você especificar que o primeiro seja 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 */
}
Alinhamento de itens no eixo cruzado
No eixo cruzado, também é possível alinhar seus itens dentro da linha flexível usando align-items
e align-self
.
O espaço disponível para esse alinhamento vai depender da altura do contêiner flexível
ou da linha flexível no caso de um conjunto de itens unidos.
O valor inicial de align-self
é stretch
.
É por isso que os itens flexíveis de uma linha se esticam até a altura do item mais alto por padrão.
Para mudar isso, adicione a propriedade align-self
a qualquer um dos itens flexíveis.
.container {
display: flex;
}
.item1 {
align-self: flex-start;
}
Use 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 itens flexíveis com flex-direction: row
.
O último item define a altura do contêiner flexível.
O primeiro item tem a propriedade align-self
com um valor de flex-start
.
Tente alterar o valor dessa propriedade para ver como ela se move dentro de seu espaço no eixo cruzado.
A propriedade align-self
é aplicada a itens individuais.
A propriedade align-items
pode ser aplicada ao contêiner flexível
para definir todas as propriedades align-self
individuais como um grupo.
.container {
display: flex;
align-items: flex-start;
}
Na próxima demonstração, tente mudar o valor de align-items
para alinhar todos os itens no eixo
cruzado como um grupo.
Por que não há uma justificativa no flexbox?
Itens flexíveis atuam como um grupo no eixo principal. Portanto, não há conceito de dividir um item individual nesse grupo.
No layout de grade, as propriedades justify-self
e justify-items
funcionam no eixo inline
para fazer o alinhamento de itens nesse eixo dentro da á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ê precisar separar um item de um grupo
ou separar o grupo em dois, aplique uma margem para fazer isso.
No exemplo abaixo, o último item tem uma margem esquerda de 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 propriedade justify-content
alinha o item ao eixo principal,
que é a linha. A propriedade align-items
no eixo cruzado.
.container {
width: 400px;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
}
Teste seu conhecimento
Teste seus conhecimentos sobre flexbox
.container { display: flex; direction: ltr; }
Para alinhar verticalmente com o flexbox, use
.container { display: flex; direction: ltr; }
Para alinhar horizontalmente com flexbox, use
.container { display: flex; direction: ltr; }
Por padrão, os itens flexíveis estão alinhados a stretch
. Se você quisesse que o tamanho
do conteúdo fosse usado em itens filhos, qual dos estilos a seguir você usaria?
justify-content: flex-start
align-content: start
content
alinha linhas flexíveis, não o alinhamento de itens filhos.height: auto
align-items: flex-start
Recursos
- O Layout de caixa flexível do CSS do MDN inclui uma série de guias detalhados com exemplos.
- Guia de dicas do CSS para o 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 do Flexbox
- Inspecionar e depurar layouts do CSS Flexbox no Chrome DevTools