Como criar layouts inteligentes somente CSS com Flexbox

Publicados: 2022-03-11

Caixa flexível, ou Flexbox em resumo, é um conjunto de propriedades em CSS introduzidas em 2009 para fornecer um sistema de layout novo e excepcional. O módulo Flexbox é identificado como parte da terceira versão do CSS (CSS3).

Você provavelmente já está usando muitas das novas propriedades do CSS3, como box-shadow , border-radius , background gradients e assim por diante. No entanto, o Flexbox ainda não viu a ampla adoção que merece. Isso pode ser devido a todas as mudanças que sofreu ao longo dos anos, ou porque é apenas parcialmente suportado no Internet Explorer 10, ou apenas porque o Flexbox é um ecossistema inteiro, enquanto os paradigmas anteriores eram predominantemente baseados em um único, pronto para uso. ir propriedades.

Ele é super poderoso e oferece uma ampla gama de opções para conseguir layouts que, antes, só podiam ser sonhados.

Este artigo irá guiá-lo pelos conceitos básicos do Flexbox e como você pode usá-lo para obter alguns layouts muito legais que, de outra forma, exigiriam hacks complicados de CSS ou mesmo JavaScript.

Por que usar o Flexbox?

Por padrão, os elementos em nível de bloco HTML são empilhados, portanto, se você quiser alinhá-los em uma linha, precisará confiar em propriedades CSS como float ou manipular a propriedade display com configurações table-ish ou inline-block.

Se você optar por usar float (esquerda ou direita), deverá limpar o wrapper em algum momento para empurrá-lo até o último elemento flutuante, caso contrário, eles transbordarão sobre qualquer coisa que venha depois. No entanto, com float, você fica limitado a organizar os elementos horizontalmente.

Alternativamente, ou além disso, você pode manipular a propriedade display para tentar obter o layout desejado! Mas isso geralmente parece desajeitado na melhor das hipóteses, para não mencionar tedioso, e muitas vezes resulta em um layout bastante frágil que não será necessariamente renderizado de forma consistente nos navegadores. Essa abordagem é particularmente ineficaz se você estiver segmentando vários dispositivos de tamanhos variados, o que quase sempre é o caso hoje em dia.

Entre na Flexbox!

Com uma regra simples aplicada a um elemento pai, você pode controlar facilmente o comportamento do layout de todos os seus filhos.

Com o Flexbox, você pode:

  • Inverta a ordem dos elementos dentro de um pai Flexbox.
  • Envolva elementos filho em colunas (o número de colunas pode variar dependendo da altura do filho e do pai).
  • Especifique a taxa na qual os elementos crescem ou diminuem enquanto o tamanho da janela de visualização é alterado.
  • Controle se os elementos podem ser reduzidos ou não, independentemente do tipo de unidade de largura especificado (relativo ou absoluto).
  • Altere a ordem dos elementos com CSS (combine isso com consultas de mídia e você encontrará possibilidades ilimitadas em seu fluxo).
  • Gere distribuições complexas dos elementos para serem equidistantes com espaço ao redor ou apenas espaço entre.
  • Gere elementos “renegados” que fluam de forma diferente (todos à esquerda, mas um à direita, superior/inferior… a decisão é sua).
  • E, o mais importante, evite o hack de correção clara para sempre!

Eu entendo que o Flexbox pode ser difícil no começo. Eu acho que é mais fácil aprender dez propriedades CSS não relacionadas do que cinco com alguma interdependência. No entanto, com suas habilidades atuais de CSS e talvez uma pequena ajuda deste artigo, você se lançará em um novo universo de CSS.

Noções básicas de Flexbox

Tela

Tela

display é uma das propriedades mais básicas em CSS e é bastante importante no contexto do Flexbox, pois é usado para definir um flex wrapper.

Existem dois valores possíveis de wrapper flex: flex e inline-flex .

