Flexbox

The CSS Podcast - 010: Flexbox

Um padrão de design que pode ser complicado no design responsivo é uma barra lateral que fica alinhada com algum conteúdo. Quando há espaço na janela de visualização, esse padrão funciona muito bem, mas, quando 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 é excelente para pegar vários itens de tamanhos diferentes e retornar o melhor layout para esses itens.

Esse é o modelo de layout ideal para esse padrão de barra lateral. O Flexbox não apenas ajuda a exibir a barra lateral e o conteúdo inline, mas, quando não há espaço suficiente, a barra lateral é dividida em uma nova linha. Em vez de definir dimensões rígidas para o navegador seguir, com flexbox, é possível fornecer limites flexíveis para indicar como o conteúdo pode ser exibido.

O que é possível fazer com um layout flexível?

Os layouts flexíveis têm os seguintes recursos, que você vai conhecer neste guia.

  • Eles podem ser mostrados como uma linha ou uma coluna.
  • Eles respeitam o modo de escrita do documento.
  • Elas são de linha única por padrão, mas podem ser solicitadas para serem exibidas em várias linhas.
  • Os itens do layout podem ser visualmente reordenados, de sua ordem no DOM.
  • O espaço pode ser distribuído dentro dos itens, para que eles fiquem maiores e menores de acordo com o espaço disponível no item pai.
  • O espaço pode ser distribuído ao redor dos itens e linhas flex em um layout unido, usando as propriedades de alinhamento de caixa.
  • Os 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 cruzado. O eixo principal é definido pela propriedade flex-direction. Se for row, o eixo principal está na linha. Se for column, o eixo principal está na coluna.

Três caixas uma ao lado da outra com uma seta apontando, apontando da esquerda para a direita. A seta é identificada como "Eixo principal"

Os itens flexíveis são movidos em grupo no eixo principal. Lembre-se: temos muitas coisas e estamos tentando encontrar o melhor layout para elas como um grupo.

O eixo cruzado é executado na direção oposta ao eixo principal. Portanto, se flex-direction for row, o eixo cruzado será executado ao longo da coluna.

Três caixas de alturas diferentes, lado a lado com uma seta, apontando da esquerda para a direita. A seta é identificada como "Eixo principal". Há outra seta apontando de cima para baixo. Esta é chamada de eixo cruzado

Você pode fazer duas coisas na direção transversal. É possível mover os itens individualmente ou em grupo para que eles fiquem alinhados entre si e com o corpo flexível contêiner do Docker. Além disso, se você uniu linhas flexíveis, você pode tratar essas linhas como um grupo para controlar como o espaço é atribuído a elas. Você vai entender como tudo isso funciona na prática ao longo deste guia. Por enquanto, lembre-se de que o eixo principal segue sua flex-direction.

Como criar um contêiner flexível

Vamos conferir como o flexbox se comporta ao selecionar itens de tamanhos diferentes e usar o flexbox para posicionar para tirá-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 flexbox, você precisa declarar que quer usar um contexto de formatação flexível e não regular em blocos e inline. Para isso, mude o valor da propriedade display para flex.

.container {
  display: flex;
}

Como você aprendeu no guia de layout, isso gera uma caixa no nível do bloco, com filhos de itens flexíveis. Os itens Flex imediatamente começam a exibir algum comportamento de flexbox, usando seus valores iniciais.

Os valores iniciais significam que:

  • Os itens são mostrados como uma linha.
  • Elas não são agrupadas.
  • Eles não crescem para preencher o contêiner.
  • Eles se alinham no início do contêiner.

Como controlar a direção dos itens

Mesmo que você ainda não tenha adicionado uma propriedade do flex-direction, os itens sã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 em uma linha.
  • row-reverse: os itens são dispostos como uma linha 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 no final do contêiner flexível.

É possível testar todos os valores usando nosso grupo de itens na demonstração abaixo.

Revertendo o fluxo de itens e acessibilidade

Você deve ter cuidado ao usar qualquer propriedade que reorganize a exibição visual de como as coisas são ordenadas no documento HTML, já que pode afetar negativamente a acessibilidade. Os valores row-reverse e column-reverse são um bom exemplo disso. A reordenação acontece apenas na ordem visual, não na lógica lógica. Isso é importante de entender, já que a ordem lógica é a ordem em que um leitor de tela vai ler em voz alta o conteúdo, e qualquer pessoa que use o teclado a acompanhará.

Veja no vídeo a seguir como, em um layout de linha invertida, a tabulação entre links fica desconectada à medida que a navegação pelo teclado segue o DOM e não o elemento visual exibição.

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 ela não dificulta o uso do site para algumas pessoas.

Para mais informações, acesse:

Modos de gravação e direção

