Guia completo do Flexbox

Tutorial completo do CSS flexbox. Este guia completo explica tudo sobre o flexbox, concentrando-se em todas as propriedades possíveis para o elemento pai (contêiner flexível) e elementos filho (elementos flexíveis). Ele também inclui histórico, demonstrações, modelos e um gráfico de suporte ao navegador.

Antecedentes
O módulo Flexbox Layout (caixa flexível) ( recomendação do candidato do W3C de outubro de 2017) tem como objetivo fornecer uma maneira mais eficiente de colocar, alinhar e distribuir espaço entre os elementos em um contêiner, mesmo que seu tamanho seja desconhecido e / ou dinâmico (Flex significa "flexível") .

A idéia principal do layout flexível é dar ao contêiner a capacidade de alterar a largura / altura de seus elementos (e ordem) para preencher melhor o espaço disponível (principalmente para exibição em todos os tipos de dispositivos com qualquer tamanho de tela). O contêiner flex expande os elementos para preencher o espaço livre disponível ou os compacta para evitar o estouro.

Mais importante, o layout do flexbox é independente da direção, diferentemente dos layouts regulares (bloco na vertical e embutido na horizontal). Embora funcionem bem para páginas, eles não têm flexibilidade (sem trocadilhos :-)) para suportar aplicativos grandes ou complexos (especialmente quando se trata de alterar a orientação, redimensionar, esticar, compactar etc.).

Nota : O layout do Flexbox é mais adequado para componentes de aplicativos e layouts de pequena escala, enquanto o layout de grade é projetado para layouts de maior escala.

Noções básicas e terminologia
Como o flexbox é um módulo inteiro e não uma propriedade única, ele inclui muitos elementos com um conjunto de propriedades. Alguns deles são projetados para serem instalados em um contêiner (o elemento pai é chamado de "flex container"), enquanto outros são projetados para serem instalados em elementos filhos (os chamados "elementos flexíveis").

Se o layout "normal" for baseado nas direções de bloco e inline, o layout flexível será baseado nas "direções de fluxo flexível". Por favor, observe este desenho da especificação que explica a idéia básica de um layout flexível.



Os elementos serão localizados na direção do eixo principal ( eixo principal do início principal ao extremo principal ) ou na direção do eixo transversal ( eixo transversal do início transversal ao extremo transversal ).

  • eixo principal - o eixo principal do container flex é o eixo principal ao longo do qual os elementos flex estão localizados. Cuidado, esse eixo não é necessariamente horizontal; depende da propriedade flex-direction (veja abaixo).
  • início principal | fim principal - itens flexíveis são colocados no contêiner, começando com início principal e terminando com final principal.
  • tamanho principal - a largura ou altura do elemento flexível, dependendo do que está na dimensão principal. É determinado pelo tamanho principal dos elementos flexíveis, isto é, propriedade 'width' ou 'height', dependendo do que está na dimensão principal.
  • eixo transversal - o eixo perpendicular ao eixo principal, chamado eixo transversal. Sua direção depende da direção do eixo principal.
  • partida cruzada | ponto cruzado - as linhas flexíveis são preenchidas com elementos e colocadas no contêiner, começando do ponto cruzado do contêiner em direção ao ponto cruzado.
  • tamanho transversal - largura ou altura do elemento flexível. Dependendo da propriedade css da direção flexível, essa é a largura ou a altura do elemento. Esse é sempre o tamanho transversal dos itens flexíveis.


Propriedades para pai (contêiner flexível)




exibição


Define um contêiner flexível; embutido ou bloqueado, dependendo do valor definido. Permite contexto flexível para todos os descendentes de primeiro nível.

.container { display: flex; /* or inline-flex */ } 

Tenha em mente:

Observe que as colunas CSS não afetam o contêiner flex.

direção flexível



Define o eixo principal, determinando assim a direção dos itens flexíveis colocados no container flex. O Flexbox é (além da embalagem opcional) um conceito de layout unidirecional. Pense nos elementos flexíveis como layouts primários em linhas horizontais ou colunas verticais.

 .container { flex-direction: row | row-reverse | column | column-reverse; } 

  • linha (padrão): da esquerda para a direita em ltr ; direita para a esquerda em rtl
  • linha reversa direita para esquerda ltr ; esquerda para a direita em rtl
  • coluna : igual à linha, mas de cima para baixo
  • reverso da coluna : a mesma coisa, reverso da linha, mas de baixo para cima