A diferença entre os dois é que um display: flex wrapper age como um elemento de bloco enquanto um display: inline-flex wrapper age como um inline-block. Além disso, os elementos inline-flex crescem se não houver espaço suficiente para conter os filhos. Mas fora essas diferenças, o comportamento dos dois seria o mesmo.

Experimente o código de exemplo abaixo, reduza a largura da janela de visualização quando o inline-flex estiver ativo e… role.

Veja a propriedade Pen Flexbox @Toptal - Parent - `display` por DD (@Diegue) no CodePen.

 .wrapper { display: flex || inline-flex; }

Direção flexível

Direção flexível

Agora que você viu a primeira amostra, pode inferir que o comportamento padrão é simplesmente fazer uma linha dos elementos. Mas há mais:

  • row (padrão): organiza os elementos da esquerda para a direita (mas se RTL estiver definido, será para trás).
  • row-reverse: inverte a ordem dos elementos em uma disposição de linha
  • coluna: organiza os elementos de cima para baixo
  • column-reverse: Inverte as ordens dos elementos em uma disposição de coluna

Dica: Os valores de column e column-reverse podem ser usados ​​para trocar os eixos, de modo que as propriedades que afetariam o eixo horizontal afetariam o eixo vertical.

Veja a propriedade Pen Flexbox @Toptal - Parent - `flex-direction` por DD (@Diegue) no CodePen.

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

Envoltório flexível

Se você verificar o primeiro exemplo de código, descobrirá que os elementos filho não são empilhados por padrão em um wrapper flexível. É aqui que flex-wrap entra em ação:

  • nowrap (padrão): Impede que os itens em um contêiner flexível sejam agrupados
  • wrap: agrupa os itens conforme necessário em várias linhas (ou colunas, dependendo do flex-direction )
  • wrap-reverse: Assim como wrap , mas o número de linhas (ou colunas) cresce na direção oposta à medida que os itens são agrupados

Veja a propriedade Pen Flexbox @Toptal - Parent - `flex-wrap` por DD (@Diegue) no CodePen.

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

Fluxo flexível

Você pode combinar as propriedades flex-direction e flex-wrap em uma única propriedade: flex-flow .

 .wrapper { flex-flow: {flex-direction} {flex-wrap}; }

Justifique o conteúdo

Justifique o conteúdo

Esta propriedade é usada para controlar o alinhamento horizontal dos elementos filhos:

  • flex-start (padrão): os elementos são alinhados à esquerda (semelhante aos elementos inline com text-align: left )
  • flex-end: os elementos são alinhados à direita (semelhante aos elementos inline com text-align: right )
  • center: os elementos são centralizados (semelhante aos elementos embutidos com text-align: center )
  • space-around (onde a mágica começa): Cada elemento será renderizado com a mesma quantidade de espaço ao redor de cada item. Observe que o espaço entre dois elementos filho sequenciais será o dobro do espaço entre os elementos mais externos e os lados do wrapper.
  • space-between: Assim como space-around , exceto que os elementos serão separados pela mesma distância e não haverá espaço próximo a nenhuma borda do wrapper.

Nota: Lembre-se de que flex-direction , quando definido como column ou column-reverse , troca o eixo. Se um deles estiver definido, justify-content afetará o alinhamento vertical, não o horizontal.

Veja a propriedade Pen Flexbox @Toptal - Parent - `justify-content` por DD (@Diegue) no CodePen.

Alinhar itens

Alinhar itens

Essa propriedade é semelhante a justify-content mas o contexto de seus efeitos são as linhas em vez do próprio wrapper:

  • flex-start: Os elementos são alinhados verticalmente na parte superior do wrapper.
  • flex-end: Os elementos são alinhados verticalmente na parte inferior do wrapper.
  • center: Os elementos são centralizados verticalmente dentro do wrapper (finalmente, uma prática segura para conseguir isso).
  • esticar (padrão): Força os elementos a ocuparem a altura total (quando aplicado a uma linha) e a largura total (quando aplicado a uma coluna) do wrapper.
  • linha de base: alinha verticalmente os elementos às suas linhas de base reais.

