Flexbox et Grid Layout comptent parmi les spécifications qui ont le plus contribué à l'évolution des styles CSS durant ces dernières années. Véritables bénédictions pour l'intégrateur, ces deux approches ont littéralement révolutionné les modes de mise en page classiques et renvoyé les anciennes techniques bancales aux oubliettes.
Les premières ébauches de spécifications Flexbox datent de 2009, tandis que le premier brouillon officiel de Grid Layout est apparu en 2012. Bien que tous deux supportés simultanément dès la sortie d'Internet Explorer 10 en octobre 2012, l'adoption de Grid Layout en est encore à ses balbutiements en raison... d'Internet Explorer.
Quelles sont les raisons de ces réticences, et surtout, comment utiliser Grid Layout en production dès aujourd'hui ?
Une compatibilité acceptable...
À la mi-2018, les chiffres étaient déjà fort éloquents : 90% de support en France, et 88% dans le monde entier. La grande majorité des navigateurs de bureau et mobiles reconnaissent cette spécification depuis plusieurs versions comme le montre l'indispensable référence Can I Use.
Seuls absents à ce jour : Opera Mini (0.14% d'usage en France) et... Internet Explorer version 9 et inférieure (0.1% d'usage en France).
Sachez tout de même que des sites tels que Slate, Financial Times, Stripe, Slack, Medium et Yandex emploient Grid Layout en production : http://www.gridexamples.com/
Mais un support partiel d'Internet Explorer
Microsoft Edge 16, sorti en septembre 2017, reconnaît la dernière version de la spécification Grid dans son intégralité.
Par contre, les anciennes moutures d’Internet Explorer sont un peu plus à la traîne : IE10, IE11 et les premières éditions de Edge supportent officiellement Grid Layout mais se réfèrent à une antique version de la spécification qui est bien moins complète, et de nombreuses fonctionnalités y sont donc manquantes.
Une question de version
L'implémentation de Grid par les différentes version d’Internet Explorer est simple et compliquée à la fois :
- IE9 et inférieur : pas de support
- IE10, IE11, Edge 12-15 : ancienne spécification (support partiel)
- Edge 16+ : nouvelle spécification
Dans la suite de cet article, le terme "Internet Explorer" fait référence aux versions "IE10, IE11, Edge 12-15".
Le support partiel d'Internet Explorer s'explique par le fait que la spécification Grid Layout a évolué plus rapidement que lui, et se manifeste principalement par :
- Des fonctionnalités manquantes (qui n'existent tout simplement pas dans IE),
- Des fonctionnalités divergentes (qui s'écrivent différemment ou opèrent autrement sur IE que les autres),
- Des bugs (eh ouais !).
Fonctionnalités manquantes
Parmi les lacunes principales de ces versions, on dénombre le manque de support des certaines fonctionnalités majeures détaillées ci-après.
Pas de placement automatique
Première particularité notable dans l'intégration des grilles dans Internet Explorer : il n'y a pas de notion de Placement Automatique des éléments sur IE : Il faut placer chaque élément individuellement et explicitement dans chaque cellule.
Il en découle, fort logiquement qu'aucune des propriétés standards suivantes n'est reconnue par IE :
grid-auto-columns
grid-auto-rows
grid-auto-flow
grid
(propriété raccourcie globale)
Pas de gouttières
Ne craignez rien pour votre maison, les seules gouttières dont vous serez privés sur Internet Explorer sont celles permettant d'espacer les rangées et les colonnes de la grille.
Les propriétés grid-row-gap
, grid-column-gap
et grid-gap
(et leur équivalent plus récent gap
tout court) prévues pour gérer aisément les gouttières dans Grid Layout sont totalement absentes du vocabulaire d'IE et il ne s'y passera rien du tout s'il les croise au détour d'une ligne de code.
La seule manière de s'en sortir est de prévoir une colonne (ou rangée) supplémentaire qui fera office de gouttière :
.container {
display: -ms-grid; /* version IE */
display: grid;
grid-gap: 1rem;
-ms-grid-columns: 1fr 1rem 1fr; /* version IE */
grid-template-columns: 1fr 1fr;
}
Pas de zones nommées
Grid Layout propose une méthode alternative de construction : les zones et lignes nommées.
Les propriétés grid-template-areas
et grid-area
permettent de créer des zones nommées et de s'y placer... mais elles non plus ne sont pas supportées par Internet Explorer.
Ce genre de syntaxe sera donc inopérant sur IE :
.container {
display: grid;
grid-template-areas: "a b"
"c d";
}
.child {
grid-area: a;
}
Divers autres manquements
Pour finir, n'oublions pas qu'Internet Explorer ignore totalement :
- Les valeurs
auto-fit
etauto-fill
très pratiques pour construire des grilles automatiques, - Le mot-clé
dense
qui permet de remplir les cases laissées libres dans la grille.
Des fonctionnalités divergentes
Depuis leur version de brouillon (adoptée à l'époque par IE10 précipitamment), certaines propriétés ou valeurs ont muté... sans que Internet Explorer ne suive le wagon.
Des propriétés différentes... et préfixées
C'est un jeu auquel nous aurions aimé nous passer : il faut deviner quelles propriétés sont préfixées pour Internet Explorer et, surtout, pressentir quel est leur petit nom sur ce navigateur car il risque d'être différent du reste du monde.
Voici la liste des propriétés de grille reconnues sur IE mais sous un nom différent des standards :
propriété standard | équivalent IE |
---|---|
display: grid |
display: -ms-grid |
grid-template-columns |
-ms-grid-columns |
grid-template-rows |
-ms-grid-rows |
grid-row-start |
-ms-grid-row |
grid-column-start |
-ms-grid-column |
grid-row-end |
-ms-grid-row-span (plus ou moins équivalent) |
grid-column-end |
-ms-grid-column-span (plus ou moins équivalent) |
align-self |
-ms-grid-row-align |
justify-self |
-ms-grid-column-align |
Exemple de code CSS standard :
.container {
display: grid;
grid-template-rows: 20rem 100px 1fr;
grid-template-columns: 100px 1fr 10rem;
}
.child {
grid-column: 1 / 3;
}
Équivalent sur Internet Explorer :
.container {
display: -ms-grid;
-ms-grid-rows: 20rem 100px 1fr;
-ms-grid-columns: 100px 1fr 10rem;
}
.child {
-ms-grid-column: 1;
-ms-grid-column-span: 2;
}
Fort heureusement, l'outil autoprefixer évoqué en détail plus loin gère très bien ces propriétés sans que vous ayez à vous en soucier.
repeat()
Dans les premières spécifications, la valeur-fonction repeat()
est née sous une mouture totalement différente de ce que l'on connaît actuellement. Internet Explorer est là pour nous rappeler ce temps jadis.
valeur standard | équivalent IE |
---|---|
repeat(10, 1fr 2rem) |
(1fr 2em)[10] |
Il est donc parfaitement possible d'appliquer cette valeur pour répéter des motifs de pistes, mais en faisant bien attention de respecter la syntaxe particulière d'IE.
Des bugs
Ah ben forcément on ne pouvait pas y couper : Internet Explorer, tout comme les autres navigateurs, est parfois un peu buggué quand il s'agit de CSS, et plus particulièrement lorsqu'une spécification est récente. Il faut parfois attendre les mises à jour des navigateurs pour voir certains bugs se résorber ou disparaître.
Pour vous aider à patienter, Rachel Andrew, papesse de Grid Layout, a concocté un espace collaboratif sur Github nommé "Gridbugs" et qui compile un ensemble de bugs (et solutions) fréquents concernant Grid Layout : https://github.com/rachelandrew/gridbugs
N'hésitez pas une seconde à placer ce lien dans vos favoris.
Alors on fait quoi concrètement ?
Dans la pratique, nous disposons de trois solutions pour gérer les lacunes actuelles des navigateurs :
- notre cerveau,
- l'outil PostCSS Autoprefixer,
- la règle CSS @supports().
Je ne vais pas entrer dans le détail de la première option, mais plutôt m'intéresser aux deux suivantes.
Autoprefixer
Autoprefixer est un (superbe) outil permettant d’ajouter tous les préfixes CSS à vos propriétés de manière automatisée et, surtout, uniquement pour les navigateurs le nécessitant encore.
Par défaut, Grid Layout n’est pas activé sur Autoprefixer. Il faut l’activer dans les options en passant grid: false
à grid: true
.
Autre point important : la dernière version d'Autoprefixer a fait d'énormes progrès en matière de gestion des préfixes et fonctionnalités pour Internet Explorer (depuis la version version 8.6.4 précisément), il est dorénavant beaucoup plus fiable et vivement conseillé dans vos projets (pas que pour Grid Layout d'ailleurs).
Pour comprendre comment fonctionne le nouveau Autoprefixer dans les détails, je vous invite à consulter cette ressource anglophone très complète : https://css-tricks.com/css-grid-in-ie-css-grid-and-the-new-autoprefixer/
Ce qu'apporte Autoprefixer ?
Comme son nom l'indique, Autoprefixer ajoute automatiquement les préfixes (-webkit-
, -moz-
, -ms-
, etc.) lorsque cela est nécessaire sur une propriété ou sur une valeur.
Mais il va bien au-delà puisqu'il est capable de convertir totalement des propriétés pour les rendre compatibles.
Les propriétés suivantes, par exemple, n'ont pas d'équivalent dans Internet Explorer, mais elles sont reconnues grâce à Autoprefixer, qui les transforme en "syntaxe IE-friendly" :
grid-template-areas
grid-template
grid-row-end
grid-column-end
grid-row
grid-column
grid-area
grid-row-gap
grid-column-gap
grid-gap
Exemple de code standard :
.container {
display: grid;
grid-gap: 1em;
grid-template: "a b" minmax(100px, 1fr)
"c d" 20em / 1fr 1fr;
}
.child {
grid-area: a;
}
Converti grâce à Autoprefixer en :
.container {
display: -ms-grid;
display: grid;
grid-gap: 1em;
-ms-grid-rows: minmax(100px, 1fr) 1em 20em;
-ms-grid-columns: 1fr 1em 1fr;
grid-template: "a b" minmax(100px, 1fr)
"c d" 20em / 1fr 1fr;
}
.child {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: a;
}
Et hop, emballé c'est pesé ! Il devient bien plus simple de gérer le cas Internet Explorer grâce à ce genre d'outil.
Notez que grâce à Autoprefixer, rien de nous empêche désormais d'employer la méthode de placement via zones nommées (areas).
@supports ()
La règle @supports, également nommée “règle conditionnelle”, permet de détecter la reconnaissance de certaines propriétés CSS au sein du navigateur.
Introduite au sein des spécifications dans le module des CSS conditionnelles, au même titre que les Media Queries, la règle @supports
se rapproche de ce que peut nous offrir un outil tel que Modernizr, à savoir détecter le support ou non d’une fonctionnalité CSS chez votre visiteur afin de prévoir une alternative au besoin.
@supports
est reconnue depuis à partir de Microsoft Edge, il est donc totalement ignoré par IE11 et inférieurs.- le test
(display: grid)
n'est reconnu qu'à partir de Edge 16
@supports (display: grid) {
/* will return true for any browser supporting the spec, Edge included */
}
Cette syntaxe de @supports
nous permet de ne conserver que les navigateurs vraiment totalement compatibles avec les versions stables de Grid Layout, en excluant IE10, IE11 et Edge 15 qui ne reconnaissent que la version préfixée.
Quelles sont mes options ?
Pour finir, voyons quelles sont les options à ma disposition en regard de mes contraintes de compatibilité navigateurs.
Je suis libre ! (Edge minimum)
- on applique Grid Layout pour les navigateurs modernes uniquement (Edge+) via
@supports
- pas besoin d'Autoprefixer
Je dois absolument tenir compte d'IE10 et IE11
- on applique Grid Layout pour tous les navigateurs
- on active Autoprefixer pour pallier les lacunes d'IE
- on emploie des propriétés et des fonctionnalités capables d'être prises en compte par Autoprefixer et on fait attention où l'on met les doigts pour ne pas se faire pincer très fort.
Je dois absolument tenir compte d'IE9 (OMG!)
- il va falloir prévoir une alternative en positionnements ancestraux (
float
/inline-block
). Courage ! - on applique Grid Layout pour les navigateurs modernes uniquement (Edge) via la règle
@support
- pas besoin d'Autoprefixer mais on doit faire le double du boulot (deux versions de positionnements à maintenir)
Conclusion
Rien de tel qu'un petit exemple concret pour illustrer l'ensemble de cet article et conclure en beauté.
L'objectif à atteindre est de concevoir un gabarit de 3 éléments de largeur identique (1/3 de l'espace disponible) et séparés par une gouttière de 1em.
.container {
display: flex; /* 1 */
justify-content: space-between; /* 2 */
}
.container > * {
flex-basis: calc(100% / 3 - (1em * 2 / 3)); /* 3 + 4 */
}
@supports (display: grid) { /* 5 */
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 1em;
}
}
/*
Explications :
1- l'alternative est ici Flexbox (prévoir Autoprefixer pour les navigateurs nécessiteux)
2- on prévoit une "gouttière" de 1em
3- on calcule la taille des 3 enfants par rapport à la gouttière
4- on préfère flex-basis à width pour éviter de devoir écraser width dans Grid Layout
5- seuls les navigateurs modernes (Edge) se reconnaîtront ici
*/
Commentaires
Hello Raphaël !
Merci pour cet article. C'est top :)
Dans un autre article tu conseillais d'utiliser `@supports (grid-area: auto) {}` pour détecter les navigateurs modernes.
Finalement, on n'a plus besoin de cette astuce ?
Thomas.
@tzi : Hello :)
En fait c'était un bug de Codepen finalement : display: grid marche comme il faut (= pas reconnu sur edge <16, comme souhaité)
https://blog.goetter.fr/2017/08/26/une-histoire-de-grid-layout-de-microsoft-et-de-supports/#comment-650
Hello !
Super article. Merci. C’est fou ce qu’on peut apprendre grâce à ce site et particulièrement grâce à tes articles.
@Bidules : Merci beaucoup :)
Tenir compte d'IE et Edge, quelle hérésie !
Merci Raphaël pour ce récap très complet. Il est encore difficile de se passer d'IE qui encore utilisé sur les sites institutionnels ou par nos clients eux-mêmes. Perso, j'ai encore recours aux commentaires conditionnels malgré l'utilisation d'Autoprefixer.
J'utilise flexbox qui marche avec tout et qui fait pareil que grid sans s'emmerder avec les navigateurs
je ne comprend toujours pas pourquoi flexbox n'a pas de gap mais je remplace par une bordure blanche ou transparente
Grid n 'a pas des fonctions radicalement superieures a flexbox
j' utiliserais peut être Grid dans quelques années
merci pour le texte
@eckri: Grid est bi-dimensionnel alors que Flexbox est mono-dimensionnel. De plus Grid est orienté structure alors que Flexbox est orienté contenu. On peut tout à fait coupler les 2.
Bonjour, c'est peut être une question à la con, mais je la pose quand même.
Au final il n'est question que de la problématique des anciennes versions d'IE. Quid de Firefox et Chrome ?
Grid est implémenté par exemple à partir de la version 52 de Firefox.
Est-ce que la question n'est pas abordée car personne n'est censé être bloqué sur une vieille version de Firefox, ce dernier se mettant de toutes façons à jour sans considération de version de système d'exploitation ou autre ?
Merci
Salut Raphaël,
Comment tu gères pour les version d'iOS 9 ?
Merci