Un guide sur la prise en charge CSS dans les navigateurs

Publié: 2022-03-10
Résumé rapide ↬ Il peut être frustrant de vouloir utiliser une fonctionnalité et de découvrir qu'elle n'est pas prise en charge ou qu'elle se comporte différemment d'un navigateur à l'autre. Dans cet article, Rachel Andrew détaille les différents types de problèmes de prise en charge des navigateurs et montre comment le CSS évolue pour faciliter leur traitement.

Nous ne vivrons jamais dans un monde où tous ceux qui consultent nos sites ont un navigateur et une version de navigateur identiques, tout comme nous ne vivrons jamais dans un monde où tout le monde a la même taille d'écran et la même résolution. Cela signifie que gérer les anciens navigateurs - ou les navigateurs qui ne prennent pas en charge quelque chose que nous voulons utiliser - fait partie du travail d'un développeur Web. Cela dit, les choses vont bien mieux maintenant que par le passé, et dans cet article, je vais jeter un œil aux différents types de problèmes de support de navigateur que nous pourrions rencontrer. Je vais vous montrer quelques façons de les gérer, et aussi regarder les choses qui pourraient arriver bientôt et qui peuvent aider.

Pourquoi avons-nous ces différences ?

Même dans un monde où la majorité des navigateurs sont basés sur Chromium, ces navigateurs n'exécutent pas tous la même version de Chromium que Google Chrome. Cela signifie qu'un navigateur basé sur Chromium, tel que Vivaldi, peut avoir quelques versions derrière Google Chrome.

Et, bien sûr, les utilisateurs ne mettent pas toujours à jour rapidement leurs navigateurs, bien que cette situation se soit améliorée ces dernières années, la plupart des navigateurs se mettant à jour en silence.

Il y a aussi la manière dont les nouvelles fonctionnalités entrent dans les navigateurs en premier lieu. Ce n'est pas le cas que de nouvelles fonctionnalités pour CSS sont conçues par le groupe de travail CSS, et une spécification complète transmise aux fournisseurs de navigateurs avec une instruction pour l'implémenter. Très souvent, ce n'est que lorsqu'une implémentation expérimentale a lieu que tous les détails les plus fins de la spécification peuvent être élaborés. Par conséquent, le développement de fonctionnalités est un processus itératif et nécessite que les navigateurs implémentent ces spécifications lors du développement. Bien que la mise en œuvre se produise le plus souvent de nos jours derrière un drapeau dans le navigateur ou disponible uniquement dans une version nocturne ou d'aperçu, une fois qu'un navigateur a une fonctionnalité complète, il est susceptible de l'activer pour tout le monde même si aucun autre navigateur n'a encore de support.

Tout cela signifie que, même si nous l'aimons, nous n'existerons jamais dans un monde où les fonctionnalités sont magiquement disponibles simultanément sur chaque ordinateur de bureau et téléphone. Si vous êtes un développeur Web professionnel, votre travail consiste à gérer ce fait.

Plus après saut! Continuez à lire ci-dessous ↓

Bugs contre manque de support

Nous sommes confrontés à trois problèmes concernant la prise en charge du navigateur :

  1. Pas de prise en charge d'une fonctionnalité
    Le premier problème (et le plus facile à résoudre) est lorsqu'un navigateur ne prend pas du tout en charge la fonctionnalité.
  2. Gérer les "bugs" du navigateur
    La seconde est lorsque le navigateur prétend prendre en charge la fonctionnalité, mais le fait d'une manière différente de la manière dont les autres navigateurs prennent en charge la fonctionnalité. Un tel problème est ce que nous avons tendance à appeler un « bogue du navigateur », car le résultat final est un comportement incohérent.
  3. Prise en charge partielle des propriétés CSS
    Celui-ci devient plus commun; une situation dans laquelle un navigateur prend en charge une fonctionnalité, mais uniquement dans un contexte.

Il est utile de comprendre à quoi vous avez affaire lorsque vous voyez une différence entre les navigateurs, alors examinons chacun de ces problèmes à tour de rôle.

1. Aucune prise en charge d'une fonctionnalité

Si vous utilisez une propriété ou une valeur CSS qu'un navigateur ne comprend pas, le navigateur l'ignorera. C'est la même chose que vous utilisiez une fonctionnalité qui n'est pas prise en charge ou que vous créiez une fonctionnalité et essayiez de l'utiliser. Si le navigateur ne comprend pas cette ligne de CSS, il la saute simplement et passe à la prochaine chose qu'il comprend.