Veja a propriedade Pen Flexbox @Toptal - Parent - `align-items` por DD (@Diegue) no CodePen.

Alinhar conteúdo

Alinhar conteúdo

Essa propriedade é semelhante a justify-content e align-items , mas funciona no eixo vertical e o contexto é o wrapper inteiro (não a linha, como no exemplo anterior). Para ver seus efeitos, você precisará de mais de uma linha:

  • flex-start: As linhas são alinhadas verticalmente no topo (ou seja, empilhadas a partir do topo do wrapper).
  • flex-end: As linhas são alinhadas verticalmente na parte inferior (ou seja, empilhadas a partir da parte inferior do wrapper).
  • center: as linhas são centralizadas verticalmente no wrapper.
  • stretch (padrão): Em geral, esta propriedade estica os elementos para utilizar toda a altura vertical do wrapper. No entanto, se você tiver definido alguma altura específica dos elementos, essa altura será respeitada e o espaço vertical restante (nessa linha, abaixo desse elemento) ficará vazio.
  • space-around: Cada linha será renderizada com a mesma quantidade de espaço em torno de si verticalmente (ou seja, abaixo e acima de si mesma). Observe que o espaço entre duas linhas será, portanto, o dobro do espaço entre as linhas superior e inferior e as bordas do wrapper.
  • space-between: Assim como space-around , exceto que os elementos serão separados pela mesma distância e não haverá espaço nas bordas superior e inferior do wrapper.

Veja a propriedade Pen Flexbox @Toptal - Parent - `align-content` por DD (@Diegue) no CodePen.

Flexão de crescimento

Flexão de crescimento

Essa propriedade define a proporção relativa do espaço disponível que o elemento deve usar. O valor deve ser um número inteiro, onde 0 é o padrão.

Digamos que você tenha dois elementos diferentes no mesmo wrapper flex. Se ambos tiverem um valor de flex-grow de 1, eles crescerão igualmente para compartilhar o espaço disponível. Mas se um valor de flex-grow de 1 e o outro um valor de flex-grow de 2, como mostrado no exemplo abaixo, este com um valor de flex-grow de 2 crescerá para ocupar duas vezes mais espaço que o primeiro.

 .wrapper .elements { flex-grow: 1; /* Default 0 */ } .wrapper .elements:first-child { flex-grow: 2; } 

Veja a propriedade Pen Flexbox @Toptal - Children - `flex-grow` por DD (@Diegue) no CodePen.

Flex Shrink

Semelhante ao flex-grow , esta propriedade define se o elemento é “encolhível” ou não com um valor inteiro. Semelhante a flex-grow , flex-shrink especifica o fator de redução de um item flex.

Veja a propriedade Pen Flexbox @Toptal - Children - `flex-shrink` por DD (@Diegue) no CodePen.

 .wrapper .element { flex-shrink: 1; /* Default 0 */ }

Base flexível

Esta propriedade é usada para definir o tamanho inicial de um elemento antes que o espaço disponível seja distribuído e os elementos sejam ajustados de acordo.

Dica: flex-basis não suporta calc() e box-sizing: border-box em todos os navegadores, então eu recomendo usar width se você precisar usar um desses (observe que você também precisará definir flex-basis: auto; ).

Veja a propriedade Pen Flexbox @Toptal - Children - `flex-basis` de DD (@Diegue) no CodePen.

 .wrapper .element { flex-basis: size || auto; /* Default auto */ }

Flexão

Você pode combinar as propriedades flex-grow , flex-shrink e flex-basis em uma única propriedade: flex da seguinte forma:

 .wrapper { flex: {flex-grow} {flex-shrink} {flex-basis}; }

Dica: Se você planeja usar flex , certifique-se de definir todos os valores (mesmo se quiser usar valores padrão) porque alguns navegadores podem não reconhecê-los (um bug comum está relacionado a não ter definido o valor flex-grow ).

