Um guia completo para Flexbox - CSS-Tricks

Índice:

Anonim

Fundo

O Flexbox Layoutmódulo (caixa flexível) (uma recomendação candidata do W3C em outubro de 2017) visa fornecer uma maneira mais eficiente de dispor, alinhar e distribuir espaço entre os itens em um contêiner, mesmo quando seu tamanho é desconhecido e / ou dinâmico (assim palavra “flex”).

A ideia principal por trás do layout flexível é dar ao contêiner a capacidade de alterar a largura / altura (e ordem) de seus itens para melhor preencher o espaço disponível (principalmente para acomodar todos os tipos de dispositivos de exibição e tamanhos de tela). Um contêiner flexível expande os itens para preencher o espaço livre disponível ou os reduz para evitar o estouro.

Mais importante ainda, o layout do flexbox é independente de direção, em oposição aos layouts regulares (bloco que é baseado na vertical e inline que é baseado na horizontal). Embora funcionem bem para páginas, falta flexibilidade (sem trocadilhos) para suportar aplicativos grandes ou complexos (especialmente quando se trata de mudança de orientação, redimensionamento, alongamento, encolhimento etc.).

Nota: O layout Flexbox é mais apropriado para os componentes de um aplicativo e layouts de pequena escala, enquanto o layout de grade é destinado a layouts de escala maior.

Noções básicas e terminologia

Como o flexbox é um módulo inteiro e não uma única propriedade, ele envolve muitas coisas, incluindo todo o seu conjunto de propriedades. Alguns deles devem ser definidos no container (elemento pai, conhecido como “flex container”), enquanto os outros devem ser definidos nos filhos (chamados “flex items”).

Se o layout “regular” for baseado em direções de fluxo em bloco e em linha, o layout flexível será baseado em “direções de fluxo flex”. Por favor, dê uma olhada nesta figura da especificação, explicando a ideia principal por trás do layout flexível.

Os itens serão dispostos seguindo o main axis(de main-startpara main-end) ou o eixo cruzado (de cross-startpara cross-end).

  • eixo principal - o eixo principal de um contêiner flexível é o eixo principal ao longo do qual os itens flexíveis são dispostos. Cuidado, não é necessariamente horizontal; depende da flex-directionpropriedade (veja abaixo).
  • main-start | main-end - Os flex items são colocados dentro do contêiner começando do main-start e indo para o main-end.
  • tamanho principal - a largura ou altura de um item flexível, o que quer que esteja na dimensão principal, é o tamanho principal do item. A propriedade de tamanho principal do item flexível é a propriedade 'largura' ou 'altura', o que estiver na dimensão principal.
  • eixo transversal - O eixo perpendicular ao eixo principal é denominado eixo transversal. Sua direção depende da direção do eixo principal.
  • cross-start | ponta cruzada - as linhas flexíveis são preenchidas com itens e colocadas no contêiner, começando no lado cruzado do contêiner flexível e indo em direção ao lado da ponta cruzada.
  • tamanho cruzado - A largura ou altura de um item flexível, o que quer que esteja na dimensão cruzada, é o tamanho cruzado do item. A propriedade de tamanho cruzado é qualquer 'largura' ou 'altura' que esteja na dimensão cruzada.

Pegue o pôster!

Refere muito este guia? Afixe uma cópia na parede do escritório.

Comprar pôster

Propriedades para o pai
(flex container)

exibição

Isso define um flex container; inline ou bloco dependendo do valor fornecido. Ele permite um contexto flexível para todos os seus filhos diretos.

.container ( display: flex; /* or inline-flex */ )

Observe que as colunas CSS não têm efeito em um flex container.

direção flexível

Isso estabelece o eixo principal, definindo assim a direção em que os flex items são colocados no flex container. Flexbox é (além da embalagem opcional) um conceito de layout de direção única. Pense nos itens flexíveis principalmente em linhas horizontais ou colunas verticais.

.container ( flex-direction: row | row-reverse | column | column-reverse; )
  • row(padrão): da esquerda para a direita em ltr; direita para esquerda emrtl
  • row-reverse: da direita para a esquerda em ltr; da esquerda para a direita emrtl
  • column: mesmo que, rowmas de cima para baixo
  • column-reverse: mesmo que, row-reversemas de baixo para cima

envoltório flexível

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

