Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Grille CSS et formes personnalisées, partie 1

Dans un article précédent, j'ai examiné la capacité de CSS Grid à créer des mises en page complexes en utilisant ses pouvoirs de placement automatique. Je suis allé plus loin dans un autre article qui ajout d'un effet de survol de zoom aux images dans une disposition en grille. Cette fois, je veux plonger dans un autre type de grille, celle qui travaille avec des formes.

Par exemple, que se passe-t-il si les images ne sont pas parfaitement carrées mais ont plutôt la forme d'hexagones ou de losanges ? Alerte spoiler : nous pouvons le faire. En fait, nous allons combiner les techniques de grille CSS que nous avons examinées et ajouter du CSS clip-path ainsi que mask magie pour créer des grilles d'images fantaisistes pour à peu près toutes les formes que vous pouvez imaginer !

Commençons par un peu de balisage

La plupart des mises en page que nous allons examiner peuvent sembler faciles à réaliser à première vue, mais le défi consiste à les réaliser avec le même balisage HTML. Nous pouvons utiliser beaucoup d'emballages, divs, et ainsi de suite, mais le but de cet article est d'utiliser la même et la plus petite quantité de code HTML et d'obtenir toujours toutes les différentes grilles que nous voulons. Après tout, qu'est-ce que CSS sinon un moyen de séparer le style et le balisage ? Notre style ne doit pas dépendre du balisage, et vice versa.

Ceci dit, commençons par ceci :

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

Un conteneur avec des images est tout ce dont nous avons besoin ici. Rien de plus!

Grille CSS d'hexagones

Ceci est aussi parfois appelé une grille "en nid d'abeille".

Il existe déjà de nombreux autres articles de blog qui montrent comment faire cela. Merde, je écrit un ici sur CSS-Tricks ! Cet article est toujours bon et va très loin dans la création d'une mise en page réactive. Mais pour ce cas précis, nous allons nous appuyer sur une approche CSS beaucoup plus simple.

D'abord, utilisons clip-path sur les images pour créer la forme hexagonale et nous les plaçons toutes dans la même zone de grille afin qu'elles se chevauchent.

.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%)

Rien d'extraordinaire pour le moment. Toutes les images sont des hexagones et les unes au-dessus des autres. Il semble donc que tout ce que nous ayons est un seul élément d'image en forme d'hexagone, mais il y en a vraiment sept.

L'étape suivante consiste à appliquer une translation aux images pour les placer correctement sur la grille.

Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Grille CSS et formes personnalisées, partie 1

Notez que nous voulons toujours qu'une des images reste au centre. Le reste est placé autour d'elle en utilisant CSS translate et la bonne géométrie à l'ancienne. Voici les formules fictives que j'ai trouvées pour chaque image de la grille :

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))

Quelques calculs et optimisations plus tard (passons cette partie ennuyeuse, n'est-ce pas ?), nous obtenons le CSS suivant :

.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)); }

Ce sera peut-être plus facile quand nous aurons fonctions de trigonométrie réelles en CSS!

Chaque image est traduite par le --_x ainsi que --_y variables basées sur ces formules. Seule la deuxième image (nth-child(2)) n'est défini dans aucun sélecteur car c'est celui du centre. Il peut s'agir de n'importe quelle image si vous décidez d'utiliser un ordre différent. Voici la commande que j'utilise :

Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Grille CSS et formes personnalisées, partie 1

Avec seulement quelques lignes de code, nous obtenons une grille d'images sympa. À cela, j'ai ajouté un petit effet de survol aux images pour rendre les choses plus fantaisistes.

Devinez quoi? Nous pouvons obtenir une autre grille hexagonale en mettant simplement à jour quelques valeurs.

Si vous vérifiez le code et le comparez avec le précédent, vous remarquerez que j'ai simplement échangé les valeurs à l'intérieur clip-path et j'ai basculé entre --x ainsi que --y. C'est tout!

Grille CSS de losanges

Rhombus est un mot tellement fantaisiste pour un carré qui a pivoté de 45 degrés.

Même HTML, tu te souviens ? On commence d'abord par définir une grille 2×2 d'images en 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;
}

La première chose qui pourrait attirer votre attention est la grid propriété. C'est assez peu utilisé mais c'est super utile car c'est un raccourci qui vous permet de définir une grille complète dans une seule déclaration. Ce n'est pas la propriété la plus intuitive et la plus lisible, mais nous sommes ici pour apprendre ainsi que découvrez de nouvelles choses, alors utilisons-le plutôt que d'écrire toutes les propriétés individuelles de la grille.

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);

Ceci définit deux colonnes égales à la --s variable et définit la hauteur de toutes les lignes à --s aussi. Puisque nous avons quatre images, nous obtiendrons automatiquement une grille 2×2.

Voici une autre façon dont nous aurions pu l'écrire :

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

…qui peut être réduite avec le grid sténographie:

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

Après avoir défini la grille, nous la faisons pivoter ainsi que les images avec CSS transforms et on obtient ceci :

Notez comment je les fais pivoter tous les deux en 45deg, mais en sens inverse.

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

La rotation des images dans le sens négatif les empêche de tourner avec la grille afin qu'elles restent droites. Maintenant, on applique un clip-path pour en découper une forme de losange.

Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)

Nous avons presque fini! Nous devons rectifier la taille de l'image pour les faire s'emboîter. Sinon, ils sont espacés au point où cela ne ressemble pas à une grille d'images.

Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Grille CSS et formes personnalisées, partie 1

L'image se trouve dans les limites du cercle vert, qui est le cercle inscrit de la zone de grille où l'image est placée. Ce que nous voulons, c'est agrandir l'image pour qu'elle rentre dans le cercle rouge, qui est le cercle circonscrit de la zone de la grille.