Alinhar a si mesmo

Alinhar a si mesmo

Esta propriedade é semelhante a align-items mas o efeito é aplicado individualmente a cada elemento. Os valores possíveis são:

  • flex-start: alinha verticalmente o elemento ao topo do wrapper.
  • flex-end: Alinha verticalmente o elemento na parte inferior do wrapper.
  • center: centraliza verticalmente o elemento dentro do wrapper (finalmente uma maneira simples de conseguir isso!).
  • esticar (padrão): estica o elemento para ocupar a altura total do wrapper (quando aplicado a uma linha) ou a largura total do wrapper (quando aplicado a uma coluna).
  • baseline: Alinha os elementos de acordo com suas linhas de base reais.

Veja a propriedade Pen Flexbox @Toptal - Children - `align-self` de DD (@Diegue) no CodePen.

Ordem

Flexbox pode reordenar imagens conforme apresentado neste exemplo

Uma das melhores coisas incluídas no Flexbox é a capacidade de reordenar elementos (usando a propriedade order ) sem precisar modificar o DOM ou usar JavaScript. A forma como a propriedade order funciona é super simples. Da mesma forma que o z-index controla a ordem na qual os itens são renderizados, a order controla a ordem na qual os elementos são posicionados dentro do wrapper; ou seja, elementos de menor valor de order (que pode até ser negativo, diga-se de passagem) são posicionados antes daqueles de maior valor de order .

Veja a propriedade Pen Flexbox @Toptal - Children - `order` por DD (@Diegue) no CodePen.

 .wrapper .elements { order: 1; /* this one will be positioned second */ } .wrapper .elements:last-child { order: -1; /* this one will be positioned first */ }

Juntando tudo: exemplos de uso do Flexbox

Quando se trata de projetar layouts, o Flexbox abre um mundo de possibilidades. Abaixo, você pode encontrar alguns exemplos de uso das propriedades do Flexbox.

Componente de alinhamento vertical

Com o Flexbox, você pode alinhar qualquer coisa verticalmente, incluindo vários elementos de uma só vez. Sem o Flexbox, você precisava usar técnicas de posicionamento ou de tabela que exigiam a criação de um filho para conter vários elementos. Mas com o Flexbox, você pode deixar essas técnicas tediosas e frágeis para trás, e simplesmente definir algumas propriedades no wrapper e pronto, independente de quantas vezes o conteúdo dentro do container mude ou o tipo de mudança!

 .wrapper { display: flex; /* always present for Flexbox practices */ flex-direction: column; /* elements stack */ justify-content: center; /* now that flex-direction is a column, the axis are swapped so this centers the content vertically */ min-height: 100vh /* make sure wrapper is taller enough */ } 

Veja o Pen Flexbox @Toptal - Usos reais que podemos dar - Alinhamento vertical por DD (@Diegue) no CodePen.

Metade/metade de layout

Um layout “metade/metade” é um layout de altura total com duas colunas, cada uma com seu conteúdo centralizado verticalmente. Geralmente é implementado “acima da dobra” (ou seja, antes que os usuários rolem para baixo após o carregamento da página).

Usando técnicas mais tradicionais, você pode criar esse layout com elementos flutuantes (de largura de 50% cada), limpando os flutuantes no wrapper (“clearfix” :before e :after , overflow: hidden , ou um <div> maluco com clear: both; no final). No entanto, é muito trabalho e o resultado não é tão estável quanto o que o Flexbox oferece.

No trecho de código a seguir, você verá como é fácil definir o layout e também como os filhos também se tornam wrappers Flexbox, pois tudo também está alinhado verticalmente.

Invólucro externo:

 .wrapper { display: flex; flex-direction: column; /* only for mobile */ }