Ce principe de conception de CSS signifie que vous pouvez utiliser joyeusement de nouvelles fonctionnalités, sachant que rien de mal n'arrivera à un navigateur qui n'a pas de support. Pour certains CSS, utilisés uniquement comme amélioration, c'est tout ce que vous avez à faire. Utilisez la fonctionnalité, assurez-vous que lorsque cette fonctionnalité n'est pas disponible, l'expérience est toujours bonne, et c'est tout. Cette approche est l'idée de base derrière l'amélioration progressive, en utilisant cette fonctionnalité de la plate-forme qui permet l'utilisation en toute sécurité de nouvelles choses dans les navigateurs qui ne les comprennent pas.

Si vous souhaitez vérifier si une fonctionnalité que vous utilisez est prise en charge par les navigateurs, vous pouvez consulter le site Web Puis-je utiliser. Un autre bon endroit pour rechercher des informations de support détaillées est la page de chaque propriété CSS sur MDN. Les données de prise en charge du navigateur ont tendance à être très détaillées.

Le nouveau CSS comprend l'ancien CSS

Au fur et à mesure que de nouvelles fonctionnalités CSS sont développées, une attention particulière est portée à la manière dont elles interagissent avec le CSS existant. Par exemple, dans la spécification Grid and Flexbox, il est détaillé en termes de comment display: grid et display: flex traitent des scénarios tels que lorsqu'un élément flottant devient un élément de grille ou qu'un conteneur multicol est transformé en grille. Cela signifie que certains comportements sont ignorés, ce qui vous permet d'écraser simplement le CSS du navigateur non pris en charge. Ces remplacements sont détaillés dans la page pour l'amélioration progressive et la disposition de la grille sur MDN.

Détection de la prise en charge avec des requêtes de fonctionnalités

La méthode ci-dessus ne fonctionne que si le CSS que vous devez utiliser n'a pas besoin d'autres propriétés pour l'accompagner. Vous devrez peut-être ajouter des propriétés supplémentaires à votre CSS pour les anciens navigateurs, qui seront également interprétées par les navigateurs qui prennent également en charge la fonctionnalité.

Un bon exemple de cela peut être trouvé lors de l'utilisation de Grid Layout. Alors qu'un élément flottant qui devient un élément de grille perd tout comportement flottant, il est probable que si vous essayez de créer un repli pour une disposition de grille avec flotteur, vous aurez ajouté des pourcentages de largeur et éventuellement des marges aux éléments.

 .grid > .item { width: 23%; margin: 0 1%; } 
Une mise en page à quatre colonnes
En utilisant des flottants, nous pouvons créer une mise en page à quatre colonnes, les largeurs et les marges doivent être définies en % . ( Grand aperçu )

Ces largeurs et marges s'appliqueront alors toujours lorsque l'élément flottant est un élément de grille. La largeur devient un pourcentage de la piste de la grille plutôt que la largeur totale du conteneur ; toute marge sera alors appliquée ainsi qu'un écart que vous aurez éventuellement spécifié.

 .grid > .item { width: 23%; margin: 0 1%; } .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; } 
Une mise en page à quatre colonnes avec des colonnes écrasées
La largeur est maintenant un pourcentage de la piste de la grille - pas du conteneur. ( Grand aperçu )

Heureusement, il existe une fonctionnalité intégrée au CSS et implémentée dans les navigateurs modernes qui nous aide à faire face à cette situation. Les requêtes de fonctionnalités nous permettent de demander directement au navigateur ce qu'il prend en charge, puis d'agir sur la réponse. Tout comme une requête multimédia - qui teste certaines propriétés de l'appareil ou de l'écran - les requêtes de fonctionnalités testent la prise en charge d'une propriété et d'une valeur CSS.

Tester pour le support

Le test de support est le cas le plus simple, nous utilisons @supports puis testons une propriété et une valeur CSS. Le contenu de la requête de fonctionnalité ne s'exécutera que si le navigateur répond par true, c'est-à-dire qu'il prend en charge la fonctionnalité.

Tester sans support

Vous pouvez demander au navigateur s'il ne prend pas en charge une fonctionnalité. Dans ce cas, le code à l'intérieur de la requête de fonctionnalité ne s'exécutera que si le navigateur indique qu'il n'est pas pris en charge.

 @supports not (display: grid) { .item { /* CSS from browsers which do not support grid layout */ } }