.container ( flex-wrap: nowrap | wrap | wrap-reverse; )
  • nowrap (padrão): todos os itens flexíveis estarão em uma linha
  • wrap: os itens flexíveis serão quebrados em várias linhas, de cima para baixo.
  • wrap-reverse: os itens flexíveis serão agrupados em várias linhas de baixo para cima.

Existem algumas demos visuais flex-wrapaqui.

flex-flow

Esta é uma abreviação para as propriedades flex-directione flex-wrap, que juntas definem os eixos principal e cruzado do contêiner flexível. O valor padrão é row nowrap.

.container ( flex-flow: column wrap; )

justify-content

Isso define o alinhamento ao longo do eixo principal. Ajuda a distribuir o espaço livre extra restante quando todos os itens flexíveis em uma linha são inflexíveis ou são flexíveis, mas atingiram seu tamanho máximo. Ele também exerce algum controle sobre o alinhamento dos itens quando eles ultrapassam 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 empacotados no início da direção flexível.
  • flex-end: os itens são embalados no final da direção flexível.
  • start: os itens são embalados no início da writing-modedireção.
  • end: os itens são embalados no final da writing-modedireção.
  • left: os itens são embalados em direção à borda esquerda do contêiner, a menos que isso não faça sentido com o flex-direction, então ele se comporta como start.
  • right: os itens são embalados na borda direita do contêiner, a menos que isso não faça sentido com o flex-direction, então ele se comporta como end.
  • center: os itens são centralizados ao longo da linha
  • space-between: os itens são distribuídos uniformemente na linha; o primeiro item está na linha inicial, o último item na linha final
  • space-around: os itens são distribuídos uniformemente na linha com espaço igual ao redor deles. Observe que visualmente os espaços não são iguais, pois todos os itens têm espaço igual em ambos os lados. O primeiro item terá uma unidade de espaço contra a borda do contêiner, mas duas unidades de espaço entre o próximo item porque o próximo item tem seu próprio espaçamento que se aplica.
  • space-evenly: os itens são distribuídos de forma que o espaçamento entre quaisquer dois itens (e o espaço para as bordas) seja igual.

Observe que o suporte do navegador para esses valores é matizado. Por exemplo, space-betweennunca tive suporte de algumas versões do Edge, e start / end / left / right não estão no Chrome ainda. MDN possui gráficos detalhados. Os valores mais seguros são flex-start, flex-ende center.

Existem também duas palavras-chave adicionais que você pode combinar com estes valores: safee unsafe. O uso safegarante que, independentemente de como você faz esse tipo de posicionamento, você não pode empurrar um elemento para que ele fique fora da tela (por exemplo, fora do topo) de forma que o conteúdo também não possa ser rolado (chamado de “perda de dados”) .

alinhar-itens

Isso define o comportamento padrão de como os itens flexíveis são dispostos ao longo do eixo cruzado na linha atual. Pense nisso como a justify-contentversão 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; )
  • stretch (padrão): esticar para preencher o contêiner (ainda respeitar largura mínima / largura máxima)
  • flex-start/ start/ self-start: os itens são colocados no início do eixo transversal. A diferença entre eles é sutil e diz respeito ao respeito às flex-directionregras ou às writing-moderegras.
  • flex-end/ end/ self-end: os itens são colocados no final do eixo transversal. A diferença novamente é sutil e é sobre respeitar flex-directionregras versus writing-moderegras.
  • center: os itens estão centrados no eixo cruzado
  • baseline: os itens são alinhados como suas linhas de base alinham

As palavras-chave modificadoras safee unsafepodem ser usadas em conjunto com todas as outras palavras-chave (embora observe o suporte do navegador) e ajudam a evitar o alinhamento de elementos de forma que o conteúdo se torne inacessível.

align-content

Isso alinha as linhas de um contêiner flexível quando há espaço extra no eixo cruzado, semelhante a como justify-contentalinha itens individuais no eixo principal.

Observação: esta propriedade só tem efeito em contêineres flexíveis multilinhas, onde flex-flowé definido como wrapou wrap-reverse). Um recipiente flexível de linha única (ou seja, onde flex-flowé definido com seu valor padrão no-wrap) não refletirá align-content.

