Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Grade CSS e formas personalizadas, parte 1

Em um artigo anterior, analisei a capacidade do CSS Grid de crie layouts complexos usando seus poderes de posicionamento automático. Eu dei um passo adiante em outro artigo que adicionou um efeito de foco de zoom às imagens em um layout de grade. Desta vez, quero mergulhar em outro tipo de grade, que trabalha com formas.

Tipo, e se as imagens não forem perfeitamente quadradas, mas tiverem a forma de hexágonos ou losangos? Alerta de spoiler: nós podemos fazer isso. Na verdade, vamos combinar técnicas de CSS Grid que vimos e colocar algumas CSS clip-path e mask mágica para criar grades de imagens extravagantes para praticamente qualquer forma que você possa imaginar!

Vamos começar com alguma marcação

A maioria dos layouts que veremos podem parecer fáceis de alcançar à primeira vista, mas a parte desafiadora é alcançá-los com a mesma marcação HTML. Podemos usar muitos invólucros, divs e outros enfeites, mas o objetivo deste post é usar a mesma e menor quantidade de código HTML e ainda obter todas as grades diferentes que queremos. Afinal, o que é CSS senão uma maneira de separar estilo e marcação? Nosso estilo não deve depender da marcação e vice-versa.

Dito isso, vamos começar com isso:

<div class="gallery">
  <img src="..." alt="...">
  <img src="..." alt="...">
  <img src="..." alt="...">
  <img src="..." alt="...">
  <!-- as many times as we want -->
</div>

Um container com imagens é tudo o que precisamos aqui. Nada mais!

Grade CSS de Hexágonos

Isso também é às vezes chamado de grade “favo de mel”.

Já existem muitos outros posts por aí que mostram como fazer isso. Caramba, eu escreveu um aqui em CSS-Tricks! Esse artigo ainda é bom e vai muito fundo na criação de um layout responsivo. Mas para este caso específico, vamos contar com uma abordagem CSS muito mais simples.

Primeiro, vamos usar clip-path nas imagens para criar a forma hexagonal e colocamos todas elas na mesma área de grade para que se sobreponham.

.gallery {
  --s: 150px; /* controls the size */
  display: grid;
}

.gallery > img {
  grid-area: 1/1;
  width: var(--s);
  aspect-ratio: 1.15;
  object-fit: cover;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0 50%)

Nada extravagante ainda. Todas as imagens são hexágonos e acima umas das outras. Parece que tudo o que temos é um único elemento de imagem em forma de hexágono, mas na verdade são sete.

O próximo passo é aplicar uma tradução às imagens para colocá-las corretamente na grade.

Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
Grade CSS e formas personalizadas, parte 1

Observe que ainda queremos que uma das imagens permaneça no centro. O resto é colocado em torno dele usando CSS translate e a boa e velha geometria. Aqui estão as fórmulas simuladas que criei para cada imagem na grade:

translate((height + gap)*sin(0deg), (height + gap)*cos(0))
translate((height + gap)*sin(60deg), (height + gap)*cos(60deg))
translate((height + gap)*sin(120deg), (height + gap)*cos(120deg))
translate((height + gap)*sin(180deg), (height + gap)*cos(180deg))
translate((height + gap)*sin(240deg), (height + gap)*cos(240deg))
translate((height + gap)*sin(300deg), (height + gap)*cos(300deg))

Alguns cálculos e otimizações depois (vamos pular essa parte chata, certo?) obtemos o seguinte CSS:

.gallery {
  --s: 150px; /* control the size */
  --g: 10px;  /* control the gap */
  display: grid;
}
.gallery > img {
  grid-area: 1/1;
  width: var(--s);
  aspect-ratio: 1.15;
  object-fit: cover;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50% ,75% 100%, 25% 100%, 0 50%);
  transform: translate(var(--_x,0), var(--_y,0));
}
.gallery > img:nth-child(1) { --_y: calc(-100% - var(--g)); }
.gallery > img:nth-child(7) { --_y: calc( 100% + var(--g)); }
.gallery > img:nth-child(3),
.gallery > img:nth-child(5) { --_x: calc(-75% - .87*var(--g)); }
.gallery > img:nth-child(4),
.gallery > img:nth-child(6) { --_x: calc( 75% + .87*var(--g)); }
.gallery > img:nth-child(3),
.gallery > img:nth-child(4) { --_y: calc(-50% - .5*var(--g)); }
.gallery > img:nth-child(5), 
.gallery > img:nth-child(6) { --_y: calc( 50% + .5*var(--g)); }

Talvez seja mais fácil quando chegarmos funções reais de trigonometria em CSS!

Cada imagem é traduzida pelo --_x e --_y variáveis ​​que se baseiam nessas fórmulas. Apenas a segunda imagem (nth-child(2)) é indefinido em qualquer seletor porque está no centro. Pode ser qualquer imagem se você decidir usar uma ordem diferente. Aqui está a ordem que estou usando:

Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
Grade CSS e formas personalizadas, parte 1

