Je vous propose de découvrir ensemble le nouveau système de grille en CSS (display:grid;
). Cette nouvelle disposition va permettre de définir une grille qui sera ensuite utilisée pour placer les éléments enfants.
Quelques liens utiles
- Documentation MDN Web docs
- Grid Garden, pratiquez les grilles en arrosant des plantes
- CSS Grid Playground (en)
- Support des navigateurs
Le principe
Prenons le code HTML suivant
<!-- .grid>div*9>lorem -->
<div class="grid">
<div>lorem</div>
<div>lorem</div>
<div>lorem</div>
<div>lorem</div>
</div>
Pour commencer à utiliser les grilles il faut commencer par définir un display:grid
sur notre élément parent et de définir ensuite la taille des colonnes / lignes :
.grid {
display: grid;
grid-template-colums: 10% 80% 10%;
grid-template-rows: 100px 200px;
/*
Ou en racourci
grid-template: 10% 80% 10% / 100px 200px;
*/
}
Nous avons ici déclaré 3 colonnes et 2 lignes. Les éléments enfants de notre élément .grid
vont alors se placer de manière automatique au sein de la grille que l'on vient de créer. Le quatrième élément se placera automatiquement à la ligne suivante, et de nouvelles lignes seront créées si nécessaire. Il est important de noter que par défaut les éléments vont s'étendre pour occuper l'ensemble de l'espace disponible dans chaque cases (ils prendront ici une hauteur de 100 pixels ou de 200 pixels suivant la ligne qu'ils occupent).
Il est aussi possible de spécifier des "goutières" pour espacer nos différentes lignes / colonnes :
.grid {
/* ... */
grid-column-gap: 10px;
grid-row-gap: 20px;
/*
Ou en racourci
grid-gap: 20px 10px;
*/
}
L'utilisation de ces gouttières va entraîner un problème de débordement dans notre cas. L'espace des gouttières va s'ajouter aux tailles spécifiées des colonnes (10% + 20px + 80% + 20px + 10% = 100% + 40px). Pour remédier à ce genre de problématiques, nous avons la possibilité d'utiliser une nouvelle unité de mesure : le fr.
Cette unité de mesure permet de préciser que la colonne/ligne va occuper une portion de l'espace disponible. Si plusieurs colonnes ou plusieurs lignes utilisent cette unité de mesure, l'espace disponible sera fractionné et réparti entre les différents cases.
On peut donc réécrire notre première règle de la manière suivante :
.grid {
display: grid;
grid-template-rows: 1fr 8fr 1fr;
grid-gap: 20px 10px;
}
Cette unité de mesure permet donc de s'assurer que l'ensemble de l'espace disponible sera occupé par nos différentes colonnes.
Comment placer les enfants ?
Une fois cette grille définie, il va être possible de spécifier le placement des éléments enfants au sein de notre grille. Pour cela, on a un ensemble de propriétés qui vont permettre de piloter la colonne de départ et de fin ainsi que la ligne de départ et de fin :
.grid-item {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: span 2; /* L'élément s'étend sur 2 lignes */
/* racourci
grid-column: 1 / 3;
grid-row: 2 / span 1
*/
}
Il est important de noter que les éléments peuvent se chevaucher et vous pouvez ainsi avoir plusieurs éléments qui occupent la même case au sein de votre grille. En revanche, les éléments qui n'ont pas de propriétés grid-column
et grid-row
vont automatiquement occuper les espaces restants. Il est possible de piloter l'algorithme utilisé pour placer ces éléments grâce à la propriété grid-auto-flow
.
row
, L'algorithme va essayer de remplir chaque ligne avant de passer à la ligne suivantecolumn
, L'algorithme va essayer de remplir chaque colonne avant de passer à la colonne suivantedense
, L'algorithme va essayer de remplir les cases disponibles automatiquement (attention, cela peut se traduire par un changement d'ordre de vos éléments)
grid-template-areas
Une fonctionnalité intéressante du système de grille est la possibilité de nommer les différentes cases qui la composent. Ceci permettra ensuite de placer les éléments dans ses différentes cases et de pouvoir changer la disposition à volonté depuis l'élément parent. Chose qui peut s'avérer utile pour gérer le responsive par exemple.
Pour nommer nos différentes cases il faudra utiliser la propriété grid-template-area
.
.grid {
grid-template-columns: repeat(4, 50px);
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}
.header {
grid-area: header;
}
.body {
grid-area: main;
}
.sidebar {
grid-area: sidebar;
}
.footer {
grid-area: footer;
}