flex-wrap



Por padrão, os itens flexíveis tentarão caber em uma linha. Você pode alterar isso e permitir que os itens pulem para uma nova linha, conforme necessário, usando esta propriedade.

 .container{ flex-wrap: nowrap | wrap | wrap-reverse; } 

  • nowrap (padrão): todos os itens flexíveis estarão na mesma linha
  • quebra : os itens flex envolvem várias linhas de cima para baixo.
  • quebra automática : os itens flex envolvem várias linhas de baixo para cima.

Veja demos visuais do comportamento do flex-wrap aqui .

fluxo flexível (aplica-se a: elemento pai do contêiner flex)


Este é um atalho para as propriedades de direção flexível e empacotamento flexível que juntas definem os eixos principal e transversal do contêiner flexível. O valor padrão é linha nowrap .

 flex-flow: <'flex-direction'> || <'flex-wrap'> 

justificar conteúdo




Esta propriedade determina o alinhamento ao longo do eixo principal. Ajuda a distribuir o restante do espaço livre adicional, sempre que todos os elementos flexíveis em uma linha são inflexíveis ou flexíveis, mas atingiram seu tamanho máximo. Ele também fornece algum controle sobre o alinhamento dos elementos quando eles excedem a linha.

 .container { justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe; } 

  • flex-start (padrão): os itens são deslocados para o início da direção de flex-direction.
  • flex-end : os itens são movidos para mais perto do final da direção flex.
  • start : os elementos são deslocados para o início da direção do modo de escrita .
  • fim : os elementos são deslocados no final da direção do modo de escrita .
  • esquerda : os elementos são deslocados para a borda esquerda do contêiner, se isso não faz sentido na direção da flexão , ele se comporta como o começo .
  • right : os elementos são deslocados para a borda direita do contêiner; se isso não faz sentido na direção da flexão , ele se comporta como o começo .
  • center : os elementos são centralizados ao longo da linha
  • espaço entre : os elementos são distribuídos uniformemente ao longo da linha; o primeiro elemento está no início da linha, o último elemento no final da linha
  • space-around : os elementos são distribuídos uniformemente ao longo da linha com o mesmo espaço ao seu redor. Observe que visualmente os espaços não são iguais, pois todos os elementos têm o mesmo espaço nos dois lados. O primeiro elemento terá uma unidade de espaço oposta à borda do contêiner, mas duas unidades de espaço entre o próximo elemento, porque o próximo elemento tem seu próprio espaçamento, o que se aplica.
  • uniformemente no espaço : os elementos são distribuídos para que a distância entre dois elementos (e a distância das bordas) seja a mesma.

Observe que o suporte do navegador para esses valores tem suas próprias nuances. Por exemplo, o espaço intermediário nunca recebeu suporte do Edge e o início / fim / esquerda / direita ainda não está no Chrome. MDN possui gráficos detalhados . Os valores mais seguros são flex-start , flex-end e center .

Também há duas palavras-chave adicionais que você pode associar a esses valores: seguro e não seguro . O uso do safe garante que, independentemente de como você se envolva nesse tipo de posicionamento, não será possível posicionar o elemento para que ele seja exibido fora da tela (por exemplo, de cima), para que o conteúdo também não possa ser rolado (isso é chamado de "perda de dados") .

alinhar itens




Essa propriedade determina o comportamento padrão de como os itens flexíveis são posicionados ao longo do eixo transversal na linha atual. Pense nisso como uma versão com conteúdo justificado para o eixo transversal (perpendicular ao eixo principal).

 .container { align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe; } 


  • esticar (padrão): esticar para encher o contêiner (a largura mínima / largura máxima ainda é respeitada)
  • flex-start / start / self-start : os elementos são colocados no início do eixo transversal. A diferença entre eles é pequena e consiste em observar regras de direção flexível ou regras de modo de escrita .
  • flex-end / end / self-end : os elementos são posicionados no final do eixo transversal. A diferença é novamente sutil e está em conformidade com as regras de direção flexível ou modo de gravação .
  • centro : os elementos são centralizados no eixo transversal
  • linha de base : os elementos são alinhados de acordo com sua linha de base

palavras-chave modificadoras seguras e não seguras podem ser usadas em combinação com todas essas palavras-chave ( embora isso não seja suportado por todos os navegadores ), isso ajuda a impedir o alinhamento dos elementos para que o conteúdo fique inacessível.

