Houdini : Peut-être le développement CSS le plus excitant dont vous n'avez jamais entendu parler

Publié: 2022-03-10
Résumé rapide ↬ Avez-vous déjà voulu utiliser une fonctionnalité CSS particulière mais ne l'avez pas fait car elle n'était pas entièrement prise en charge par tous les navigateurs ? Ou, pire, il était supporté par tous les navigateurs, mais le support était bogué, incohérent voire totalement incompatible ? Si cela vous est arrivé – et je parie que c'est le cas – alors vous devriez vous soucier de Houdini. Houdini est un nouveau groupe de travail du W3C dont le but ultime est de faire disparaître ce problème pour toujours. Il prévoit de le faire en introduisant un nouvel ensemble d'API qui, pour la première fois, donnera aux développeurs le pouvoir d'étendre CSS lui-même, et les outils pour s'accrocher au processus de style et de mise en page du moteur de rendu d'un navigateur.

Avez-vous déjà voulu utiliser une fonctionnalité CSS particulière mais ne l'avez pas fait car elle n'était pas entièrement prise en charge par tous les navigateurs ? Ou, pire, il était supporté par tous les navigateurs, mais le support était bogué, incohérent voire totalement incompatible ? Si cela vous est arrivé – et je parie que c'est le cas – alors vous devriez vous soucier de Houdini.

Houdini est un nouveau groupe de travail du W3C dont le but ultime est de faire disparaître ce problème pour toujours. Il prévoit de le faire en introduisant un nouvel ensemble d'API qui, pour la première fois, donnera aux développeurs le pouvoir d'étendre le CSS lui-même et les outils pour s'accrocher au processus de style et de mise en page du moteur de rendu d'un navigateur .

Lectures complémentaires sur SmashingMag :

  • Pourquoi arrêter d'installer votre environnement WebDev en local
  • L'avenir du CSS : propriétés CSS expérimentales
  • 53 techniques CSS dont vous ne pourriez pas vous passer

Mais qu'est-ce que cela signifie, concrètement ? Est-ce même une bonne idée ? Et comment cela aidera-t-il les développeurs à créer des sites Web maintenant et à l'avenir ?

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

Dans cet article, je vais essayer de répondre à ces questions. Mais avant de le faire, il est important de préciser quels sont les problèmes aujourd'hui et pourquoi il y a un tel besoin de changement. Je parlerai ensuite plus précisément de la manière dont Houdini résoudra ces problèmes et énumérerai certaines des fonctionnalités les plus intéressantes actuellement en développement. Enfin, je proposerai des choses concrètes que nous, les développeurs Web, pouvons faire aujourd'hui pour aider à faire de Houdini une réalité.

Quels problèmes Houdini essaie-t-il de résoudre ?

Chaque fois que j'écris un article ou que je crée une démo montrant une toute nouvelle fonctionnalité CSS, inévitablement, quelqu'un dans les commentaires ou sur Twitter dira quelque chose comme : « C'est génial ! Dommage qu'on ne puisse pas l'utiliser avant 10 ans.

Aussi ennuyeux et peu constructifs que soient des commentaires comme celui-ci, je comprends le sentiment. Historiquement, il a fallu des années pour que les propositions de fonctionnalités soient largement adoptées. Et la raison en est que, tout au long de l'histoire du Web, la seule façon d'ajouter une nouvelle fonctionnalité au CSS était de passer par le processus de normalisation.

Processus de normalisation
Les étapes du processus de normalisation. (Voir la grande version)

Bien que je n'ai absolument rien contre le processus de normalisation, il est indéniable que cela peut prendre beaucoup de temps !

Par exemple, flexbox a été proposé pour la première fois en 2009, et les développeurs se plaignent toujours de ne pas pouvoir l'utiliser aujourd'hui en raison d'un manque de prise en charge des navigateurs. Certes, ce problème disparaît lentement car presque tous les navigateurs modernes se mettent désormais à jour automatiquement. mais même avec les navigateurs modernes, il y aura toujours un décalage entre la proposition et la disponibilité générale d'une fonctionnalité.

