Grid et Flexbox, le duo gagnant
CSS Grid et Flexbox sont faits pour fonctionner ensemble. Grid pour l'organisation générale, Flexbox pour les ajustements spécifiques. Chen Hui Jing le démontre avec un exemple magistral (et quelques bonus).
Plongée profonde dans CSS Grid
Vous vous rappelez la réponse de Rachel Andrew à la question "utiliser CSS Grid ou Flexbox" ? Sinon vous pouvez regarder la vidéo (en anglais).
Flexbox est fait pour les layouts unidimensionnels, CSS Grid est fait pour les layouts en 2 dimensions
Je suis sûre que beaucoup l'ont réalisé avant moi, mais avant ma relation torride d'un mois avec CSS Grid je ne m'étais pas rendue compte à quel point Flexbox et Grid sont faits pour s'entendre. C'était quelque chose du genre oeufs et bacon, pomme et cannelle, beurre de cacahuète et confiture — ah ça y est, j'ai faim tout d'un coup.
Vous avez peut-être vu que j'ai apporté une contribution au CSS Reference de Codrops. Sérieux, c'est une des meilleures choses qui me soit arrivées en 2016. Une des entrées qui manquaient encore était CSS Grid. Avant de m'y mettre, j'avais juste bricolé un peu avec Grid en construisant un prototype pour Penang Hokkien utilisant Grid, histoire de voir si le mode vertical fonctionnerait mieux qu'avec Flexbox.
Et puis je me suis attelée au boulot et j'ai écrit l'article.
3 semaines plus tard, j'avais l'impression d'avoir fusionné avec Metal Cactuar puissance maximum (désolé, Final Fantasy fait partie de ma vie), autrement dit j'étais passé au niveau supérieur.
J'ai passé beaucoup de temps à éplucher la spécification, la lecture des articles de Manuel Rego Casasnovas sur CSS Grid m'a beaucoup aidé ainsi que l'antisèche de Rachel Andrew à un moment de grande confusion.
Un conseil : quand vous essayez d'apprendre une nouvelle propriété CSS, ayez toujours sous la main un template vide avec lequel vous pourrez expérimenter. Ça m'a vraiment été utile avec une propriété aussi nouvelle que Grid. Je sais, il y a aussi Codepen et tout, mais rien ne vaut un template vierge pour une expérimentation libre de toute distraction.
Exemples et démos
Pour analyser toutes les propriétés, j'ai commencé à construire des grilles très basiques, juste pour voir le fonctionnement des valeurs de propriétés. Si vous avez regardé la syntaxe de grid-template-rows
dans la spécification, vous savez que ce n'était pas une tâche triviale. Grid lui-même n'est compliqué à apprendre. Mais comme il a été conçu pour être flexible et puissant, il vous faudra un peu de temps pour rentrer dans son fonctionnement.
Quelques-unes des grilles basiques se sont transformées en démos. Certaines trouvaient leur inspiration dans des conversations avec des membres du CSS Layout Club. J'ai aussi glané quelques idées dans le cours de Coursera Ideas from the History of Graphic Design, il y a plein de belles choses (la semaine dernière était consacrée au Bauhaus).
Je suis tombée sur cette page de Malerei, Fotografie, Film par László Moholy-Nagy, dont la mise en page utilisait une grille originale et l'idée m'est venue qu'on pouvait peut-être la réaliser en CSS...
Le Bauhaus dans mon navigateur
Voici comment j'ai procédé. J'ai dessiné les lignes de la grille par-dessus l'image en utilisant Sketch, de façon à me faire une idée du nombre de colonnes nécessaires. Dans cet exemple, c'était 1 large colonne suivie de 5 colonnes plus étroites de largeur égale, et j'ai laissé ensuite le navigateur se débrouiller avec la hauteur des rangées.
.grid {
display: grid;
grid-template-columns: 30% 9% 9% 9% 9% 9%;
justify-content: center; /* pour justifier la grille au centre du container */
}
Ensuite, il y a eu tout le code de placement avec les propriétés grid-row
et grid-column
. Mais si vous regardez à nouveau l'image originale, vous verrez que le contenu de chaque cellule a son propre alignement. Par exemple, celui de la première cellule est à droite, celui de la deuxième est en bas à gauche, etc.
👉🏿 NdT : pour consulter les définitions et utilisation des propriétés, voyez l'article CSS Grid Layout, guide complet).
Mon premier réflexe, vu que j'avais cet alignement de boîtes, a été d'appliquer justify-self
et align-self
là où c'était nécessaire, pour ajuster les positions de contenu à l'intérieur de chaque cellule. Bien tenté, mais à côté... Le problème est que ces deux propriétés affectent la quantité d'espace occupée par la cellule.
Le design du Bauhaus présente des bordures noires très frappantes autour de chaque cellule. La propriété border
s'applique à l'item de grille. Toute propriété d'alignement de grille autre que stretch
adaptera la dimension de l'item grid à son contenu. Toute bordure appliquée à un item grid s'adaptera au contenu de l'item, par conséquent je ne pouvais pas procéder ainsi.
Flexbox à la rescousse
Par défaut, tous les items grid se comportent comme si leur alignement avait été réglé sur stretch
sur chaque axe. J'ai donc laissé tomber, pour permettre à la grille de ressembler à une grille, et à la place, j'ai appliqué display: flex
à l'item grid, ce qui m'a permis d'utiliser les propriétés d'alignement flex sur le container flex, pour positionner le contenu de mon item grid.
.grid__item:nth-child(5) {
grid-row: 3 / 5;
border-right: 1em solid;
padding: 1em;
display: flex;
align-items: flex-start;
justify-content: flex-end;
}
Le code ressemble à ce qui précède, mais ce que je veux souligner avant tout c'est qu'il s'agit d'une formidable technique pour la mise en page. Grid pour l'organisation générale, et Flexbox pour les ajustements spécifiques. Voici ce que ça donne sur Codepen si vous voulez voir le résultat final.
Bonus : réaliser des formes en CSS
À part les deux photos, tout ce qui est sur la page est réalisé en CSS, autrement dit la flèche et la roue dentée sont des div
auxquelles j'ai appliqué des styles. J'aime faire des formes en CSS, avec une div
unique si possible. Il suffit pour cela de quelques propriétés pratiques, box-shadow
, border
et les pseudo-éléments.
La flèche
Les flèches sont assez simples à réaliser. Il vous faut juste un pseudo-élément pour la pointe. Le corps de la flèche est une simple div
à laquelle on donne une position: relative
de façon à positionner la pointe par rapport au corps. La pointe est un triangle, qu'on peut réaliser grâce à l'astuce de la bordure.
.arrow {
width: 0.5em;
height: 65%;
background-color: #000;
position: relative;
&::after {
display: block;
content: '';
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: -1em;
border-style: solid;
border-width: 1em 1em 0 1em;
border-color: #000 transparent transparent transparent;
}
}
La roue dentée
Là, c'est un peu plus compliqué. Le corps de la roue est un cercle, réalisé via border-radius: 50%
, mais les dents vont nous demander un peu de travail. Je n'ai pas pu le faire avec une seule div
cette fois-ci (mais si quelqu'un y arrive, contactez-moi). J'ai ajouté une div
interne. La bonne nouvelle c'est que toutes les dents ont une forme identique, donc l'astuce box-shadow
peut être utilisée ici.
.gear {
height: 5em;
width: 5em;
background-color: #000;
border-radius: 50%;
position: relative;
&::before,
&::after {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
content: '';
}
&::before {
height: 3em;
width: 1em;
box-shadow: 0em -3em 0em 0em #000, 0em 3em 0 0em #000;
}
&::after {
height: 1em;
width: 3em;
box-shadow: 3em 0 0em 0em #000, -3em 0 0 0em #000;
}
}
Le corps de la roue et les 4 dents directionnées comme les aiguilles d'une boussole ont été réalisées avec une seule div
et 2 pseudo-éléments. Pour les 4 autres dents, j'ai utilisé la div
intérieure avec des pseudo-éléments et fait tourner les box-shadow
. Je dois toujours résoudre le problème de transform-origin
car je trouve qu'il y a encore une certaine asymétrie.
.inner-gear {
height: 2em;
width: 2em;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #e1e1d5;
&::before,
&::after {
position: absolute;
display: block;
content: '';
}
&::before {
height: 3em;
width: 1em;
box-shadow: 0em -3em 0em 0em #000, 0em 3em 0 0em #000;
transform: rotate(45deg);
transform-origin: (75% 75%);
}
&::after {
height: 1em;
width: 3em;
box-shadow: 3em 0 0em 0em #000, -3em 0 0 0em #000;
transform: rotate(45deg);
transform-origin: (25% 75%);
}
}
Conclusion
CSS Grid est vraiment génial, et nous sommes nombreux à le penser. Jen Simmons a compilé une liste de bonnes ressources Grid, faites un tour sur Learn CSS Grid et essayez de construire quelque chose avec Grid. Vous ne le regretterez pas !