align-content




Essa propriedade alinha as linhas no contêiner flexível quando houver espaço adicional no eixo transversal, assim como o conteúdo justificado alinha os elementos individuais no eixo principal.

Nota : esta propriedade não se aplica quando há apenas uma linha de itens flexíveis.

 .container { align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe; } 

  • flex-start / start : os itens mudaram para o início do contêiner. O flex-start mais suportado usa a direção flexível enquanto o start usa a direção do modo de gravação .
  • flex-end / end : itens deslocados para o final do contêiner. O flex-end mais suportado usa a direção flexível , enquanto o end usa a direção do modo de gravação .
  • center : os itens estão centralizados no contêiner
  • espaço entre : os elementos são distribuídos uniformemente; a primeira linha está no início do contêiner e a última no final
  • space-around : os elementos são distribuídos igualmente com espaço igual em cada linha
  • espaço uniformemente : os elementos são distribuídos uniformemente, o mesmo espaço ao seu redor
  • esticar (padrão): as linhas são esticadas para ocupar o espaço restante

palavras-chave modificadoras seguras e não seguras podem ser usadas em combinação com todas essas palavras-chave (embora isso não seja suportado por todos os navegadores), isso ajuda a impedir o alinhamento dos elementos para que o conteúdo fique inacessível.

Propriedades para os primeiros elementos filhos (elementos flexíveis)




ordem




Por padrão, os itens flexíveis estão na ordem original. No entanto, a propriedade order controla a ordem em que aparecem no contêiner flex.

 .item { order: <integer>; /* default is 0 */ } 

crescimento flexível




Essa propriedade determina a capacidade do elemento flex se esticar, se necessário. Ele assume um valor de zero, que serve como uma proporção. Essa propriedade é a quantidade de espaço que um elemento deve ocupar dentro de um contêiner flexível.

Se todos os elementos de crescimento flexível estiverem definidos como 1, o espaço restante no contêiner será distribuído igualmente entre todos os elementos filhos. Se um dos filhos tiver o valor 2, esse elemento ocupará o dobro do espaço que o restante (ou tente pelo menos).

 .item { flex-grow: <number>; /* default 0 */ } 

Números negativos não são suportados.

encolhimento flexível


Essa propriedade determina a capacidade do membro flexível de contratar, se necessário.

 .item { flex-shrink: <number>; /* default 1 */ } 

Números negativos não são suportados.

base flexível


Esta propriedade determina o tamanho do elemento padrão antes de alocar o espaço restante. Pode ser um comprimento (por exemplo, 20%, 5rem etc.) ou uma palavra-chave. A palavra - chave automática significa "veja minha propriedade de largura ou altura". A palavra-chave content significa "tamanho com base no conteúdo do elemento" - essa palavra-chave ainda não é muito bem suportada, por isso é difícil verificar se ela usa conteúdo máximo, conteúdo mínimo ou conteúdo adequado .

 .item { flex-basis: <length> | auto; /* default auto */ } 

Se definido como 0 , o espaço extra ao redor do conteúdo não será levado em consideração. Se definido como automático , o espaço extra será alocado com base em seu valor de crescimento flexível .
Veja esta foto.


flex


Este é um atalho para o uso de flex-grow , flex-shrink e flex-base juntos. O segundo e terceiro parâmetros ( flex-shrink e flex-base ) são opcionais. Por padrão, é 0 1 automático .

 .item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] } 

É recomendável que você use essa propriedade abreviada em vez de definir propriedades individuais. Essa redução define razoavelmente outros significados.

alinhar-se




Esta propriedade permite substituir o alinhamento padrão (ou especificado usando itens de alinhamento ) para itens flex individuais.
Consulte a propriedade align-items para entender os valores disponíveis.

 .item { align-self: auto | flex-start | flex-end | center | baseline | stretch; } 

Observe que as propriedades de flutuação , limpeza e alinhamento vertical não afetam os elementos flexíveis.

Exemplos


Vamos começar com um exemplo muito simples que resolve um problema quase diário: centralização perfeita. A solução mais fácil para esta tarefa é usar o flexbox.

 .parent { display: flex; height: 300px; /*    */ } .child { width: 100px; /*    */ height: 100px; /*    */ margin: auto; /* ! */ } 