Fait intéressant, ce n'est pas le cas dans tous les domaines du Web. Considérez comment les choses ont fonctionné récemment en JavaScript :

Processus de polyremplissage
Les étapes du processus de polyfill. (Voir la grande version)

Dans ce scénario, le temps entre avoir une idée et commencer à l'utiliser en production peut parfois être une question de jours. Je veux dire, j'utilise déjà les fonctions async / await en production, et cette fonctionnalité n'a même pas été implémentée dans un seul navigateur !

Vous pouvez également voir une énorme différence dans les sentiments généraux de ces deux communautés. Dans la communauté JavaScript, vous lisez des articles dans lesquels les gens se plaignent que les choses vont trop vite. En CSS, d'un autre côté, vous entendez des gens se plaindre de la futilité d'apprendre quelque chose de nouveau en raison du temps qu'il faudra avant qu'ils puissent réellement l'utiliser.

Alors, pourquoi n'écrivons-nous pas simplement plus de polyfills CSS ?

À première vue, écrire plus de polyfills CSS peut sembler être la réponse. Avec de bons polyfills, CSS pourrait aller aussi vite que JavaScript, n'est-ce pas ?

Malheureusement, ce n'est pas si simple. Polyfilling CSS est incroyablement difficile et, dans la plupart des cas, impossible à faire d'une manière qui ne détruit pas complètement les performances.

JavaScript est un langage dynamique, ce qui signifie que vous pouvez utiliser JavaScript pour polyfill JavaScript. Et parce qu'il est si dynamique, il est extrêmement extensible. CSS, d'autre part, peut rarement être utilisé pour polyfill CSS. Dans certains cas, vous pouvez transpiler CSS en CSS dans une étape de construction (PostCSS le fait) ; mais si vous voulez remplir tout ce qui dépend de la structure du DOM ou de la disposition ou de la position d'un élément, vous devrez exécuter la logique côté client de votre polyfill.

Malheureusement, le navigateur ne rend pas cela facile.

Le tableau ci-dessous donne un aperçu de base de la façon dont votre navigateur passe de la réception d'un document HTML à l'affichage de pixels à l'écran. Les étapes colorées en bleu montrent où JavaScript a le pouvoir de contrôler les résultats :

Processus de rendu
Accès JavaScript au pipeline de rendu du navigateur. (Voir la grande version)

L'image est assez sombre. En tant que développeur, vous n'avez aucun contrôle sur la façon dont le navigateur analyse HTML et CSS et les transforme en modèle d'objet DOM et CSS (CSSOM). Vous n'avez aucun contrôle sur la cascade. Vous n'avez aucun contrôle sur la façon dont le navigateur choisit de disposer les éléments dans le DOM ou sur la façon dont il peint ces éléments visuellement à l'écran. Et vous n'avez aucun contrôle sur ce que fait le compositeur.

La seule partie du processus à laquelle vous avez un accès complet est le DOM. Le CSSOM est plutôt ouvert ; cependant, pour citer le site Web de Houdini, il est "sous-spécifié, incohérent d'un navigateur à l'autre et manquant de fonctionnalités essentielles".

Par exemple, le CSSOM dans les navigateurs d'aujourd'hui ne vous montrera pas les règles pour les feuilles de style d'origine croisée, et il supprimera simplement toutes les règles ou déclarations CSS qu'il ne comprend pas, ce qui signifie que si vous voulez polyfiller une fonctionnalité dans un navigateur qui ne le prend pas en charge, vous ne pouvez pas utiliser le CSSOM. Au lieu de cela, vous devez parcourir le DOM, trouver les balises <style> et/ou <link rel=“stylesheet”> , obtenir le CSS vous-même, l'analyser, le réécrire puis le rajouter au DOM.

Bien sûr, la mise à jour du DOM signifie généralement que le navigateur doit ensuite parcourir à nouveau toutes les étapes de la cascade, de la mise en page, de la peinture et de la composition.

Processus de rendu Polyfill
Poly-remplir le pipeline de rendu du navigateur avec JavaScript. (Voir la grande version)

