Fundo
O Flexbox Layout
mó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-start
para main-end
) ou o eixo cruzado (de cross-start
para 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-direction
propriedade (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ôsterPropriedades 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 emltr
; direita para esquerda emrtl
row-reverse
: da direita para a esquerda emltr
; da esquerda para a direita emrtl
column
: mesmo que,row
mas de cima para baixocolumn-reverse
: mesmo que,row-reverse
mas 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 linhawrap
: 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-wrap
aqui.
flex-flow
Esta é uma abreviação para as propriedades flex-direction
e 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 dawriting-mode
direção.end
: os itens são embalados no final dawriting-mode
direçã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 oflex-direction
, então ele se comporta comostart
.right
: os itens são embalados na borda direita do contêiner, a menos que isso não faça sentido com oflex-direction
, então ele se comporta comoend
.center
: os itens são centralizados ao longo da linhaspace-between
: os itens são distribuídos uniformemente na linha; o primeiro item está na linha inicial, o último item na linha finalspace-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-between
nunca 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-end
e center
.
Existem também duas palavras-chave adicionais que você pode combinar com estes valores: safe
e unsafe
. O uso safe
garante 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-content
versã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 àsflex-direction
regras ou àswriting-mode
regras.flex-end
/end
/self-end
: os itens são colocados no final do eixo transversal. A diferença novamente é sutil e é sobre respeitarflex-direction
regras versuswriting-mode
regras.center
: os itens estão centrados no eixo cruzadobaseline
: os itens são alinhados como suas linhas de base alinham
As palavras-chave modificadoras safe
e unsafe
podem 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-content
alinha itens individuais no eixo principal.
Observação: esta propriedade só tem efeito em contêineres flexíveis multilinhas, onde flex-flow
é definido como wrap
ou 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-start
honra oflex-direction
enquantostart
honra awriting-mode
direção.flex-end
/end
: itens embalados até o final do contêiner. O (mais suporte)flex-end
homenageia oflex-direction
enquanto que o final homenageia awriting-mode
direção.center
: itens centralizados no contêinerspace-between
: itens distribuídos uniformemente; a primeira linha está no início do contêiner enquanto a última está no finalspace-around
: itens uniformemente distribuídos com espaço igual em cada linhaspace-evenly
: os itens são distribuídos uniformemente com espaço igual ao redor delesstretch
: as linhas se estendem para ocupar o espaço restante
As palavras-chave modificadoras safe
e unsafe
podem 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 order
propriedade 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-grow
definidos 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 auto
palavra-chave significa “olhe para minha propriedade de largura ou altura” (o que foi feito temporariamente pela main-size
palavra - chave até ser descontinuado). Os content
meios 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-content
e fit-content
fazer.
.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-grow
valor. Veja este gráfico.
flex
Esta é a abreviação de flex-grow,
flex-shrink
e flex-basis
combinado. O segundo e o terceiro parâmetros ( flex-shrink
e 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-items
explicação para entender os valores disponíveis.
.item ( align-self: auto | flex-start | flex-end | center | baseline | stretch; )
Note-se que float
, clear
e vertical-align
nã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 auto
em um flex container absorver espaço extra. Portanto, definir uma margem vertical de auto
deixará 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 @mixin
para 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.