Article original : How to add Flexbox fallback to CSS Grid
J'ai partagé comment construire un calendrier avec CSS Grid dans l'article précédent. Aujourd'hui, je veux partager comment construire un fallback Flexbox pour le même calendrier.
Comment fournir un support
Généralement, il existe trois façons de fournir un support en ce qui concerne le CSS.
Première méthode : Écrire un code de fallback. Écraser le code de fallback.
.selector {
property: fallback-value;
property: actual-value;
}
Deuxième méthode : Écrire un code de fallback. Écraser le code de fallback dans les requêtes de fonctionnalités CSS (@supports). Réinitialiser les propriétés à l'intérieur de @supports si nécessaire.
.selector {
property: fallback-value;
}
@supports (display: grid) {
property: actual-value;
}
Troisième méthode : Tout écrire dans @supports.
@supports not (display: grid) {
.selector {
property: fallback-value;
}
}
@supports (display: grid) {
.selector {
property: actual-value;
}
}
Ces trois méthodes sont listées par ordre de complexité décroissante. (Si vous devez écraser du code, c'est plus compliqué). Cela signifie que tout écrire dans @supports est le plus simple des trois.
La façon dont vous choisissez de supporter votre projet dépend du support des navigateurs pour :
- La fonctionnalité
- La fonctionnalité de fallback
- Le support des requêtes de fonctionnalités
Vérification du support
Le meilleur endroit pour vérifier le support est caniuse. Ici, je vois que le support pour CSS Grid est décent. Les navigateurs dont je dois m'inquiéter sont :
- Opera Mini : 1,42 % d'utilisation mondiale
- Navigateurs Android 2.1 à 4.4.4 : 0,67 % d'utilisation mondiale
- Navigateur Blackberry : 0,02 % d'utilisation mondiale (Je ne vais pas m'inquiéter de celui-ci).

Le support pour le fallback (Flexbox) est également bon.
Mais nous avons un problème : le fallback Flexbox ne fonctionnerait pas pour Android 2.1 à 4.3 (il ne supporte pas le wrapping). L'utilisation mondiale pour Android 2.1 à 4.3 est de 0,37 %.
Ici, je dois décider :
- Est-ce que fournir un fallback Flexbox pour Opera Mini (1,42 %), Android 4.4.4 (0,3 %), et Blackberry (0,02 %) vaut l'effort ?
- Dois-je changer le fallback de Flexbox à une fonctionnalité plus ancienne pour supporter Android 2.1 à 4.3 (un autre 0,37 %) ?

Supposons, pour ce projet, que je décide que le fallback Flexbox est suffisant. Je ne vais pas m'inquiéter d'Android 2.1 à 4.3.
Ensuite, je veux vérifier si les navigateurs supportent les requêtes de fonctionnalités CSS.
Ici, je vois :
- Opera Mini supporte les requêtes de fonctionnalités
- Android 4.4.4 supporte les requêtes de fonctionnalités
- Le navigateur Blackberry ne supporte pas les requêtes de fonctionnalités
- IE 11 ne supporte pas les requêtes de fonctionnalités
Décider comment écrire le code de fallback
Plus tôt, j'ai mentionné qu'il existe trois façons d'écrire un code de fallback pour CSS :
- Écrire un code de fallback. Écraser le code de fallback.
- Écrire un code de fallback. Écraser le code de fallback dans
@supports. - Tout écrire dans
@supports.
Si j'écris tout à l'intérieur de @supports, je peux fournir un support pour :
- Opera Mini (1,43 %)
- Android 4.4.4 (0,3 %)
Mais je perds le support pour :
- IE 11 (2,3 %)
- Blackberry (0,02 %)
Je ne veux pas abandonner les 2,3 % d'utilisateurs de IE, ce qui signifie que la Méthode 3 (tout écrire dans @supports) est exclue.
Si j'utilise la Méthode 2 (Écrire un code de fallback. Écraser le code de fallback dans @supports), je peux fournir un support pour :
- IE 11 (2,3 %)
- Opera Mini (1,43 %)
- Android 4.4.4 (0,3 %)
- Navigateur Blackberry (0,02 %)
C'est tout ce dont j'ai besoin. C'est pourquoi je vais opter pour la Méthode 2.
Note : Si vous voulez coder en même temps, vous pouvez utiliser la démo de mon article précédent comme point de départ.
Désactiver le code Grid
Tout d'abord, nous plaçons le code CSS Grid sous @supports (comme nous en avons discuté ci-dessus).
@supports (display: grid) {
.day-of-week,
.date-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
}
.date-grid button:first-child {
grid-column: 6;
}
}
Nous pouvons désactiver le code CSS Grid en définissant display sur une valeur invalide (pas grid). Cela désactive l'ensemble du bloc de code.
(Merci à Rachel Andrew pour ce truc astucieux. Je crois que je l'ai appris d'elle ?).
@supports (display: gridx) {
/*...*/
}