Bien que devoir restituer complètement une page puisse ne pas sembler être un gros problème de performances (en particulier pour certains sites Web), considérez la fréquence à laquelle cela doit potentiellement se produire. Si la logique de votre polyfill doit s'exécuter en réponse à des événements tels que les événements de défilement, le redimensionnement de la fenêtre, les mouvements de la souris, les événements du clavier - vraiment à tout moment, tout change - alors les choses vont être sensiblement, parfois même paralysantes, lentes.

Cela s'aggrave encore lorsque vous réalisez que la plupart des polyfills CSS disponibles aujourd'hui incluent leur propre analyseur CSS et leur propre logique en cascade. Et parce que l'analyse et la cascade sont en fait des choses très compliquées, ces polyfills sont généralement soit trop volumineux, soit trop buggés.

Pour résumer tout ce que je viens de dire de manière plus concise : si vous voulez que le navigateur fasse quelque chose de différent de ce qu'il pense être censé faire (compte tenu du CSS que vous lui avez donné), vous devez trouver un moyen de le simuler en mettant à jour et en modifiant le DOM vous-même. Vous n'avez pas accès aux autres étapes du pipeline de rendu.

Mais pourquoi voudrais-je jamais modifier le moteur de rendu interne du navigateur ?

Ceci, pour moi, est absolument la question la plus importante à laquelle répondre dans tout cet article. Donc, si vous avez parcouru les choses jusqu'à présent, lisez cette partie lentement et attentivement !

Après avoir regardé la dernière section, je suis sûr que certains d'entre vous pensaient : « Je n'ai pas besoin de ça ! Je construis juste des pages Web normales. Je n'essaie pas de pirater les composants internes du navigateur ou de créer quelque chose de super fantaisiste, expérimental ou à la pointe de la technologie.

Si vous pensez cela, alors je vous exhorte fortement à prendre du recul une seconde et à vraiment examiner les technologies que vous avez utilisées pour créer des sites Web au fil des ans. Vouloir accéder et s'accrocher au processus de style du navigateur ne consiste pas seulement à créer des démos fantaisistes - il s'agit de donner aux développeurs et aux auteurs de framework le pouvoir de faire deux choses principales :

  • pour normaliser les différences entre navigateurs,
  • pour inventer ou polyfill de nouvelles fonctionnalités afin que les gens puissent les utiliser aujourd'hui.

Si vous avez déjà utilisé une bibliothèque JavaScript telle que jQuery, vous avez déjà bénéficié de cette capacité ! En fait, c'est l'un des principaux arguments de vente de presque toutes les bibliothèques et frameworks frontaux actuels. Les cinq référentiels JavaScript et DOM les plus populaires sur GitHub - AngularJS, D3, jQuery, React et Ember - font tous beaucoup de travail pour normaliser les différences entre les navigateurs afin que vous n'ayez pas à y penser. Chacun expose une seule API, et cela fonctionne.

Maintenant, pensez à CSS et à tous ses problèmes inter-navigateurs. Même les frameworks CSS populaires tels que Bootstrap et Foundation qui revendiquent la compatibilité entre navigateurs ne normalisent pas réellement les bogues entre navigateurs - ils les évitent simplement. Et les bugs inter-navigateurs dans CSS ne sont pas seulement une chose du passé. Aujourd'hui encore, avec les nouveaux modules de mise en page tels que flexbox, nous sommes confrontés à de nombreuses incompatibilités entre navigateurs.

En fin de compte, imaginez à quel point votre vie de développement serait plus agréable si vous pouviez utiliser n'importe quelle propriété CSS et être sûr que cela fonctionnerait exactement de la même manière dans tous les navigateurs. Et pensez à toutes les nouvelles fonctionnalités que vous lisez dans les articles de blog ou dont vous entendez parler lors de conférences et de rencontres - des choses comme les grilles CSS, les points d'accrochage CSS et le positionnement collant. Imaginez si vous pouviez tous les utiliser aujourd'hui et d'une manière aussi performante que les fonctionnalités CSS natives. Et tout ce que vous avez à faire est de récupérer le code de GitHub.