.container ( align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline +… safe | unsafe; )
  • normal (padrão): os itens são embalados em sua posição padrão como se nenhum valor tivesse sido definido.
  • flex-start/ start: itens embalados no início do contêiner. O (mais suportado) flex-starthonra o flex-directionenquanto starthonra a writing-modedireção.
  • flex-end/ end: itens embalados até o final do contêiner. O (mais suporte) flex-endhomenageia o flex-directionenquanto que o final homenageia a writing-modedireção.
  • center: itens centralizados no contêiner
  • space-between: itens distribuídos uniformemente; a primeira linha está no início do contêiner enquanto a última está no final
  • space-around: itens uniformemente distribuídos com espaço igual em cada linha
  • space-evenly: os itens são distribuídos uniformemente com espaço igual ao redor deles
  • stretch: as linhas se estendem para ocupar o espaço restante

As palavras-chave modificadoras safee unsafepodem ser usadas em conjunto com todas as outras palavras-chave (embora observe o suporte do navegador) e ajudam a evitar o alinhamento de elementos de forma que o conteúdo se torne inacessível.

Propriedades para os filhos
(itens flexíveis)

ordem

Por padrão, os itens flexíveis são dispostos na ordem de origem. No entanto, a orderpropriedade controla a ordem em que aparecem no flex container.

.item ( order: 5; /* default is 0 */ )

flex-grow

Isso define a capacidade de um item flexível crescer, se necessário. Aceita um valor sem unidade que serve de proporção. Ele determina a quantidade de espaço disponível dentro do flex container que o item deve ocupar.

Se todos os itens forem flex-growdefinidos como 1, o espaço restante no contêiner será distribuído igualmente para todos os filhos. Se um dos filhos tiver o valor 2, o espaço restante ocupará o dobro do espaço dos outros (ou tentará, pelo menos).

.item ( flex-grow: 4; /* default 0 */ )

Números negativos são inválidos.

flex-encolher

Isso define a capacidade de um item flexível encolher, se necessário.

.item ( flex-shrink: 3; /* default 1 */ )

Números negativos são inválidos.

base flexível

Isso define o tamanho padrão de um elemento antes que o espaço restante seja distribuído. Pode ser um comprimento (por exemplo, 20%, 5rem, etc.) ou uma palavra-chave. A autopalavra-chave significa “olhe para minha propriedade de largura ou altura” (o que foi feito temporariamente pela main-sizepalavra - chave até ser descontinuado). Os contentmeios de palavra-chave “tamanho-lo com base no conteúdo do item” - esta palavra-chave não é bem suportado ainda, por isso é difícil de teste e mais difícil de saber o que seus irmãos max-content, min-contente fit-contentfazer.

.item ( flex-basis: | auto; /* default auto */ )

Se definido como 0, o espaço extra ao redor do conteúdo não é fatorado. Se definido como auto, o espaço extra é distribuído com base em seu flex-growvalor. Veja este gráfico.

flex

Esta é a abreviação de flex-grow, flex-shrinke flex-basiscombinado. O segundo e o terceiro parâmetros ( flex-shrinke flex-basis) são opcionais. O padrão é 0 1 auto, mas se você definir um único valor numérico, é como 1 0.

.item ( flex: none | ( ? || ) )

Recomenda-se que você use esta propriedade abreviada em vez de definir as propriedades individuais. A abreviação define os outros valores de forma inteligente.

alinhar-se

Isso permite que o alinhamento padrão (ou aquele especificado por align-items) seja substituído por itens flexíveis individuais.

Por favor, veja a align-itemsexplicação para entender os valores disponíveis.

.item ( align-self: auto | flex-start | flex-end | center | baseline | stretch; )

Note-se que float, cleare vertical-alignnão têm efeito sobre um item de flex.

Exemplos

Vamos começar com um exemplo muito simples, resolvendo um problema quase diário: centralização perfeita. Não poderia ser mais simples se você usar o flexbox.

.parent ( display: flex; height: 300px; /* Or whatever */ ) .child ( width: 100px; /* Or whatever */ height: 100px; /* Or whatever */ margin: auto; /* Magic! */ )

Isso depende do fato de uma margem definida autoem um flex container absorver espaço extra. Portanto, definir uma margem vertical de autodeixará o item perfeitamente centralizado em ambos os eixos.

Agora vamos usar mais algumas propriedades. Considere uma lista de 6 itens, todos com dimensões fixas, mas podem ser dimensionados automaticamente. Queremos que eles sejam distribuídos uniformemente no eixo horizontal para que, quando redimensionar o navegador, tudo seja dimensionado de maneira adequada e sem consultas de mídia.