Isso ocorre porque a propriedade da margem de alinhamento vertical definida como automática no contêiner flexível absorve espaço adicional. Assim, definir a margem como automático tornará o objeto perfeitamente centralizado nos dois eixos.

Agora vamos usar mais algumas propriedades. Considere uma lista de 6 elementos, todos com tamanhos fixos, mas pode haver tamanhos automáticos. Queremos que eles sejam distribuídos uniformemente ao longo do eixo horizontal, para que, ao redimensionar o navegador, tudo seja bem dimensionado e sem consultas à mídia.

 .flex-container { /*    flex  */ display: flex; /*    flex-direction        * ,       : * flex-direction: row; * flex-wrap: wrap; */ flex-flow: row wrap; /*   ,     */ justify-content: space-around; } 

Feito. Tudo o resto é apenas estilo.



Se você alterar a resolução ou escala da tela, será assim:



Vamos tentar outra coisa. Imagine que temos elementos de navegação alinhados à direita na parte superior do site, mas queremos que eles sejam alinhados em largura em telas de tamanho médio e dispostos em uma coluna em dispositivos pequenos. É bem simples

 /*   */ .navigation { display: flex; flex-flow: row wrap; /*           */ justify-content: flex-end; } /*   */ @media all and (max-width: 800px) { .navigation { /*       ,       */ justify-content: space-around; } } /*   */ @media all and (max-width: 500px) { .navigation { /*         ,    */ flex-direction: column; } } 

Telas grandes

Telas intermediárias

Telas pequenas


Vamos tentar algo ainda melhor, jogando com a flexibilidade dos itens flex! Que tal um layout de página inteira de três colunas com cabeçalho e rodapé. E isso não depende da ordem inicial dos elementos.

 .wrapper { display: flex; flex-flow: row wrap; } /*  ,      100%,  flex-base */ .wrapper > * { flex: 1 100%; } /*         * 1. header * 2. article * 3. aside 1 * 4. aside 2 * 5. footer */ /*   */ @media all and (min-width: 600px) { /*          */ .aside { flex: 1 auto; } } /*   */ @media all and (min-width: 800px) { /*            ,      ,      */ .main { flex: 2 0px; } .aside-1 { order: 1; } .main { order: 2; } .aside-2 { order: 3; } .footer { order: 4; } } 

Telas grandes

Telas intermediárias

Telas pequenas


Prefixo para Flexbox
O Flexbox requer um prefixo para melhor suporte entre os navegadores. Ele não inclui apenas predefinições com um prefixo de fornecedor, mas possui nomes e valores de propriedades completamente diferentes. Isso se deve ao fato de as especificações do Flexbox terem mudado ao longo do tempo, existem versões "antigas", "interpoladoras" e "novas" .

Talvez a melhor maneira de lidar com isso seja escrever uma nova (e última) sintaxe e executar seu CSS através do Autoprefixer , que faz o fallback muito bem.

Além disso, aqui está o Sass @mixin para ajudar com alguns prefixos, o que também lhe dá uma idéia do que precisa ser feito:

 @mixin flexbox() { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; } @mixin flex($values) { -webkit-box-flex: $values; -moz-box-flex: $values; -webkit-flex: $values; -ms-flex: $values; flex: $values; } @mixin order($val) { -webkit-box-ordinal-group: $val; -moz-box-ordinal-group: $val; -ms-flex-order: $val; -webkit-order: $val; order: $val; } .wrapper { @include flexbox(); } .item { @include flex(1 200px); @include order(2); } 

Erros
Flexbox, é claro, não está isento de erros. A melhor coleção que eu já vi são os Flexbugs de Philip Walton e Greg Whitworth. Este é um repositório de código aberto para rastrear todos eles, por isso acho melhor referenciá-lo.

Suporte do navegador


Dividido pela "versão" do flexbox:

  • (novo) significa sintaxe recente da especificação (por exemplo, display: flex; )
  • (interpolador) significa uma sintaxe informal estranha desde 2011 (por exemplo, display: flexbox; )
  • (antigo) significa a sintaxe antiga desde 2009 (por exemplo, display: box; )



O Blackberry Browser 10+ suporta a nova sintaxe.

Para obter mais informações sobre como misturar sintaxes para obter melhor suporte ao navegador, consulte este artigo (truques de CSS) ou este artigo (DevOpera) .

Source: https://habr.com/ru/post/pt467049/


All Articles