C'est le rêve de Houdini. C'est l'avenir que le groupe de travail essaie de rendre possible.

Ainsi, même si vous n'envisagez jamais d'écrire un polyfill CSS ou de développer une fonctionnalité expérimentale, vous voudriez probablement que d'autres personnes puissent le faire, car une fois que ces polyfills existent, tout le monde en profite.

Quelles fonctionnalités Houdini sont actuellement en développement ?

J'ai mentionné ci-dessus que les développeurs ont très peu de points d'accès au pipeline de rendu du navigateur. Vraiment, les seuls endroits sont les DOM et, dans une certaine mesure, le CSSOM.

Pour résoudre ce problème, le groupe de travail Houdini a introduit plusieurs nouvelles spécifications qui permettront, pour la première fois, aux développeurs d'accéder aux autres parties du pipeline de rendu. Le tableau ci-dessous montre le pipeline et quelles nouvelles spécifications peuvent être utilisées pour modifier quelles étapes. (Notez que les spécifications en gris sont prévues mais doivent encore être écrites.)

Couverture des spécifications
Où les nouvelles spécifications Houdini s'intègrent dans le pipeline de rendu du navigateur. (Voir la grande version)

Les quelques sections suivantes donnent un bref aperçu de chaque nouvelle spécification et des types de fonctionnalités qu'elle offre. Je dois également noter que d'autres spécifications ne sont pas mentionnées dans cet article; pour la liste complète, consultez le référentiel GitHub des brouillons de Houdini.

API d'analyse CSS

L'API CSS Parser n'est actuellement pas écrite ; donc, une grande partie de ce que je dis pourrait facilement changer, mais l'idée de base est que cela permet aux développeurs d'étendre l'analyseur CSS et de lui parler de nouvelles constructions - par exemple, de nouvelles règles multimédias, de nouvelles pseudo-classes, l'imbrication, @extends , @apply , etc...

Une fois que l'analyseur connaît ces nouvelles constructions, il peut les placer au bon endroit dans le CSSOM, au lieu de simplement les supprimer.

API Propriétés et valeurs CSS

CSS a déjà des propriétés personnalisées et, comme je l'ai déjà dit, je suis très enthousiasmé par les possibilités qu'elles ouvrent. L'API CSS Properties and Values ​​va encore plus loin dans les propriétés personnalisées et les rend encore plus utiles en ajoutant des types.

L'ajout de types aux propriétés personnalisées présente de nombreux avantages, mais le principal argument de vente est peut-être que les types permettront aux développeurs de faire la transition et d'animer des propriétés personnalisées, ce que nous ne pouvons pas faire aujourd'hui.

Considérez cet exemple :

 body { --primary-theme-color: tomato; transition: --primary-theme-color 1s ease-in-out; } body.night-theme { --primary-theme-color: darkred; }

Dans le code ci-dessus, si la classe night-theme est ajoutée à l'élément <body> , alors chaque élément de la page qui fait référence à la valeur de la propriété –primary-theme-color passera lentement de tomato à darkred . Si vous vouliez le faire aujourd'hui, vous devriez écrire manuellement la transition pour chacun de ces éléments, car vous ne pouvez pas faire la transition de la propriété elle-même.

Une autre fonctionnalité prometteuse de cette API est la possibilité d'enregistrer un « crochet d'application », qui donne aux développeurs un moyen de modifier la valeur finale d'une propriété personnalisée sur les éléments une fois l'étape en cascade terminée, ce qui pourrait être une fonctionnalité très utile pour les polyfills.

CSS typé OM

CSS Typed OM peut être considéré comme la version 2 du CSSOM actuel. Son objectif est de résoudre de nombreux problèmes avec le modèle actuel et d'inclure des fonctionnalités ajoutées par la nouvelle API d'analyse CSS et l'API Propriétés et valeurs CSS.

Un autre objectif majeur de Typed OM est d'améliorer les performances. La conversion des valeurs de chaîne du CSSOM actuel en représentations JavaScript typées de manière significative entraînerait des gains de performances substantiels.