Testez pour plusieurs choses

Si vous avez besoin que plusieurs propriétés soient prises en charge, utilisez and .

 @supports (display: grid) and (shape-outside: circle()){ .item { /* CSS from browsers which support grid and CSS shapes */ } }

Si vous avez besoin d'aide pour une propriété ou une autre, utilisez or .

 @supports (display: grid) or (display: flex){ .item { /* CSS from browsers which support grid or flexbox */ } }

Choisir une propriété et une valeur à tester

Vous n'avez pas besoin de tester chaque propriété que vous souhaitez utiliser - juste quelque chose qui indiquerait la prise en charge des fonctionnalités que vous prévoyez d'utiliser. Par conséquent, si vous souhaitez utiliser Grid Layout, vous pouvez tester display: grid . À l'avenir (et une fois que la prise en charge des sous-réseaux sera disponible dans les navigateurs), vous devrez peut-être être plus précis et tester les fonctionnalités des sous-réseaux. Dans ce cas, vous testerez grid-template-columns: subgrid pour obtenir une vraie réponse uniquement des navigateurs qui ont implémenté le support subgrid.

Si nous revenons maintenant à notre exemple de repli flottant, nous pouvons voir comment les requêtes de fonctionnalités vont le trier pour nous. Ce que nous devons faire est d'interroger le navigateur pour savoir s'il prend en charge la disposition en grille. Si c'est le cas, nous pouvons redéfinir la largeur de l'élément sur auto et la marge sur 0 .

 .grid > .item { width: 23%; margin: 0 1%; } @supports(display: grid) { .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; } .grid > .item { width: auto; margin: 0; } } 

Voir les requêtes et la grille des fonctionnalités du stylet par (Rachel Andrew) sur CodePen.

Voir les requêtes et la grille des fonctionnalités du stylet par (Rachel Andrew) sur CodePen.

Notez que même si j'ai inclus tout le code de la grille dans ma requête de fonctionnalité, je n'en ai pas besoin. Si un navigateur ne comprenait pas les propriétés de la grille, il les ignorerait afin qu'elles puissent être en toute sécurité en dehors de la requête de fonctionnalité. Les choses qui doivent être à l'intérieur d'une requête de fonctionnalité dans cet exemple sont les propriétés de marge et de largeur, car elles sont nécessaires pour l'ancien code de navigateur mais seraient également appliquées par les navigateurs prenant en charge.

Embrassez la cascade

Un moyen très simple d'offrir des solutions de repli consiste à utiliser le fait que les navigateurs ignorent les CSS qu'ils ne comprennent pas, et le fait que là où tout le reste a une spécificité égale, l'ordre des sources est pris en compte en termes de CSS appliqué à un élément .

Vous écrivez d'abord votre CSS pour les navigateurs qui ne prennent pas en charge la fonctionnalité. Testez ensuite la prise en charge de la propriété que vous souhaitez utiliser, si le navigateur confirme qu'il prend en charge, remplacez le code de secours par votre nouveau code.

Il s'agit à peu près de la même procédure que vous pourriez utiliser lorsque vous utilisez des requêtes multimédias pour une conception réactive, en suivant une approche axée sur le mobile. Dans cette approche, vous commencez par votre mise en page pour les écrans plus petits, puis ajoutez ou écrasez des éléments pour les plus grands au fur et à mesure que vous progressez dans vos points d'arrêt.

Puis-je utiliser des requêtes de fonctionnalité CSS ? Données sur la prise en charge des requêtes de fonctionnalités CSS sur les principaux navigateurs de caniuse.com.

La méthode de travail ci-dessus signifie que vous n'avez pas à vous soucier des navigateurs qui ne prennent pas en charge les requêtes de fonctionnalités. Comme vous pouvez le voir dans Puis-je utiliser , les requêtes de fonctionnalités ont un très bon support. Les navigateurs hors concours qui ne les prennent pas en charge étant n'importe quelle version d'Internet Explorer.

