
Uma das minhas partes favoritas da especificação CSS Grid é
grid-gap
. Eles facilitam a indentação entre os elementos dentro da grade.
As margens e as técnicas que recorremos para implementá-las em diferentes situações têm sido um dos principais pontos irritantes do CSS.
O W3C recomendou o abandono da propriedade
grid-gap
em favor de um
gap
simples e seu uso no Flexbox e no Multi-Column.
Neste guia, veremos como as margens foram adicionadas ao Flexbox antes e como a propriedade
gap
faz isso, permitindo obter recuo sem ajustes adicionais.
Margens em uma grade Flexbox comum
Neste exemplo, pegaremos um grupo de blocos, usaremos o Flexbox para criar um estilo de malha e separaremos os blocos usando margens.
Vamos começar com HTML básico. Temos
flex-container
flex-item.
<div class="flex-container"> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> </div>
Graças ao comportamento do Flexbox, o conteúdo será localizado um ao lado do outro. Com base no valor da largura do contêiner, determinamos o tamanho dos filhos e, em seguida, permitimos que eles sejam transferidos usando a propriedade
flex-wrap
.
.flex-container { display: flex; flex-wrap: wrap; } .flex-item { width: calc(100% / 3); }

Isso nos dá blocos de tamanho perfeito iguais a 1/3 da largura do contêiner. Vamos definir margens para adicionar espaço vertical e horizontal entre cada elemento.
.flex-item { width: calc(100% / 3); margin-right: 1rem; margin-bottom: 1rem; }

Ai! Nossos elementos, que são 1/3 do contêiner, não se ajustam mais à largura do elemento pai. Embora as margens entre as linhas tenham sido bastante corretas e não causem problemas.
Precisamos definir a largura dos filhos, levando em consideração o espaço adicional criado pela margem. Você também precisa definir a propriedade
margin-right
como zero para cada terceiro elemento.
Agora, temos duas margens iguais a
1rem
e devemos subtraí-las uniformemente da largura dos três elementos.
flex-item { // width: calc(100% / 3); width: calc((100% / 3) - (2rem / 3)); // one-third - two margins divided equally among 3 items margin-right: 1rem; margin-bottom: 1rem; } .flex-item:nth-child(3n) { margin-right: 0; }

Parece muito difícil? Para mim sim. Existem maneiras mais simples de fazer isso, mas elas também não fornecem o espaçamento exato de 1rem entre as colunas. Esse código complexo também complica bastante o design responsivo.
Quando a propriedade gap fica disponível para uso no Flexbox em todos os navegadores, o código fica muito mais limpo. Também podemos passar de definir a largura para crianças para usar as propriedades
flex-grow
,
flex-shrink
e
flex-basis
.
Recuar com Gap
Usando a propriedade gap, nos livramos da necessidade de executar a maioria dos truques com a largura dos elementos. Também nos permite voltar a usar valores flex-grow / flex-shrink.
No exemplo a seguir, ainda usamos a
display: flex
e
flex-wrap: wrap
propriedades para nosso contêiner, mas agora também adicionamos a propriedade
gap
. Essa é uma propriedade abreviada que combina o
row-gap
entre
column-gap
. Confira a
documentação do
MDN para todos os métodos.
Agora, em vez de definir a largura para cada elemento flexível, definimos os valores flex-grow, flex-shrink e flex-base. A propriedade
flex-basis
determinará quantas colunas os navegadores instalarão no contêiner. Ainda usaremos a função
calc()
para isso, mas o código acabará ficando mais limpo
.flex-container { display: flex; flex-wrap: wrap; gap: 1rem; } .flex-item { flex: 1 1 calc((100% / 3) - 2rem); }

Um leitor atento também notará que agora isso permite que os últimos elementos aumentem de tamanho para preencher o espaço da linha na qual os elementos estão ausentes. É isso que CSS Grid e Flexbox, com base na largura dos elementos, não podem fazer por nós.
Bônus: Gap também facilita a capacidade de resposta.
Em nosso exemplo original, se quiséssemos alterar o número de colunas de contêiner em determinados pontos de controle, teríamos que recalcular a largura E alterar os seletores de
nth-child
para se livrar das margens.
No exemplo de
gap
, tudo o que precisamos fazer é ajustar a propriedade de base flexível e pronto.
.flex-item { flex: 1 1 100%; // 1 across at mobile } @media (min-width: 640px) { .flex-item { flex-basis: calc((100% / 2) - 1rem); // 2 across at tabletish } } @media (min-width: 1024px) { .flex-item { flex-basis: calc((100% / 3) - 2rem); // 3 across at desktop } }
Não vou mentir,
ainda prefiro CSS Grid para esse padrão de design, mas espero que você veja alguns exemplos de uso para esse incrível novo recurso.
Olhando para o futuro
Agora, a propriedade gap é suportada apenas no Firefox. Portanto, se este artigo lhe interessar, peço desculpas humildemente. Você terá que esperar que outros navegadores os atualizem. Espero que eles notem a dor dos desenvolvedores em relação às margens e, mais cedo ou mais tarde, nos dêem novas oportunidades.
Adição do tradutor
Parece que ainda existe um truque que permite que você se livre da necessidade usando, por exemplo,
nth-child(3n)
para remover as margens corretas dos elementos Flex adjacentes à borda direita do contêiner e até mesmo corrigindo cada vez que o número de colunas no Flex- muda recipiente.
Obviamente, também não é perfeito e é o seguinte:
- Na marcação HTML, envolva o contêiner Flex em uma tag de invólucro opcional
- Para crianças, por exemplo, em vez de
margin-right: 10px
, defina margin-left: 10px
- E para compensar o crescente recuo esquerdo, é necessário definir uma propriedade para o contêiner Flex com um valor negativo de
margin-left: -10px;
O resultado pode ser visualizado no
CodePen