Deixe-me dizer isto primeiro: o flexbox é fácil. Seja por causa de problemas de adoção antecipada, ou porque aprendemos a pensar em termos de flutuações e bloqueios, muitas vezes ouço de designers da Web que eles acham que o Flexbox é complexo de implementar. Mas repito: o flexbox é fácil.
Há um truque para entender o flexbox, que eu vou te ensinar, depois disso tudo ficará claro. Mas primeiro quero falar sobre o que é flexbox.
Flexbox (ou o Módulo de Layout de Caixa Flexível para dar seu nome correto) é um conjunto de propriedades CSS que se combinam para distribuir conteúdo de maneira responsiva.
O Flexbox é a primeira técnica de layout CSS que funciona para a web moderna. É justo dizer que até o flexbox ser suportado, não havia uma técnica de layout que funcionasse bem com o design responsivo da web.
Muitos hacks andam por aí, como os elementos de configuração para exibir: inline-block e permitindo que eles envolvam. Mas isso apresentou uma série de problemas para locais flexíveis, não apenas a falta de controle e o efeito colateral do redimensionamento de elementos. Por esse motivo, muitos sites responsivos ainda usam JavaScript para posicionar o conteúdo.
O Flexbox é descrito pelo W3C como sendo destinado ao layout de elementos da interface do usuário - itens como itens de menu - não é destinado a páginas inteiras.
A razão pela qual não se destina ao layout de páginas inteiras, é que o flexbox tem um módulo CSS complementar, o Módulo de Layout de Grade que é destinado ao layout. O layout de grade é considerado a técnica mais apropriada para layouts de página inteira. Infelizmente, há um suporte muito limitado para a grade no momento atual, e por "limitado" quero dizer "nenhum". Mesmo a versão mais recente do Chrome não consegue suportá-lo sem sinalizadores.
Felizmente, o suporte ao navegador para o flexbox é muito mais abrangente. E porque resolve muitos problemas de layout modernos, o flexbox é uma ferramenta ideal até que a grade seja finalmente adotada.
O Flexbox é ideal para estilizar componentes em uma página. O poder real do flexbox, e o motivo pelo qual ele funciona muito melhor do que outras opções de layout, vem da declaração de estilos em grupos de itens, em vez de itens individuais.
Quando se trata de layout, raramente precisamos posicionar um único item - se estamos planejando fazer isso, é muito melhor usar o posicionamento. O Flexbox funciona melhor quando controla como grupos de elementos se relacionam entre si.
Sempre projete uma coisa considerando-a em seu próximo contexto maior - uma cadeira em uma sala, uma sala em uma casa, uma casa em um ambiente, um ambiente em um plano da cidade. - Eliel Saarinen
Assim, a especificação do flexbox é dividida em duas partes, um conjunto de propriedades que se referem ao elemento do contêiner e um conjunto de propriedades que se referem aos elementos internos.
O suporte ao navegador é, normalmente, uma questão complexa. Tornou-se ainda mais complexo para o flexbox porque o flexbox possui várias sintaxes diferentes. A indecisão inicial, o desenvolvimento independente por parte de alguns fornecedores de navegadores e um processo iterativo nos deixaram várias versões diferentes do flexbox que precisam ser atendidas.
Felizmente, com a adição de alguns prefixos de navegador para navegadores legados, agora podemos confiar nele. De acordo com caniuse.com dos atuais navegadores tradicionais, apenas o IE9 apresentará um problema para nós.
Felizmente, como todo o CSS, se o flexbox falhar, ele falhará silenciosamente. Significa que o IE9 irá simplesmente ignorá-lo.
Graças a uma desconcertante falta de cooperação entre vários ramos de comitês e corporações, a implementação do flexbox praticamente rivalizou com o caos do início dos anos 2000, quando cada navegador implementava cada propriedade única e incorretamente ao mesmo tempo. Dando a todos o benefício da dúvida, as três implementações do flexbox foram simplesmente uma abordagem iterativa que resultou na solução comum mais útil.
Existem três versões da sintaxe do flexbox que você precisa estar ciente: antigo, intermediário e novo. Navegadores diferentes suportam sintaxes diferentes, o IE10, por exemplo, suporta a sintaxe inbetween.
Assim como os prefixos de navegadores, escrevemos a sintaxe do Flexbox do mais antigo para o mais novo, para que a mais nova sintaxe com suporte substitua as sintaxes mais antigas.
Por exemplo, nós escrevemos display: flex da seguinte forma:
display:-webkit-box; /*old prefixed for webkit*/display:-moz-box; /*old prefixed for mozilla*/display:-ms-flexbox; /*inbetween prefixed for ie*/display:-webkit-flex; /*new prefixed for webkit*/display:flex; /*new*/
No interesse da clareza, eu não vou mergulhar nas sintaxes mais antigas, ou debater os méritos de pré-processadores, pós-processadores e scripts de conversão diferentes. Em todos os meus exemplos, vou usar a nova sintaxe correta.
Quando se trata de código de produção eu uso uma série de mixins Sass para estender o suporte ao flexbox para navegadores mais antigos.
Existe um excelente Sass mixin aqui , que você pode usar para evitar o inchaço do código ou extrair a sintaxe legada.
O segredo do flexbox é que não é uma caixa. Até agora, todo o layout na Web usava um sistema cartesiano de xey para traçar pontos. O Flexbox, por outro lado, é um vetor.
Parece ótimo, certo? O Flexbox é um vetor, o que significa que definimos um comprimento e definimos um ângulo. Nós podemos mudar o ângulo, sem afetar o comprimento; e podemos alterar o comprimento sem afetar o ângulo.
Esta nova abordagem significa que algumas das terminologias do flexbox são inicialmente complexas. Por exemplo, quando alinhamos itens ao topo de um contêiner flexível, usamos flex-start, não top - porque, se alterarmos a orientação, o flex-start ainda será aplicado, mas o top não.
Depois de entender essa abordagem, muito do flexbox é desmistificado.
A sintaxe do Flexbox é dividida em dois grupos: as propriedades que controlam o contêiner e as propriedades que controlam os descendentes diretos do contêiner. O primeiro é o mais útil, então vamos começar por aí.
Digamos que queremos espaçar itens dentro de um bloco. Nós queremos que eles sejam espaçados uniformemente. Usar o flexbox é muito fácil de fazer. A primeira coisa que precisamos é de uma marcação para testar isso:
Flexbox Layout
É um página HTML simples , com um div da casa , que contém cinco salas divs cada um dos quais tem uma classe que identifica sua função, cozinha, banheiro, lounge e quarto.
O que vamos fazer é definir a casa como um contêiner de flexbox. Qualquer propriedade de flexbox que colocamos em casa será então aplicada a seus filhos (a sala s).
Para fazer o layout da sala , primeiro precisamos declarar a casa como um contêiner de flexbox e, em seguida, informar como queremos que os elementos filhos sejam organizados.
Para declarar a casa como um contêiner flexbox, usamos o seguinte código:
.house {background:#FF5651;display:flex;}
E é isso. Nós criamos uma caixa flexível. Tudo o que precisamos fazer agora é dizer ao flexbox como fazer o layout da sala . Podemos fazer isso usando a propriedade justify-content .
justify-content tem cinco valores possíveis: center, flex-start, flex-end, espaço-around e espaço-entre. Estes centralizam os itens, os alinham ao início (que é superior ou esquerdo, como discutiremos a seguir), ao final (que é o inferior ou o direito), os divide com espaço igual em torno de cada item ou com espaço igual entre cada item, respectivamente.
Nós vamos usar o espaço ao redor:
.house {background:#FF5651;display:flex;justify-content: space-around;}
Aqui está uma demonstração . Observe como há o dobro do espaço entre os itens como há nas duas bordas externas? Isso porque cada item tem o mesmo espaço à esquerda e à direita. Se tivéssemos usado espaço entre eles, não haveria espaço nas bordas.
Eu não tenho certeza sobre você, mas o banheiro na minha casa é um pouco menor do que o salão, e apesar de eu ter uma pequena cozinha, eu adoraria uma muito maior. Então, vamos fazer algumas adições ao nosso código para refletir isso:
.kitchen {width:300px;height:300px;}.washroom {width:45px;height:60px;}
Como você pode ver em este exemplo , nossos quartos ainda estão uniformemente espaçados. Mesmo que tenhamos mudado o tamanho. O Flexbox é brilhante na organização de conteúdo.
Como discutimos acima, uma das razões pelas quais o flexbox funciona tão bem para os designers é que ele é descrito como um vetor. Atualmente, o flexbox suporta apenas quatro ângulos: 0, 90, 180 e 270 graus. Então é muito mais simples pensar neles como um eixo.
Para alterar o eixo, usamos a propriedade flex-direction , que tem quatro valores possíveis: row (o padrão - como você pode ver nos exemplos acima, nossos quartos estão dispostos da esquerda para a direita), row-reverse, column e coluna reversa.
Se mudarmos a direção da flexão para a coluna, você verá nesta demo que os quartos agora estão dispostos verticalmente, de cima para baixo:
.house {background:#FF5651;display:flex;justify-content: space-around;flex-direction:column;}
Como tenho certeza de que você pode adivinhar, a reversão de linha e a reversão de coluna invertem a ordem dos itens em seu contêiner flexível.
Você notará no último exemplo que, enquanto a casa se estende por toda a janela de exibição, ela se estende até a altura total, mesmo quando definida como flex-direction: column.
Para funcionar bem com o sistema de coordenadas baseado em cartesiano do CSS, o contêiner do flexbox é tratado como um elemento de nível de bloco.
Exatamente como display: o bloco possui uma exibição complementar : inline-block, portanto , para mostrar: flex tem display: inline-flex.
O inline-flex é atualmente mais útil se você estiver colocando elementos do flexbox em um layout existente e você precisa dele para brincar com floats e elementos posicionados.
Como vimos, o flexbox não se importa se ele está na horizontal ou na vertical, a direção escolhida é considerada o eixo primário do flexbox.
Mas o flexbox também nos permite controlar a posição ao longo do eixo secundário oposto.
A posição no eixo secundário é controlada pela propriedade align-items ; Ele tem cinco valores possíveis: linha de base, centro, flex-end, flex-start e stretch.
linha de base normalmente será a opção mais útil. Assegura que as linhas de base do texto estejam alinhadas. Para testar isso, precisamos fazer algumas modificações em nosso arquivo HTML:
Flexbox Layout KitchenWashroomLoungeBedroomBedroom
Você verá que adicionei um texto, importou e aplicou uma fonte do Google. Eu também mudei o tamanho da fonte na cozinha e no banheiro, então há uma clara distinção.
Quando definimos a propriedade de itens de alinhamento como linha de base, você verá nesta demo que a linha de base do texto coincida.
.house {background:#FF5651;display:flex;justify-content:space-around;align-items:baseline;}
itens de alinhamento: o centro central alinha, verticalmente (se flex-direção: linha ou flex-direção: linha-reversa ) ou horizontalmente (se flex-direção: coluna, ou flex-direção: coluna-reversa ). Aqui está uma demonstração.
itens de alinhamento: o início flexível alinha - se à parte superior e os itens de alinhamento: a extremidade flexível alinha - se à parte inferior (se flex-direction: row ou flex-direction: row-reverse ) ou à esquerda e à direita flex-direction: coluna, ou flex-direction: coluna-reversa ). Aqui está uma demonstração.
alongar, é outra opção muito útil. o alongamento redimensionará os itens, de modo que cada um tenha a mesma altura (eles crescerão, não encolherão). Aqui está uma demonstração.
Em nossos outros exemplos, definimos explicitamente a altura dos itens, o que é suficiente para substituir o flexbox, portanto, para ver os itens de alinhamento: estique o trabalho corretamente, será necessário remover a altura de todas as classes, exceto uma.
Até agora, usamos o flexbox nos elementos de layout para que eles sejam redimensionados em todo o espaço, mas o que acontece quando o conteúdo dos itens é grande demais para caber em uma linha?
Para demonstrar isso, vou aumentar o tamanho dos meus quartos:
Flexbox Layout KitchenWashroomLoungeBedroomBedroom
Aqui está como parece agora.
Se você diminuir a janela do navegador, verá que o conteúdo é cortado, pois não há espaço para isso. Felizmente, o flexbox define uma propriedade de flex-wrap apenas para essa eventualidade, que possui três valores possíveis: no-wrap (o padrão), wrap e wrap-reverse.
wrap faz com que quaisquer itens que se estendam além do contêiner sejam agrupados em uma linha subsequente, exatamente como uma linha de texto é envolvida.
.house {background:#FF5651;display:flex;justify-content:space-around;align-items:baseline;flex-wrap:wrap;}
Se você esmagar o seu navegador, você verá nesta demo os itens agora são colocados em novas linhas. Observe como a propriedade de itens de linha de base: ainda é aplicada? O poder real do Flexbox está em combinar suas propriedades.
Um conceito importante, que abordarei mais adiante, é que o flex-wrap: wrap-reverse não reverte a ordem dos itens, fazendo com que quaisquer itens que se estendam além do contêiner sejam envolvidos em uma linha anterior, como visto nesta demo .
Como muitas propriedades CSS, algumas propriedades do flexbox têm versões abreviadas que são implementadas de forma mais consistente pelos fabricantes de navegadores.
A propriedade flex-flow é uma abreviatura das propriedades flex-direction e flex-wrap . Então, ao invés de escrever:
flex-direction:row-reverse;flex-wrap:wrap;
Nós podemos usar a abreviação:
flex-flow:row-reverse wrap;
Acima, usamos a propriedade align-items para alinhar itens aos itens de linha de base, posição e alongamento. Como você pode ver no último exemplo, isso ainda está ocorrendo, mas ocorre linha por linha.
Quando nossos itens foram agrupados, temos a opção de definir como eles serão dispostos no eixo secundário se o contêiner for maior que o necessário.
Se definirmos a altura mínima da nossa casa para 1200px, nosso layout se parece com isso .
.house {background:#FF5651;min-height:1200px;display:flex;justify-content:space-around;flex-wrap:wrap;}
Agora podemos usar a propriedade align-content para dispor os itens no eixo secundário completo.
A propriedade align-content possui seis configurações: center, flex-end, flex-start, espaço-around, espaço-entre e stretch. Esses valores fornecem os mesmos resultados que em outros lugares: centralização, alinhamento a uma extremidade, espaçamento uniforme ou alongamento.
Aqui está uma demonstração com a propriedade definida como espaço ao redor.
Até agora, todas as propriedades que analisamos foram definidas no elemento container. Para ajustar os itens, o flexbox também nos fornece várias propriedades que podem ser definidas em itens individuais.
Para esclarecer isso, vamos remover alguns dos nossos códigos:
Flexbox Layout KitchenWashroomLoungeMaster BedroomBedroom
Aqui está como parece.
A primeira propriedade de item do flexbox é a propriedade flex com nome confuso. flex é um valor da propriedade de exibição no contêiner, mas também é uma propriedade independente.
A propriedade flex é um atalho para as propriedades flex-grow, flex-shrink e flex-base . O papel dessas propriedades é esticar ou reduzir o tamanho do conteúdo para que ele preencha o espaço completamente.
A propriedade flex-grow informa os itens que eles podem ampliar, se necessário, para que os itens preencham totalmente a largura (para flex-direction: row ) e a altura (para flex-direction: column ).
A propriedade flex-grow recebe uma proporção. Então, se definirmos a propriedade flex-grow como 1, todos os nossos itens terão o mesmo tamanho você pode ver aqui .
.room {background:#00AAF2;height:90px;flex-grow:1;}
Além de ter um tamanho igual, também podemos definir proporções diferentes. Eu ainda quero que minha cozinha seja maior do que o meu banheiro, então vamos consertar isso nesta demo .
.kitchen {height:300px;flex-grow:2;}
O flex-shrink funciona exatamente da mesma maneira que o flex-grow, exceto que ele encolhe o item, se necessário, em vez de expandi-lo.
Se você redimensionar o navegador, verá que em tamanhos diferentes, a minha cozinha não é exatamente o dobro da largura das outras salas . Isso é devido à propriedade de base flexível .
flex-basis determina como as propriedades flex-grow e flex-shrink são calculadas. Tem 2 valores: auto (o padrão) e 0.
Se definido como 0, todo o item é levado em consideração. Se definido como automático , é o preenchimento em torno do conteúdo do item que é redimensionado. Em outras palavras, 0 ignora o tamanho do conteúdo do item ao calcular, e o automático leva isso em consideração. Há um diagrama prático fornecido pelo W3C que explica isso.
Aqui está uma demonstração do que acontece quando eu defino flex-basis: 0 no exemplo acima.
flex-basis: 0 é particularmente útil se você deseja dividir itens uniformemente, independentemente do conteúdo.
Como dito acima, a propriedade flex é um atalho para essas propriedades, e você descobrirá que é a maneira mais confiável de definir esses valores.
A ordem dos valores é flex-grow, flex-shrink, flex-base. Então, para definir um valor de crescimento de 2, um valor de encolhimento de 1 e uma base de 0, você usaria:
.room {background:#00AAF2;height:90px;flex: 2 1 0;}
Um dos melhores recursos do flexbox é sua capacidade de alterar a ordem dos itens, sem afetar a marcação; isso é particularmente útil para acessibilidade, pois permite codificar a marcação adequadamente e, em seguida, exibi-la de maneira ideal.
Para fazer isso, usamos a propriedade order do item.
Olhando para o nosso exemplo, o banheiro fica ao lado da cozinha. Eu prefiro que seja ao lado dos quartos, então eu posso pular direto para o chuveiro da manhã, então vamos mexer. Atualmente é o segundo item, queremos que seja o terceiro. Então, definimos a propriedade do pedido de acordo nesta demo .
.washroom {height:60px;order:2;}
Veja como ele pulou todo o caminho até o final da linha? É ao lado dos quartos, mas não como pretendíamos. Essa é uma grande pegadinha no flexbox, porque muitos desenvolvedores (inclusive eu) inicialmente esperam que a ordem funcione como um array.
A ordem na verdade funciona como o z-index do CSS , o que significa que se você não definir explicitamente um pedido para um item, ele será considerado menor na ordem do que um item para o qual um valor foi explicitamente definido.
Queremos que o banheiro seja trocado pelo salão, então nesta demo os únicos outros itens que precisam de um pedido são os quartos .
.washroom {height:60px;order:2;}.bedroom {order:3;}
Observe como os dois quartos compartilham o mesmo número de pedido? Em casos como esses, o navegador recorrerá à ordem DOM.
A propriedade final do item é alinhada. É usado para alterar o alinhamento do item no eixo secundário. Os itens de alinhamento são usados para alinhar todos os itens, e essa propriedade oferece a opção de desativar essa configuração geral.
Ele usa os mesmos cinco valores que a propriedade equivalente no contêiner: linha de base, centro, flex-end, flex-start e stretch.
Aqui está uma demonstração do banheiro realinhado.
.washroom {height:60px;order:2;align-self:flex-end;}
O Flexbox é uma opção poderosa para o layout de conteúdo. Embora não seja para o uso de páginas inteiras, seu suporte superior ao Layout de grade torna-a uma ótima opção, especialmente para sites que exigem acesso móvel.
Para demonstrar, vamos montar uma página simples que use algumas das técnicas descritas acima.
A primeira é a nossa marcação e alguns estilos básicos para a página.
Flexbox Demo - A
- B
- C
- D
- E
- F
- G
Como você pode ver , Eu tenho um div com a página de id . Página interna Eu tenho uma lista não ordenada de itens de notícias. Após as notícias, tenho o cabeçalho, que está abaixo do conteúdo de notícias em benefício da acessibilidade. Finalmente, eu tenho um rodapé.
A primeira coisa que quero fazer é mover o cabeçalho para o topo da página. Para fazer isso, definiremos a página como um contêiner de flexbox. Então vamos definir a direção para a coluna. Em seguida, atribua um pedido a cada elemento filho da página .
#page {display:flex;}#page {display:flex;flex-flow:column;}#header {order:1;}#news {order:2;}#footer {order:3;}
O próximo passo é colocar o cabeçalho. Elementos filho dentro de contêineres flexbox podem ser contêineres flexbox por si só, portanto, podemos usar flexbox para espaçar uniformemente os elementos de cabeçalho .
Vamos definir o cabeçalho para ser um contêiner de flexbox, então vamos espaçar o conteúdo uniformemente, sem preenchimento extra nas laterais e, finalmente, vamos garantir que os itens de menu estejam na mesma linha de base do logotipo.
#header {order:1;display:flex;justify-content:space-between;align-items:baseline;}
Nossas notícias serão espaços reservados para histórias em destaque, portanto, elas precisam ter um tamanho substancial para criar espaço para texto, imagem ou vídeo. Então precisamos deles para embrulhar.
Vamos definir a notícia div como um contêiner flexbox. Em seguida, vamos dar ao newsItem algumas dimensões mínimas e algumas cores para que possamos vê-las claramente.
#news {order:2;display:flex;}.newsItem {min-width:300px;min-height:250px;background:#79797B;border:1px solid #706667;}
Agora precisamos definir o contêiner de notícias para encapsular e os itens de notícias a serem expandidos para preencher o espaço disponível.
#news {order:2;display:flex;flex-flow:row wrap;}
O desafio que temos agora é que quando os itens de notícias não são distribuídos uniformemente, o maior item (G) está na parte inferior. Na maioria dos sites, queremos dar a maior quantidade de espaço ao conteúdo superior. Podemos consertar isso configurando o wrap para quebrar e inverter.
#news {order:2;display:flex;flex-flow:row wrap-reverse;}
Que reordena os itens, mas lendo do canto superior esquerdo, eles estão fora de ordem. Então, precisamos inverter a ordem, definindo a direção para reverter a linha.
#news {order:2;display:flex;flex-flow:row-reverse wrap-reverse;}
Isso coloca os itens em ordem consecutiva, lendo da esquerda para a direita, de cima para baixo; com os itens maiores sempre no topo. Mas eu não quero ter que alterar a ordem das histórias na minha marcação para forçar o item A a chegar antes do item B. Então a última coisa que eu preciso fazer é mudar a ordem dos itens.
.newsItem:nth-of-type(7) {order:1;}.newsItem:nth-of-type(6) {order:2;}.newsItem:nth-of-type(5) {order:3;}.newsItem:nth-of-type(4) {order:4;}.newsItem:nth-of-type(3) {order:5;}.newsItem:nth-of-type(2) {order:6;}.newsItem:nth-of-type(1) {order:7;}
O último elemento a ser estilizado é o rodapé. Queremos defini-lo, muito parecido com o cabeçalho, mas como o rodapé tem apenas três elementos filho (em comparação com os quatro do cabeçalho ), vamos definir o parágrafo para ser duas vezes mais largo que o logotipo, e a lista .
#footer {order:3;display:flex;align-items:baseline;flex-direction:row;}#footer > * {flex:1;}#footer > p {flex:2;padding-right:2em;}
Isso funciona muito bem em tamanhos de área de trabalho, mas reduza o seu navegador para baixo e você verá que ele é muito apertado em dispositivos pequenos. Então, vamos alterar o código para que ele seja exibido como colunas abaixo de 600px e reverte para uma linha acima de 600px.
#footer {order:3;display:flex;align-items:baseline;flex-direction:column;padding:2em 0;}#footer > * {flex:1;}#footer > p {flex:2;}@media only screen and (min-width:600px) {#footer {flex-direction:row;padding:0;}#footer > p {margin-right:2em;}}
E aí você tem isso. Uma abordagem moderna para o layout de conteúdo em uma página da Web, que é amplamente suportada e fácil de implementar.
O poder do flexbox é que suas propriedades podem ser combinadas para nos dar um controle preciso sobre nossos layouts, com a sintaxe mais simples possível.