Com apenas algumas linhas de código, obtemos uma grade legal de imagens. Para isso, adicionei um pequeno efeito de foco nas imagens para tornar as coisas mais sofisticadas.

Adivinha? Podemos obter outra grade hexagonal simplesmente atualizando alguns valores.

Se você verificar o código e compará-lo com o anterior, você notará que eu simplesmente troquei os valores dentro clip-path e eu mudei entre --x e --y. Isso é tudo!

Grade CSS de losangos

Losango é uma palavra tão chique para um quadrado que é girado 45 graus.

Mesmo HTML, lembra? Primeiro começamos definindo uma grade 2×2 de imagens em CSS:

.gallery {
  --s: 150px; /* controls the size */

  display: grid;
  gap: 10px;
  grid: auto-flow var(--s) / repeat(2, var(--s));
  place-items: center;
}
.gallery > img {
  width: 100%; 
  aspect-ratio: 1;
  object-fit: cover;
}

A primeira coisa que pode chamar sua atenção é o grid propriedade. É pouco usado, mas é super útil, pois é uma abreviação que permite definir uma grade completa em uma declaração. Não é a propriedade mais intuitiva - e para não mencionar legível -, mas estamos aqui para aprender e descobrir coisas novas, então vamos usá-lo em vez de escrever todas as propriedades individuais da grade.

grid: auto-flow var(--s) / repeat(2,var(--s));

/* is equivalent to this: */
grid-template-columns: repeat(2, var(--s));
grid-auto-rows: var(--s);

Isso define duas colunas iguais ao --s variável e define a altura de todas as linhas para --s também. Como temos quatro imagens, obteremos automaticamente uma grade 2×2.

Aqui está outra maneira que poderíamos ter escrito:

grid-template-columns: repeat(2, var(--s));
grid-template-rows: repeat(2, var(--s));

…que pode ser reduzido com o grid forma abreviada:

grid: repeat(2,var(--s)) / repeat(2,var(--s));

Depois de definir a grade, giramos ela e as imagens com CSS transforms e obtemos isso:

Observe como eu giro os dois por 45deg, mas na direção oposta.

.gallery {
  /* etc. */
  transform: rotate(45deg);
}
.gallery > img {
  /* etc. */
  transform: rotate(-45deg);
}

Girar as imagens na direção negativa evita que elas sejam giradas com a grade para que fiquem retas. Agora, aplicamos um clip-path para cortar uma forma de losango deles.

Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)

Estamos quase terminando! Precisamos retificar o tamanho da imagem para que se encaixem. Caso contrário, eles são espaçados a ponto de não parecer uma grade de imagens.

Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
Grade CSS e formas personalizadas, parte 1

A imagem está dentro do limite do círculo verde, que é o círculo inscrito da área da grade onde a imagem é colocada. O que queremos é tornar a imagem maior para caber dentro do círculo vermelho, que é o círculo circunscrito da área da grade.

Não se preocupe, não vou introduzir mais geometria chata. Tudo que você precisa saber é que a relação entre o raio de cada círculo é a raiz quadrada de 2 (sqrt(2)). Este é o valor que precisamos para aumentar o tamanho de nossas imagens para preencher a área. Nós vamos usar 100%*sqrt(2) = 141% e pronto!

.gallery {
  --s: 150px; /* control the size */

  display: grid;
  grid: auto-flow var(--s) / repeat(2,var(--s));
  gap: 10px;
  place-items: center;
  transform: rotate(45deg);
}
.gallery > img {
  width: 141%; /* 100%*sqrt(2) = 141% */
  aspect-ratio: 1;
  object-fit: cover;
  transform: rotate(-45deg);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}

Assim como a grade hexagonal, podemos tornar as coisas mais sofisticadas com esse belo efeito de zoom de foco:

Grade CSS de Formas Triangulares

Você provavelmente já sabe que o grande truque é descobrir o clip-path para obter as formas que queremos. Para esta grade, cada elemento tem seu próprio clip-path valor enquanto as duas últimas grades trabalharam com uma forma consistente. Então, desta vez, é como se estivéssemos trabalhando com algumas formas triangulares diferentes que se juntam para formar uma grade retangular de imagens.

Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
As três imagens no topo
Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
As três imagens na parte inferior

Nós os colocamos dentro de uma grade 3×2 com o seguinte CSS:

.gallery {
  display: grid;
  gap: 10px; 
  grid-template-columns: auto auto auto; /* 3 columns */
  place-items: center;
}
.gallery > img {
  width: 200px; /* controls the size */
  aspect-ratio: 1;
  object-fit: cover;
}
/* the clip-path values */
.gallery > img:nth-child(1) { clip-path: polygon(0 0, 50% 0, 100% 100% ,0 100%); }
.gallery > img:nth-child(2) { clip-path: polygon(0 0, 100% 0, 50% 100%); }
.gallery > img:nth-child(3) { clip-path: polygon(50% 0, 100% 0, 100% 100%, 0 100%); }
.gallery > img:nth-child(4) { clip-path: polygon(0 0, 100% 0, 50% 100%, 0 100%); }
.gallery > img:nth-child(5) { clip-path: polygon(50% 0, 100% 100%, 0% 100%); }
.gallery > img:nth-child(6) { clip-path: polygon(0 0, 100% 0 ,100% 100%, 50% 100%); } }