Écrire le code Flexbox
Nous devons construire la même grille de sept colonnes avec Flexbox. La première chose à faire est de reconnaître que Flexbox et Grid fonctionnent différemment. Nous ne pourrons pas obtenir une réplique parfaite, mais nous pouvons nous en approcher.
La première chose est de définir display sur flex.
.day-of-week,
.date-grid {
display: flex;
}

Nous avons besoin que les boutons dans .date-grid s'enroulent, donc nous définissons flex-wrap sur wrap.
.date-grid {
flex-wrap: wrap;
}

Nous devons répliquer la grille de sept colonnes. Un moyen facile de faire cela est de calculer la largeur de la grille en fonction de la largeur de chaque bouton. Ici, j'ai déjà défini chaque bouton à 4.5ch. Cela signifie que la largeur de la grille devrait être 7 x 4.5ch.
(Nous pouvons utiliser CSS Calc pour faire le calcul pour nous).
.day-of-week,
.date-grid {
max-width: calc(4.5ch * 7);
}

Nous avons besoin que les éléments dans .day-of-week se répartissent sur la largeur disponible. Un moyen simple est de définir justify-content sur space-between.
.day-of-week {
justify-content: space-between;
}

Ici, nous pouvons voir que les éléments dans .day-of-week s'étendent au-delà de la grille. Cette extension se produit parce que nous laissons Flexbox calculer flex-basis pour nous. Si nous voulons que chaque élément dans .day-of-week ait la même largeur, nous devons définir flex-basis nous-mêmes.
Dans ce cas, le moyen le plus simple est de définir flex-basis sur la largeur d'un élément de grille (ou 4.5ch). Note : J'ai ajusté la font-size de chaque élément dans .day-of-week à 0.7em (pour des raisons esthétiques visuelles). Nous devons tenir compte de ce changement.
.day-of-week > * {
flex-basis: calc(4.5ch / 0.7);
}

Enfin, nous devons pousser le 1er février à vendredi. (Cinq colonnes). Puisque la colonne est 4.5ch, nous le poussons simplement par 4.5ch x 5.
(Encore une fois, nous pouvons utiliser CSS Calc pour nous aider avec cela).
.date-grid button:first-child {
margin-left: calc(4.5ch * 5);
}

Correction de la version CSS Grid
Nous pouvons réactiver le code CSS Grid et apporter les modifications nécessaires maintenant.
@supports (display: grid) {
/* ... */
}

Ici, nous voyons certaines valeurs s'envoler loin à droite. Cela se produit parce que nous avons ajouté margin-left au premier élément de la grille. Nous devons réinitialiser la marge ajoutée.
@supports (display: grid) {
/* ... */
.date-grid button:first-child {
grid-column: 6;
margin-left: 0;
}
}

Une autre chose : Nous pouvons supprimer max-width parce que nous n'en avons pas besoin dans le code CSS. (Même si cela n'affecte pas le code CSS, nous voulons toujours le supprimer. Il est toujours préférable d'avoir moins de propriétés).
@supports (display: grid) {
.day-of-week,
.date-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
max-width: initial;
}
/* ... */
}
Voici la différence visuelle entre les versions Flexbox et CSS Grid. Pas trop mal !

Une chose amusante
CSS Grid est cool parce qu'il suit la direction d'écriture. Nous pouvons facilement changer le flux de gauche à droite à droite à gauche.
Note : Je ne sais pas si les calendriers sont lus de droite à gauche dans les langues rtl. Je pensais juste que ce serait amusant de le mentionner ?).

Notre code pour CSS Grid supporte naturellement ce comportement. Si vous voulez supporter le même comportement avec Flexbox, vous devez utiliser les propriétés logiques CSS.

Puisque le support pour les propriétés logiques CSS n'est pas si bon, nous devons fournir un fallback pour cela. (La meilleure façon est par la Méthode 1 : Écrire un fallback ; écraser le fallback).
.date-grid button:first-child {
margin-left: calc(4.5ch * 5);
margin-inline-start: calc(4.5ch * 5);
}
@supports (display: grid) {
/* ... */
.date-grid button:first-child {
grid-column: 6;
margin-left: 0;
margin-inline-start: 0;
}
}
C'est tout ! Voici un Codepen pour le code final :
See the Pen Building a Calendar with CSS Grid (and fallback with Flexbox) by Zell Liew (@zellwk) on CodePen.
Merci d'avoir lu. Cet article a été initialement publié sur mon blog. Inscrivez-vous à ma newsletter si vous voulez plus d'articles pour vous aider à devenir un meilleur développeur frontend.