Os itens flexíveis são dispostos como uma linha por padrão. Uma linha é executada na direção em que as frases fluem no 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 guias 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 alguns tipos de letra japoneses, uma linha será executada verticalmente, de cima para baixo. Tente mudar o flex-direction nesta demonstração que está usando o modo de escrita vertical.

Portanto, a forma como os itens flexíveis se comportam por padrão está vinculada ao modo de escrita do documento. A maioria dos tutoriais é escrita em inglês ou em outro modo de escrita horizontal da esquerda para a direita. Isso facilita presumir que os itens flexíveis estão alinhados à esquerda e executados na horizontal.

Considerando o eixo principal e transversal e o modo de escrita, Falamos de início e término em vez de acima, abaixo, à esquerda e à direita com 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 início principal. Assim, nossos itens flexíveis inicialmente se alinham desde o início principal. O fim desse eixo é main-end. O início do eixo cruzado é cross-start e o fim é cross-end.

Um diagrama rotulado dos termos acima

Unir itens flex

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 transbordar.

Um contêiner flexível com nove itens dentro dele, os itens foram encolhidos, de modo que uma palavra está em uma linha
mas não há espaço suficiente para mostrá-los lado a lado, então os itens flexíveis se estenderam para fora do
do contêiner.
Quando atingem o tamanho mínimo de conteúdo, os itens flexíveis começam a transbordar o contêiner

Os itens exibidos usando os valores iniciais serão reduzidos ao máximo possível, até o tamanho min-content antes do estouro.

Para fazer com que os itens sejam agrupados, adicione flex-wrap: wrap ao contêiner flexível.

.container {
  display: flex;
  flex-wrap: wrap;
}

Quando um contêiner flexível é envolvido, ele cria várias linhas flexíveis. Em termos de distribuição de espaço, cada linha funciona como um novo contêiner flexível. Portanto, se você estiver unindo linhas, não é possível fazer com que algo na linha 2 se alinhe com algo acima da linha 1. É isso que significa que o flexbox é unidimensional. É possível controlar o alinhamento em um eixo, uma linha ou uma coluna, mas não os dois juntos, como podemos fazer na grade.

A abreviação de fluxo flexível

É 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 nosso contêiner tenha mais espaço do que o necessário para exibir os itens, os itens são alinhados no início e não crescem para preencher o espaço. 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 diminuir para menos do que flex-basis.
  • flex-basis: auto: os itens têm um tamanho base de auto.

Isso pode ser representado por um valor de palavra-chave de flex: initial. A propriedade abreviada flex, ou os comandos 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 mesmo tempo, permite que itens grandes tenham mais espaço do que os pequenos usam flex:auto. Teste isso usando a demonstração acima. Isso define as propriedades como:

  • flex-grow: 1: os itens podem crescer mais do que o flex-basis.
  • flex-shrink: 1: os itens podem ser reduzidos para menos do que flex-basis.
  • flex-basis: auto: os itens têm um tamanho base de auto.

Usar flex: auto vai fazer com que os itens tenham tamanhos diferentes, porque o espaço compartilhado entre os itens é compartilhado depois que cada item é disposto como tamanho máximo do conteúdo. Assim, um item grande ganha mais espaço. Para forçar todos os itens a ter um tamanho consistente e ignorar o tamanho da mudança de conteúdo flex:auto para flex: 1 na demonstração.

Isso é descompactado para:

  • flex-grow: 1: os itens podem ultrapassar a flex-basis.
  • flex-shrink: 1: os itens podem encolher para um tamanho menor que o flex-basis.
  • flex-basis: 0: os itens têm um tamanho base de 0.

O uso de flex: 1 informa que todos os itens têm tamanho zero, Portanto, todo o espaço do contêiner flexível está disponível para distribuição. Como todos os itens têm um fator flex-grow de 1, eles crescem igualmente e o espaço é compartilhado igualmente.

Permitir que os itens cresçam em taxas diferentes

Não é necessário atribuir um fator flex-grow de 1 a todos os itens. Você pode 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 é dividido em seis. Uma parte é dada ao primeiro item, duas partes ao segundo e três partes ao terceiro.

Você pode fazer o mesmo para 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 de usar um flex-basis de auto é permitir que o navegador descubra a distribuição de espaço. Se você quiser fazer com que um item cresça um pouco mais do que o algoritmo decide, isso pode ser útil.

Como reordenar itens flexíveis

Os itens no contêiner flexível podem ser reordenados usando a propriedade order. Ela permite ordenar os itens em grupos ordinais. Os itens são dispostos na direção determinada por flex-direction, com os valores mais baixos em primeiro lugar. Se mais de um item tiver o mesmo valor, ele será mostrado com os outros itens com esse valor.

O exemplo abaixo demonstra essa ordem.

Teste seu conhecimento

Teste seus conhecimentos sobre o flexbox

O flex-direction padrão é

