Como criar layouts inteligentes somente CSS com Flexbox
Publicados: 2022-03-11Caixa 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
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
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
ecolumn-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
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 comocolumn
oucolumn-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
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
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
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 suportacalc()
ebox-sizing: border-box
em todos os navegadores, então eu recomendo usarwidth
se você precisar usar um desses (observe que você também precisará definirflex-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 valorflex-grow
).
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
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.