Ne vous inquiétez pas, je n'introduirai plus de géométrie ennuyeuse. Tout ce que vous devez savoir, c'est que la relation entre le rayon de chaque cercle est la racine carrée de 2 (sqrt(2)). C'est la valeur dont nous avons besoin pour augmenter la taille de nos images afin de remplir la zone. Nous utiliserons 100%*sqrt(2) = 141% et soyez fait!

.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%);
}

Comme la grille hexagonale, nous pouvons rendre les choses plus fantaisistes avec ce bel effet de survol de zoom :

Grille CSS de formes triangulaires

Vous savez probablement maintenant que le gros truc est de comprendre le clip-path pour obtenir les formes souhaitées. Pour cette grille, chaque élément a son propre clip-path alors que les deux dernières grilles fonctionnaient avec une forme cohérente. Donc, cette fois-ci, c'est comme si nous travaillions avec quelques formes triangulaires différentes qui se réunissent pour former une grille rectangulaire d'images.

Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Les trois images en haut
Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Les trois images en bas

Nous les plaçons dans une grille 3×2 avec le CSS suivant :

.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%); } }

Voici ce que nous obtenons :

La touche finale consiste à rendre la largeur de la colonne du milieu égale 0 pour supprimer les espaces entre les images. Le même genre de problème d'espacement que nous avons eu avec la grille en losange, mais avec une approche différente pour les formes que nous utilisons :

grid-template-columns: auto 0 auto;

J'ai dû jouer avec le clip-path valeurs pour s'assurer qu'elles semblent toutes bien s'emboîter comme un puzzle. Les images d'origine se chevauchent lorsque la colonne du milieu a une largeur nulle, mais après avoir découpé les images, l'illusion est parfaite :

Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Grille CSS et formes personnalisées, partie 1

Grille de tarte à pizza CSS

Devinez quoi? Nous pouvons obtenir une autre grille sympa en ajoutant simplement border-radius ainsi que overflow à nos grilles ou formes triangulaires. 🎉

Grille CSS de pièces de puzzle

Cette fois, nous allons jouer avec le CSS mask propriété de faire en sorte que les images ressemblent aux pièces d'un puzzle.

Si vous n'avez pas utilisé mask comprenant Dégradés CSS, Je recommande fortement cet autre article J'ai écrit sur le sujet parce que ça va aider avec ce qui vient ensuite. Pourquoi les dégradés ? Parce que c'est ce que nous utilisons pour obtenir les encoches rondes dans les formes des pièces du puzzle.

La mise en place de la grille devrait être un jeu d'enfant maintenant, alors concentrons-nous plutôt sur le mask partie.

Comme illustré dans la démonstration ci-dessus, nous avons besoin de deux dégradés pour créer la forme finale. Un dégradé crée un cercle (la partie verte) et l'autre crée la courbe droite tout en remplissant la partie supérieure.

--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;

Deux variables contrôlent la forme. Le --g variable n'est rien d'autre que l'écart de grille. Nous devons tenir compte de l'écart pour placer correctement nos cercles afin qu'ils se chevauchent parfaitement lorsque l'ensemble du puzzle est assemblé. Le --r La variable contrôle la taille des parties circulaires de la forme du puzzle.

Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Grille CSS et formes personnalisées, partie 1

Maintenant, nous prenons le même CSS et mettons à jour quelques valeurs pour créer les trois autres formes :

Nous avons les formes, mais pas les bords qui se chevauchent dont nous avons besoin pour les faire s'emboîter. Chaque image est limitée à la cellule de la grille dans laquelle elle se trouve, il est donc logique que les formes soient en quelque sorte mélangées pour le moment :

Grille CSS et formes personnalisées, partie 1 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Grille CSS et formes personnalisées, partie 1

Nous devons créer un débordement en augmentant la hauteur/largeur des images. À partir de la figure ci-dessus, nous devons augmenter la hauteur des première et quatrième images tandis que nous augmentons la largeur des deuxième et troisième. Vous avez probablement déjà deviné que nous devons les augmenter en utilisant le --r variable.

.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));
}

Nous nous rapprochons !

Nous avons créé le chevauchement mais, par défaut, nos images se chevauchent soit à droite (si nous augmentons la largeur) soit en bas (si nous augmentons la hauteur). Mais ce n'est pas ce que nous voulons pour les deuxième et quatrième images. La solution consiste à utiliser place-self: end sur ces deux images et notre code complet devient ceci :

Voici un autre exemple où j'utilise un dégradé conique au lieu d'un dégradé radial. Cela nous donne des pièces de puzzle triangulaires tout en conservant les mêmes HTML et CSS sous-jacents.

Un dernier ! Cette fois j'utilise clip-path et comme il s'agit d'une propriété que nous pouvons animer, nous obtenons un survol sympa en mettant simplement à jour la propriété personnalisée qui contrôle la forme.

Emballage en place

C'est tout pour cette première partie ! En combinant les choses que nous avons déjà apprises sur CSS Grid avec quelques éléments supplémentaires clip-path ainsi que mask magie, nous avons pu faire des mises en page de grille comportant différents types de formes. Et nous avons utilisé le même balisage HTML à chaque fois ! Et le balisage lui-même n'est rien de plus qu'un conteneur avec une poignée d'éléments d'image !

Dans la deuxième partie, nous allons explorer des grilles plus complexes avec des formes plus fantaisistes et des effets de survol.

Je prévois de faire la démonstration des panneaux d'image agrandis que nous avons créés ensemble dans cet autre article:

…et transformez-le en panneaux d'images en zigzag ! Et ce n'est qu'un exemple parmi tant d'autres que nous découvrirons dans le prochain article.

Horodatage:

Plus de Astuces CSS