API de mise en page CSS

L'API CSS Layout permet aux développeurs d'écrire leurs propres modules de mise en page. Et par "module de mise en page", j'entends tout ce qui peut être transmis à la propriété display CSS. Cela donnera aux développeurs, pour la première fois, un moyen de mise en page aussi performant que les modules de mise en page natifs tels que display: flex et display: table .

À titre d'exemple de cas d'utilisation, la bibliothèque de mise en page Masonry montre jusqu'où les développeurs sont prêts à aller aujourd'hui pour réaliser des mises en page complexes impossibles avec CSS seul. Bien que ces dispositions soient impressionnantes, elles souffrent malheureusement de problèmes de performances, en particulier sur les appareils moins puissants.

L'API CSS Layout fonctionne en donnant aux développeurs une méthode registerLayout qui accepte un nom de mise en page (qui est ensuite utilisé dans CSS) et une classe JavaScript qui inclut toute la logique de mise en page. Voici un exemple de base de la façon dont vous pouvez définir la masonry via registerLayout :

 registerLayout('masonry', class { static get inputProperties() { return ['width', 'height'] } static get childrenInputProperties() { return ['x', 'y', 'position'] } layout(children, constraintSpace, styleMap, breakToken) { // Layout logic goes here. } }

Si rien dans l'exemple ci-dessus n'a de sens pour vous, ne vous inquiétez pas. La principale chose à prendre en compte est le code de l'exemple suivant. Une fois que vous avez téléchargé le fichier masonry.js et que vous l'avez ajouté à votre site Web, vous pouvez écrire du CSS comme ceci et tout fonctionnera :

 body { display: layout('masonry'); }

API de peinture CSS

L'API CSS Paint est très similaire à l'API Layout ci-dessus. Il fournit une méthode registerPaint qui fonctionne exactement comme la méthode registerLayout . Les développeurs peuvent ensuite utiliser la fonction paint() dans CSS partout où une image CSS est attendue et transmettre le nom qui a été enregistré.

Voici un exemple simple qui peint un cercle coloré :

 registerPaint('circle', class { static get inputProperties() { return ['--circle-color']; } paint(ctx, geom, properties) { // Change the fill color. const color = properties.get('--circle-color'); ctx.fillStyle = color; // Determine the center point and radius. const x = geom.width / 2; const y = geom.height / 2; const radius = Math.min(x, y); // Draw the circle \o/ ctx.beginPath(); ctx.arc(x, y, radius, 0, 2 * Math.PI, false); ctx.fill(); } });

Et il peut être utilisé en CSS comme ceci :

 .bubble { --circle-color: blue; background-image: paint('circle'); }

Maintenant, l'élément .bubble sera affiché avec un cercle bleu en arrière-plan. Le cercle sera centré et de la même taille que l'élément lui-même, quel qu'il soit.

Worklets

De nombreuses spécifications répertoriées ci-dessus affichent des exemples de code (par exemple, registerLayout et registerPaint ). Si vous vous demandez où placer ce code, la réponse se trouve dans les scripts de worklet.

Les worklets sont similaires aux web workers, et ils vous permettent d'importer des fichiers de script et d'exécuter du code JavaScript qui (1) peut être appelé à différents points du pipeline de rendu et (2) est indépendant du thread principal.

Les scripts de worklet restreindront fortement les types d'opérations que vous pouvez effectuer, ce qui est essentiel pour garantir des performances élevées.

Défilement et animation composites

Bien qu'il n'y ait pas encore de spécifications officielles pour le défilement et l'animation composites, c'est en fait l'une des fonctionnalités Houdini les plus connues et les plus attendues. Les API éventuelles permettront aux développeurs d'exécuter la logique dans un worklet de compositeur, hors du thread principal, avec la prise en charge de la modification d'un sous-ensemble limité des propriétés d'un élément DOM. Ce sous-ensemble inclura uniquement les propriétés qui peuvent être lues ou définies sans forcer le moteur de rendu à recalculer la mise en page ou le style (par exemple, transformation, opacité, décalage de défilement).

Cela permettra aux développeurs de créer des animations hautement performantes basées sur le défilement et les entrées, telles que des en-têtes de défilement collants et des effets de parallaxe. Vous pouvez en savoir plus sur les cas d'utilisation que ces API tentent de résoudre sur GitHub.

Bien qu'il n'y ait pas encore de spécification officielle, le développement expérimental a déjà commencé dans Chrome. En fait, l'équipe Chrome met actuellement en œuvre des points d'accrochage CSS et un positionnement collant à l'aide des primitives que ces API exposeront éventuellement. C'est incroyable car cela signifie que les API Houdini sont suffisamment performantes pour que de nouvelles fonctionnalités Chrome soient construites dessus. Si vous craigniez encore que Houdini ne soit pas aussi rapide que natif, ce seul fait devrait vous convaincre du contraire.

Pour voir un exemple réel, Surma a enregistré une démo vidéo fonctionnant sur une version interne de Chrome. La démo imite le comportement de l'en-tête de défilement vu dans les applications mobiles natives de Twitter. Pour voir comment cela fonctionne, consultez le code source.

Que pouvez-vous faire maintenant?

Comme mentionné, je pense que tous ceux qui créent des sites Web devraient se soucier de Houdini ; cela va rendre nos vies beaucoup plus faciles à l'avenir. Même si vous n'utilisez jamais directement une spécification Houdini, vous utiliserez presque certainement quelque chose construit au-dessus d'une.

Et même si cet avenir n'est peut-être pas immédiat, il est probablement plus proche que beaucoup d'entre nous ne le pensent. Des représentants de tous les principaux fournisseurs de navigateurs étaient à la dernière réunion en face à face de Houdini à Sydney plus tôt cette année, et il y avait très peu de désaccord sur ce qu'il fallait construire ou comment procéder.

D'après ce que j'ai pu dire, il ne s'agit pas de savoir si Houdini sera une chose, mais quand, et c'est là que vous intervenez tous.

Les fournisseurs de navigateurs, comme tous ceux qui créent des logiciels, doivent donner la priorité aux nouvelles fonctionnalités. Et cette priorité est souvent fonction de la façon dont les utilisateurs veulent ces fonctionnalités.

Donc, si vous vous souciez de l'extensibilité du style et de la mise en page sur le Web, et si vous voulez vivre dans un monde où vous pouvez utiliser de nouvelles fonctionnalités CSS sans avoir à attendre qu'elles passent par le processus de normalisation, parlez aux membres du équipes de relations avec les développeurs pour le(s) navigateur(s) que vous utilisez, et dites-leur que vous le souhaitez.

L'autre façon dont vous pouvez aider est de fournir des cas d'utilisation réels - des choses que vous voulez pouvoir faire avec le style et la mise en page qui sont difficiles ou impossibles à faire aujourd'hui. Plusieurs brouillons sur GitHub ont des documents de cas d'utilisation, et vous pouvez soumettre une demande d'extraction pour apporter vos idées. Si un document n'existe pas, vous pouvez en créer un.

Les membres du groupe de travail Houdini (et du W3C en général) veulent vraiment une contribution réfléchie de la part des développeurs Web. La plupart des personnes qui participent au processus de rédaction des spécifications sont des ingénieurs qui travaillent sur les navigateurs. Souvent, ils ne sont pas eux-mêmes des développeurs Web professionnels, ce qui signifie qu'ils ne savent pas toujours où se situent les points faibles.

Ils comptent sur nous pour leur dire.

Ressources et liens

  • CSS-TAG Houdini Editor Drafts, W3C La dernière version publique de tous les brouillons Houdini
  • CSS-TAG Houdini Task Force Specifications, GitHub Le référentiel Github officiel où les mises à jour et le développement des spécifications ont lieu
  • Exemples Houdini, exemples de code GitHub présentant et expérimentant des API possibles
  • Liste de diffusion Houdini, W3C Un endroit pour poser des questions générales

Remerciements particuliers aux membres Houdini Ian Kilpatrick et Shane Stephens pour la révision de cet article.