Aqui está o que obtemos:

O toque final é igualar a largura da coluna do meio 0 para se livrar dos espaços entre as imagens. O mesmo tipo de problema de espaçamento que tivemos com a grade de losango, mas com uma abordagem diferente para as formas que estamos usando:

grid-template-columns: auto 0 auto;

Eu tive que mexer com o clip-path valores para garantir que todos pareçam se encaixar perfeitamente como um quebra-cabeça. As imagens originais se sobrepõem quando a coluna do meio tem largura zero, mas depois de fatiar as imagens, a ilusão é perfeita:

Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
Grade CSS e formas personalizadas, parte 1

Grade de pizza de pizza CSS

Adivinha? Podemos obter outra grade legal simplesmente adicionando border-radius e overflow à nossa grade ou formas triangulares. 🎉

Grade CSS de peças de quebra-cabeça

Desta vez vamos brincar com o CSS mask propriedade para fazer as imagens parecerem peças de um quebra-cabeça.

Se você não usou mask de Gradientes CSS, Eu recomendo fortemente este outro artigo Eu escrevi sobre o tema porque vai ajudar no que vem a seguir. Por que gradientes? Porque é isso que estamos usando para obter os entalhes redondos nas formas das peças do quebra-cabeça.

Configurar a grade deve ser fácil agora, então vamos nos concentrar no mask parte.

Conforme ilustrado na demonstração acima, precisamos de dois gradientes para criar a forma final. Um gradiente cria um círculo (a parte verde) e o outro cria a curva direita enquanto preenche a parte superior.

--g: 6px; /* controls the gap */
--r: 42px;  /* control the circular shapes */

background: 
  radial-gradient(var(--r) at left 50% bottom var(--r), green 95%, #0000),
  radial-gradient(calc(var(--r) + var(--g)) at calc(100% + var(--g)) 50%, #0000 95%, red)
  top/100% calc(100% - var(--r)) no-repeat;

Duas variáveis ​​controlam a forma. o --g variável nada mais é do que a lacuna da grade. Precisamos levar em conta a lacuna para posicionar corretamente nossos círculos para que eles se sobreponham perfeitamente quando todo o quebra-cabeça estiver montado. o --r variável controla o tamanho das partes circulares da forma do quebra-cabeça.

Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
Grade CSS e formas personalizadas, parte 1

Agora pegamos o mesmo CSS e atualizamos alguns valores nele para criar as outras três formas:

Temos as formas, mas não as bordas sobrepostas que precisamos para que se encaixem. Cada imagem é limitada à célula da grade em que está, então faz sentido porque as formas estão meio confusas no momento:

Grade CSS e formas personalizadas, parte 1 PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
Grade CSS e formas personalizadas, parte 1

Precisamos criar um estouro aumentando a altura/largura das imagens. A partir da figura acima, temos que aumentar a altura da primeira e quarta imagens enquanto aumentamos a largura da segunda e terceira. Você provavelmente já adivinhou que precisamos aumentá-los usando o --r variável.

.gallery > img:is(:nth-child(1),:nth-child(4)) {
  width: 100%;
  height: calc(100% + var(--r));
}
.gallery > img:is(:nth-child(2),:nth-child(3)) {
  height: 100%;
  width: calc(100% + var(--r));
}

Estamos nos aproximando!

Criamos a sobreposição, mas, por padrão, nossas imagens se sobrepõem à direita (se aumentarmos a largura) ou na parte inferior (se aumentarmos a altura). Mas não é isso que queremos para a segunda e quarta imagens. A correção é usar place-self: end nessas duas imagens e nosso código completo se torna este:

Aqui está outro exemplo em que estou usando um gradiente cônico em vez de um gradiente radial. Isso nos dá peças triangulares do quebra-cabeça, mantendo o mesmo HTML e CSS subjacentes.

Um último! Desta vez estou usando clip-path e como é uma propriedade que podemos animar, conseguimos um foco legal simplesmente atualizando a propriedade personalizada que controla a forma.

Resumindo

Isso é tudo para esta primeira parte! Combinando as coisas que já aprendemos sobre CSS Grid com algumas clip-path e mask mágica, conseguimos fazer layouts de grade com diferentes tipos de formas. E usamos a mesma marcação HTML todas as vezes! E a marcação em si nada mais é do que um contêiner com um punhado de elementos de imagem!

Na segunda parte, vamos explorar grades de aparência mais complexa com formas mais sofisticadas e efeitos de foco.

Estou planejando fazer a demonstração dos painéis de imagens em expansão que fizemos juntos em este outro artigo:

…e transformá-lo em painéis de imagens em zig-zag! E este é apenas um exemplo entre os muitos que descobriremos no próximo artigo.

Carimbo de hora:

Mais de Truques CSS