row
Por padrão, o flexbox ajusta os itens em uma linha, alinhando-os no início. Com o ajuste ativado, ele vai continuar criando linhas para as crianças navegarem.
column
Definir flex-direction como coluna é uma ótima maneira de empilhar elementos, mas não é o valor padrão.

Por padrão, um contêiner flex agrupa os filhos.

verdadeiro
O wrapper precisa estar ativado.
falso
Use flex-wrap: wrap com display: flex para agrupar filhos

Um item filho flexível aparece comprimido. Qual propriedade flexível ajuda a mitigar isso?

flex-grow
Essa propriedade descreve se os elementos podem crescer além de um tamanho básico, não como eles devem se comportar em uma base.
flex-shrink
Sim, essa propriedade descreve como lidar com o dimensionamento se a largura estiver abaixo da base.
flex-basis
Isso fornece o ponto de partida do dimensionamento, mas não como lidar com cenários de dimensionamento em que a largura fica abaixo da base, como em um cenário comprimido.

Visão geral do alinhamento do Flexbox

O Flexbox trouxe um conjunto de propriedades para alinhar itens e distribuir espaço entre eles. Essas propriedades foram tão úteis que foram movidas para a própria especificação. Você também vai encontrar essas propriedades no layout de grade. Aqui você pode descobrir como eles funcionam quando você usa o flexbox.

O conjunto de propriedades pode ser colocado em dois grupos. Propriedades para distribuição de 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 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 cruzado.
  • align-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, começam com align-.

Distribuição de espaço no eixo principal

Com o HTML usado anteriormente, os itens flexíveis são 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 são alinhados no início do contêiner flexível porque o valor inicial de justify-content é flex-start. Os itens aparecem no início e qualquer espaço extra fica no final.

Adicione a propriedade justify-content ao contêiner flexível, atribua um valor de flex-end, e os itens serão alinhados no final do contêiner, e o espaço extra será colocado no início.

.container {
  display: flex;
  justify-content: flex-end;
}

Também é possível distribuir o espaço entre os itens com justify-content: space-between.

Teste alguns dos valores na demonstração, e consulte a MDN para ver o conjunto completo de valores possíveis.

Com flex-direction: column

Se você mudou flex-direction para column, justify-content vai funcionar da coluna. Para ter espaço extra no contêiner ao trabalhar como uma coluna, você precisa atribuir um height ou block-size a ele. Caso contrário, você não terá espaço extra para distribuir.

Teste os valores diferentes, desta vez com um layout de coluna flexbox.

Como distribuir espaço entre linhas flex

Com um contêiner flexível envolvido, você pode ter espaço para distribuir no eixo cruzado. Nesse caso, é possível usar a propriedade align-content com os mesmos valores de 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 alterar esse comportamento padrão.

.container {
  align-content: center;
}

Confira na demonstração. O exemplo tem linhas de itens flexíveis, e o contêiner tem um block-size para que tenhamos algum espaço extra.

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 os dois, o primeiro será 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 */
}

Alinhar itens no eixo cruzado

No eixo cruzado, você também pode alinhar seus itens na linha flexível usando align-items e align-self. O espaço disponível para esse alinhamento depende da altura do contêiner flexível, ou linha flexível no caso de um conjunto de itens unidos.

O valor inicial de align-self é stretch, por isso os itens flexíveis em uma linha se estendem 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

Consulte 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 mudar o valor dessa propriedade para ver como ela se move no 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;
}

Nesta 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á justify-self no flexbox?

Os itens flexíveis atuam como um grupo no eixo principal. Portanto, não há o conceito de dividir um item individual fora desse grupo.

No layout de grade, as propriedades justify-self e justify-items funcionam no eixo inline para alinhar itens nesse eixo dentro da área da grade. Devido à forma 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 dividir um item de um grupo, ou separe o grupo em dois, aplique uma margem para 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 no 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 o flexbox

.container {
  display: flex;
  direction: ltr;
}

Para fazer o alinhamento vertical com o flexbox, use

alinhar palavras-chave
Legal
justificar palavras-chave
Desculpe
.container {
  display: flex;
  direction: ltr;
}

Para alinhar horizontalmente com o flexbox, use

alinhar palavras-chave
Desculpe
justificar palavras-chave
Legal
.container {
  display: flex;
  direction: ltr;
}

Por padrão, os itens flexíveis são alinhados a stretch. Se você quer conteúdo tamanho usado para itens secundários, qual dos seguintes estilos você usaria?

justify-content: flex-start
A propriedade "justify" é para alinhamento horizontal, não vertical.
align-content: start
content alinha linhas flexíveis, não o alinhamento de itens filhos.
height: auto
Isso não vai ter efeito.
align-items: flex-start
Sim, queremos alinhá-los verticalmente com o "topo" ou start, que remove o valor de alongamento padrão e usa a altura do conteúdo.

Recursos