Invólucros internos:

 .inner-wrapper { flex-grow: 1; /* Allow the element to grow if there is available space */ flex-shrink: 1; /* Elements shrink at the same rate */ flex-basis: 100%; /* Elements will cover the same amount, if is possible the 100% of the width */ } 

Veja a Pen Flexbox @Toptal - Usos reais que podemos dar - Seção Half-bleed por DD (@Diegue) no CodePen.

Botões da barra de navegação de largura total

Uma barra de navegação de largura total distribui o espaço igualmente na mesma linha de itens da barra de navegação, independentemente do número de elementos.

No exemplo abaixo, também existem alguns botões icônicos sem esse comportamento, demonstrando que você pode combinar os dois da forma que quiser. Sem o Flexbox, alcançar esses tipos de layouts exigiria código JavaScript para calcular o espaço disponível e depois distribuí-lo programaticamente, dependendo de quais botões se estendem e quais não.

Flexbox torna isso muito mais simples.

Propriedades do invólucro:

 .navbar { display: flex; }

Abrangendo propriedades filhas:

 .navbar-item { flex-grow: 1; /* They will grow */ }

Propriedades filho não abrangentes:

 .navbar-other { flex-grow: 0; // They won't grow } 

Veja o Pen Flexbox @Toptal - Usos reais que podemos dar - Navbar de botões full-bleed por DD (@Diegue) no CodePen.

Resumos

Quantas vezes você teve que implementar um conjunto de caixas de informação com ícones e texto em diferentes projetos?

Essa distribuição de elementos é útil principalmente no marketing digital, mas pode ter outros usos no desenvolvimento de software. Com o poder do Flexbox, você pode definir uma espécie de grade e também alinhar elementos, independentemente de quantos sejam.

Propriedades do invólucro:

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

Propriedades filho:

 .blurb { flex-grow: 0; /* elements don't grow */ flex-shrink: 0; /* elements don't shrink in a flexible way */ flex-basis: auto; /* the width of the elements will be set by proportions in `width` due to flex-basis not support workaround */ width: calc(33.33% - 60px); /* calculate proportional width without space taken by padding (workaround for IE 11) */ }

Para janelas de visualização de tablets e dispositivos móveis, a largura varia entre 50% e 100%.

Veja o Pen Flexbox @Toptal - Usos reais que podemos dar - Blurbs by DD (@Diegue) no CodePen.

Aprimorando a compatibilidade entre navegadores

A sintaxe do Flexbox mudou várias vezes em diferentes versões do navegador. Isso pode ser um problema ao implementar um layout com o Flexbox e tentar oferecer suporte a navegadores da Web mais antigos, especialmente versões mais antigas do Internet Explorer.

Felizmente, muitas técnicas e soluções alternativas para fazer seu código funcionar na mais ampla variedade de navegadores da Web estão listadas no Flexbugs, que é um ótimo recurso. Se você seguir as informações desse site, terá resultados melhores e consistentes em diferentes navegadores da web.

As tarefas de prefixo são particularmente úteis nesse sentido. Para automatizar a prefixação de regras CSS, você pode escolher uma das seguintes ferramentas:

Rubi:

  • Trilhos com prefixo automático
  • Prefixador automático intermediário

Node.js:

  • PostCSS Autoprefixer
  • Autoprefixador Grunt
  • Gulp Autoprefixador

Comece a criar layouts inteligentes

O Flexbox é uma ótima ferramenta para acelerar, aprimorar e dimensionar nosso trabalho. O limite está apenas na imaginação do desenvolvedor.

Se você precisar de alguma ajuda visual para planejar seu próximo layout, tente este playground legal:

Veja o Pen Flexbox @Toptal - Flexbox playground de DD (@Diegue) no CodePen.

Abra-o em uma nova janela.

Com a crescente adoção de navegadores modernos pela maioria dos usuários, o uso do Flexbox permitirá que você crie layouts incríveis facilmente, sem a necessidade de se aprofundar no código JavaScript confuso ou criar CSS desajeitado.