.flex-container ( /* We first create a flex layout context */ display: flex; /* Then we define the flow direction and if we allow the items to wrap * Remember this is the same as: * flex-direction: row; * flex-wrap: wrap; */ flex-flow: row wrap; /* Then we define how is distributed the remaining space */ justify-content: space-around; )

Feito. Todo o resto é apenas uma questão de estilo. Abaixo está uma caneta com este exemplo. Certifique-se de ir para CodePen e tente redimensionar suas janelas para ver o que acontece.

Vamos tentar outra coisa. Imagine que temos um elemento de navegação alinhado à direita no topo de nosso site, mas queremos que ele seja centralizado em telas de tamanho médio e com uma coluna em dispositivos pequenos. Bastante fácil.

/* Large */ .navigation ( display: flex; flex-flow: row wrap; /* This aligns items to the end line on main-axis */ justify-content: flex-end; ) /* Medium screens */ @media all and (max-width: 800px) ( .navigation ( /* When on medium sized screens, we center it by evenly distributing empty space around items */ justify-content: space-around; ) ) /* Small screens */ @media all and (max-width: 500px) ( .navigation ( /* On small screens, we are no longer using row direction but column */ flex-direction: column; ) )

Vamos tentar algo ainda melhor brincando com a flexibilidade dos flex items! Que tal um layout de 3 colunas para dispositivos móveis com cabeçalho e rodapé de largura total. E independente da ordem de origem.

.wrapper ( display: flex; flex-flow: row wrap; ) /* We tell all items to be 100% width, via flex-basis */ .wrapper> * ( flex: 1 100%; ) /* We rely on source order for mobile-first approach * in this case: * 1. header * 2. article * 3. aside 1 * 4. aside 2 * 5. footer */ /* Medium screens */ @media all and (min-width: 600px) ( /* We tell both sidebars to share a row */ .aside ( flex: 1 auto; ) ) /* Large screens */ @media all and (min-width: 800px) ( /* We invert order of first sidebar and main * And tell the main element to take twice as much width as the other two sidebars */ .main ( flex: 2 0px; ) .aside-1 ( order: 1; ) .main ( order: 2; ) .aside-2 ( order: 3; ) .footer ( order: 4; ) )

Prefixando Flexbox

O Flexbox requer alguns prefixos de fornecedor para oferecer suporte ao maior número possível de navegadores. Não inclui apenas propriedades anexas com o prefixo do fornecedor, mas na verdade existem nomes de propriedades e valores totalmente diferentes. Isso ocorre porque a especificação do Flexbox mudou ao longo do tempo, criando versões “antigas”, “tweener” e “novas”.

Talvez a melhor maneira de lidar com isso seja escrever na nova (e final) sintaxe e executar seu CSS por meio do Autoprefixer, que lida muito bem com os fallbacks.

Como alternativa, aqui está um Sass @mixinpara ajudar com alguns dos prefixos, que também dá uma ideia de que tipo de coisas precisam ser feitas:

@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); )

Propriedades Relacionadas

  • Um guia completo para grade
  • Entradas de Almanaque nas propriedades da grade, como grade-linha / grade-coluna

Outros recursos

  • Flexbox nas especificações CSS
  • Flexbox em MDN
  • Flexbox na Opera
  • Mergulhando no Flexbox da Bocoup
  • Misturando sintaxes para melhor suporte de navegador em CSS-Tricks
  • Flexbox de Raphael Goetter (FR)
  • Flexplorer por Bennett Feely

Insetos

O Flexbox certamente possui seus bugs. A melhor coleção deles que já vi é Flexbugs de Philip Walton e Greg Whitworth. É um local de código aberto para rastrear todos eles, então acho melhor apenas criar um link para ele.

Suporte para navegador

Dividido por “versão” do flexbox:

  • (novo) significa a sintaxe recente da especificação (por exemplo display: flex;)
  • (tweener) significa uma sintaxe não oficial estranha de 2011 (por exemplo display: flexbox;)
  • (antigo) significa a sintaxe antiga de 2009 (por exemplo display: box;)
cromada Safári Raposa de fogo Ópera IE Beira Android iOS
20- (antigo)
21+ (novo)
3.1+ (antigo)
6.1+ (novo)
2-21 (antigo)
22+ (novo)
12.1+ (novo) 10 (adolescente)
11+ (novo)
17+ (novo) 2.1+ (antigo)
4.4+ (novo)
3.2+ (antigo)
7.1+ (novo)

O navegador Blackberry 10+ suporta a nova sintaxe.