Cependant, il est probable que la nouvelle fonctionnalité que vous souhaitez utiliser ne soit pas non plus prise en charge dans IE. Donc, à l'heure actuelle, vous commencerez presque toujours par écrire du CSS pour les navigateurs sans support, puis vous testerez avec une requête de fonctionnalité. Cette requête de fonctionnalité doit tester la prise en charge.

  1. Les navigateurs qui prennent en charge les requêtes de fonctionnalités renverront vrai s'ils ont un support et donc le code à l'intérieur de la requête sera utilisé, écrasant le code des anciens navigateurs.
  2. Si le navigateur prend en charge les requêtes de fonctionnalités mais pas la fonctionnalité testée, il renverra false. Le code à l'intérieur de la requête de fonctionnalité sera ignoré.
  3. Si le navigateur ne prend pas en charge les requêtes de fonctionnalités, tout ce qui se trouve dans le bloc Feature Query sera ignoré, ce qui signifie qu'un navigateur tel qu'IE11 utilisera votre ancien code de navigateur, ce qui est très probablement exactement ce que vous voulez !

2. Traiter les "bogues" du navigateur

Le deuxième problème de prise en charge du navigateur devient heureusement moins courant. Si vous lisez "What We Wished For" (publié à la fin de l'année dernière), vous pouvez faire un petit tour dans certains des bogues de navigateur les plus déroutants du passé. Cela dit, tout logiciel est susceptible d'avoir des bugs, les navigateurs ne font pas exception. Et, si nous ajoutons à cela le fait qu'en raison de la nature circulaire de l'implémentation des spécifications, parfois un navigateur a implémenté quelque chose, puis la spécification a changé, il doit donc maintenant publier une mise à jour. Jusqu'à ce que cette mise à jour soit publiée, nous pourrions être dans une situation où les navigateurs font quelque chose de différent les uns des autres.

Les requêtes de fonctionnalités ne peuvent pas nous aider si le navigateur signale la prise en charge de quelque chose qui le prend mal. Il n'y a pas de mode par lequel le navigateur peut dire " Oui, mais vous ne l'aimerez probablement pas ". Lorsqu'un bogue d'interopérabilité réel apparaît, c'est dans ces situations où vous devrez peut-être être un peu plus créatif.

Si vous pensez voir un bogue, la première chose à faire est de le confirmer. Parfois, lorsque nous pensons voir un comportement bogué et que les navigateurs font des choses différentes, la faute en est à nous. Peut-être avons-nous utilisé une syntaxe invalide ou essayons-nous de styliser du HTML mal formé. Dans ces cas, le navigateur essaiera de faire quelque chose ; cependant, comme vous n'utilisez pas les langages tels qu'ils ont été conçus, chaque navigateur peut s'en sortir différemment. Une vérification rapide de la validité de votre code HTML et CSS est une excellente première étape.

À ce stade, je ferais probablement une recherche rapide et verrais si mon problème était déjà largement compris. Il existe quelques dépôts de problèmes connus, par exemple Flexbugs et Gridbugs. Cependant, même quelques mots-clés bien choisis peuvent générer des publications ou des articles Stack Overflow qui couvrent le sujet et peuvent vous proposer une solution de contournement.

Mais disons que vous ne savez pas vraiment ce qui cause le bogue, ce qui rend assez difficile la recherche d'une solution. Ainsi, l'étape suivante consiste à créer un cas de test réduit de votre problème, c'est-à-dire à supprimer tout ce qui n'est pas pertinent pour vous aider à identifier exactement ce qui déclenche le bogue. Si vous pensez avoir un bogue CSS, pouvez-vous supprimer tout code JavaScript ou recréer le même style en dehors d'un framework ? J'utilise souvent CodePen pour créer un cas de test réduit de quelque chose que je vois. cela a l'avantage supplémentaire de me donner le code d'une manière que je peux facilement partager avec quelqu'un d'autre si j'ai besoin de poser des questions à ce sujet.

La plupart du temps, une fois que vous avez isolé le problème, il est possible de trouver une autre façon d'obtenir le résultat souhaité. Vous constaterez que quelqu'un d'autre a trouvé une solution de contournement astucieuse, ou vous pouvez poster quelque part pour demander des suggestions.

Cela dit, si vous pensez que vous avez un bogue de navigateur et que personne d'autre ne parle du même problème, il est fort possible que vous ayez trouvé quelque chose de nouveau qui devrait être signalé. Avec tous les nouveaux CSS qui ont débarqué récemment, des problèmes peuvent parfois apparaître lorsque les gens commencent à utiliser des choses en combinaison avec d'autres parties de CSS.

Consultez cet article de Lea Verou sur le signalement de tels problèmes, "Aidez la communauté ! Signaler les bogues du navigateur !". L'article contient également d'excellents conseils pour créer un cas de test réduit.

3. Prise en charge partielle des propriétés CSS

Le troisième type de problème est devenu plus courant en raison de la façon dont les spécifications CSS modernes sont conçues. Si nous pensons à Grid Layout et Flexbox, ces spécifications utilisent toutes les deux les propriétés et les valeurs de Box Alignment Level 3, pour effectuer l'alignement. Par conséquent, des propriétés telles que align-items , justify-content et column-gap sont spécifiées pour être utilisées à la fois dans Grid et Flexbox ainsi que dans d'autres méthodes de mise en page.

Au moment de la rédaction, cependant, les propriétés d' gap fonctionnent dans Grid Layout dans tous les navigateurs prenant en charge la grille, et column-gap fonctionne dans Multicol ; cependant, seul Firefox a implémenté ces propriétés pour Flexbox.

Si je devais utiliser des marges pour créer un repli pour Flexbox, puis tester l' column-gap et supprimer les marges, mes boîtes n'auront pas d'espace entre elles dans les navigateurs qui prennent en charge column-gap dans Grid ou multicol, donc mon espacement de repli sera supprimé.

 @supports(column-gap: 20px) { .flex { margin: 0; /* almost everything supports column-gap so this will always remove the margins, even if we do not have gap support in flexbox. */ } }

Il s'agit d'une limitation actuelle des requêtes de fonctionnalité. Nous n'avons aucun moyen de tester la prise en charge d'une fonctionnalité dans une autre fonctionnalité. Dans la situation ci-dessus, ce que je veux demander au navigateur est : "Avez-vous un support pour l'écart de colonne dans Flexbox ?" De cette façon, je peux obtenir une réponse négative afin que je puisse utiliser mon secours.

Il existe un problème similaire avec les propriétés de fragmentation CSS break-before , break-after et break-inside . Comme ceux-ci ont un meilleur support lorsque la page est imprimée, les navigateurs réclament souvent un support. Cependant, si vous testez la prise en charge de multicol, vous obtenez ce qui semble être de faux positifs. J'ai soulevé un problème au sein du groupe de travail CSS pour ce problème, cependant, ce n'est pas un problème simple à résoudre. Si vous avez des idées, veuillez les ajouter ici.

Test de prise en charge du sélecteur

Actuellement, les requêtes de fonctionnalité ne peuvent tester que les propriétés et les valeurs CSS. Une autre chose que nous aimerions tester est la prise en charge de nouveaux sélecteurs, tels que ceux du niveau 4 de la spécification des sélecteurs. Il y a une note explicative et aussi une implémentation derrière un drapeau dans Firefox Nightly d'une nouvelle fonctionnalité pour les requêtes de fonctionnalités qui permettra d'atteindre cet objectif.

Si vous visitez about:config dans Firefox et activez l'indicateur layout.css.supports-selector.enabled , vous pouvez tester pour voir si différents sélecteurs sont pris en charge. La syntaxe est actuellement très simple, par exemple pour tester le sélecteur : :has :

 @supports selector(:has){ .item { /* CSS for support of :has */ } }

Il s'agit d'une spécification en cours de développement, cependant, vous pouvez voir comment des fonctionnalités pour nous aider à gérer les problèmes omniprésents de prise en charge des navigateurs sont ajoutées au moment où nous parlons.

Lectures complémentaires

Cela peut sembler frustrant lorsque vous souhaitez utiliser une fonctionnalité et découvrez qu'elle n'est pas prise en charge par un navigateur majeur, ou si les choses semblent se comporter de différentes manières. J'ai rassemblé quelques lectures pratiques qui pourraient vous aider.

  • "Utilisation de CSS Grid : Prise en charge des navigateurs sans grille" Options pour gérer les anciens navigateurs et CSS Grid
  • Page de référence MDN "Requêtes d'entités" pour les requêtes d'entités
  • Guide MDN "CSS Grid And Progressive Enhancement" pour l'amélioration progressive de la grille
  • Guide MDN "Rétrocompatibilité de Flexbox" sur la prise en charge de Flexbox, y compris les détails des anciennes implémentations préfixées
  • "Pattern Library First" Comment gérer le code de secours à l'aide d'une bibliothèque de modèles