Fermer

mars 19, 2020

Un aperçu pratique de CSS Houdini


À propos de l'auteur

Adrian Bece est un développeur Frontend polyvalent avec une vaste expérience du commerce électronique qui travaille actuellement à PROTOTYP où il crée des interfaces étonnantes avec…
En savoir plus
Adrian

Houdini, terme générique désignant la collection d'API de navigateur, vise à apporter des améliorations significatives au processus de développement Web et au développement des normes CSS en général. Les développeurs frontend pourront étendre le CSS avec de nouvelles fonctionnalités en utilisant JavaScript, se connecter au moteur de rendu CSS et expliquer au navigateur comment appliquer le CSS pendant un processus de rendu. La prise en charge du navigateur Houdini s'améliore et certaines API sont disponibles pour une utilisation aujourd'hui, c'est donc le bon moment pour se familiariser avec elles et expérimenter. Nous allons jeter un œil à chaque partie de Houdini, son support de navigateur actuel et voir comment ils peuvent être utilisés aujourd'hui en utilisant l'amélioration progressive.

Il faut beaucoup de temps pour qu'une nouvelle fonctionnalité ou amélioration CSS progresse à partir d'un brouillon initial à une fonctionnalité CSS entièrement prise en charge et stable que les développeurs peuvent utiliser. Les polyfills basés sur JavaScript peuvent être utilisés pour remplacer le manque de prise en charge du navigateur afin d'utiliser de nouvelles fonctionnalités CSS avant leur mise en œuvre officielle. Mais ils sont imparfaits dans la plupart des cas. Par exemple, scrollsnap-polyfill est l'un des nombreux polyfills qui peuvent être utilisés pour corriger les incohérences de prise en charge du navigateur pour la spécification CSS Scroll Snap. Mais même cette solution présente des limites, des bogues et des incohérences.

L'inconvénient potentiel de l'utilisation des polyfills est qu'ils peuvent avoir un impact négatif sur les performances et qu'ils sont difficiles à mettre en œuvre correctement. Cet inconvénient est lié au DOM et au CSSOM du navigateur. Le navigateur crée un DOM (Document Object Model) à partir du balisage HTML et, de même, il a créé CSSOM (CSS Object Model) à partir du balisage CSS. Ces deux arbres d'objets sont indépendants l'un de l'autre. JavaScript fonctionne sur DOM et a un accès très limité à CSSOM.

Les solutions JavaScript Polyfill ne s'exécutent qu'une fois le cycle de rendu initial terminé, c'est-à-dire lorsque DOM et CSSOM ont été créés et que le document a fini de se charger. Une fois que Polyfill a apporté des modifications aux styles dans le DOM (en les insérant), il provoque le processus de rendu à nouveau et la page entière est à nouveau rendue. L'impact négatif sur les performances devient encore plus apparent s'ils s'appuient sur la méthode requestAnimationFrame ou dépendent des interactions des utilisateurs comme les événements de défilement.

Un autre obstacle au développement Web réside dans les diverses contraintes imposées par les normes CSS ]. Par exemple, il n'y a qu'un nombre limité de propriétés CSS pouvant être animées en mode natif. CSS sait comment animer nativement les couleurs, mais ne sait pas comment animer les dégradés. Il y a toujours eu un besoin d'innover et de créer des expériences Web impressionnantes en repoussant les limites malgré les limitations technologiques. C'est pourquoi les développeurs ont souvent tendance à utiliser des solutions de contournement moins qu'idéales ou JavaScript pour implémenter un style et des effets plus avancés qui ne sont actuellement pas pris en charge par CSS tels que la disposition de maçonnerie, les effets 3D avancés, l'animation avancée, la typographie fluide, les dégradés animés, éléments sélectionnés etc.

Il semble impossible que les spécifications CSS respectent les diverses demandes de fonctionnalités de l'industrie telles que plus de contrôle sur les animations , troncature de texte améliorée, meilleure option de style pour entrée et sélection des éléments plus affichage des options plus filtre options, etc.

] Quelle pourrait être la solution potentielle? Donnez aux développeurs une façon native d'étendre CSS à l'aide de diverses API . Dans cet article, nous allons voir comment les développeurs frontend peuvent le faire en utilisant les API Houdini, JavaScript et CSS. Dans chaque section, nous allons examiner chaque API individuellement, vérifier la prise en charge de son navigateur et l'état actuel des spécifications, et voir comment elles peuvent être implémentées aujourd'hui à l'aide de l'amélioration progressive.

Qu'est-ce que Houdini?

Houdini, un terme générique pour la collecte des API de navigateur, vise à apporter des améliorations significatives au processus de développement Web et au développement des normes CSS en général. Les développeurs pourront étendre le CSS avec de nouvelles fonctionnalités en utilisant JavaScript, se connecter au moteur de rendu CSS et expliquer au navigateur comment appliquer le CSS pendant un processus de rendu.

La spécification Houdini se compose de deux groupes d'API – API de haut niveau et API de bas niveau .

Les API de haut niveau sont étroitement liées au processus de rendu du navigateur (style → mise en page → peinture → composite). Cela comprend:

  • API Paint
    Un point d'extension pour l'étape de rendu de la peinture du navigateur où les propriétés visuelles (couleur, arrière-plan, bordure, etc.) sont déterminées.
  • API Layout
    Un point d'extension pour le navigateur étape de rendu de mise en page où les dimensions, la position et l'alignement des éléments sont déterminés.
  • API d'animation
    Un point d'extension pour l'étape de rendu composite du navigateur où les calques sont dessinés à l'écran et animés.

API de bas niveau s constituent une base pour les API de haut niveau. Cela inclut:

  • API de modèle d'objet typé
  • API de propriétés et valeurs personnalisées
  • API de métriques de police
  • Worklets

Certaines API Houdini sont déjà disponibles pour une utilisation dans certains navigateurs avec d'autres

L'avenir du CSS

Contrairement aux spécifications de fonctionnalités CSS habituelles qui ont été introduites jusqu'à présent, Houdini se démarque en permettant aux développeurs d'étendre le CSS d'une manière plus native. Est-ce à dire que les spécifications CSS cesseront d'évoluer et qu'aucune nouvelle implémentation officielle des fonctionnalités CSS ne sera publiée? Eh bien, ce n'est pas le cas. Le but de Houdini est d'aider le processus de développement des fonctionnalités CSS en permettant aux développeurs de créer des prototypes de travail qui peuvent être facilement standardisés.

De plus, les développeurs pourront partager les Worklets CSS open source plus facilement et avec moins de besoin de navigateur spécifique

API de modèle d'objet typé

Avant l'introduction de Houdini, le seul moyen pour JavaScript d'interagir avec CSS était d'analyser le CSS représenté comme des valeurs de chaîne et de les modifier. L'analyse et la substitution des styles manuellement peuvent être difficiles et sujettes aux erreurs car le type de valeur doit être changé d'avant en arrière et l'unité de valeur doit être ajoutée manuellement lors de l'attribution d'une nouvelle valeur.

 selectedElement.style.fontSize = newFontSize + " px "; // newFontSize = 20
console.log (selectedElement.style.fontSize); // "20px"

Modèle d'objet typé (OM typé) L'API ajoute plus de signification sémantique aux valeurs CSS en les exposant comme des objets JavaScript typés. Il améliore considérablement le code associé et le rend plus performant, stable et maintenable. Les valeurs CSS sont représentées par l'interface CSSUnitValue qui se compose d'une valeur et d'une propriété unit.

 {
  valeur: 20,
  unité: "px"
}

Cette nouvelle interface peut être utilisée avec les nouvelles propriétés suivantes:

  • computedStyleMap () : pour analyser les styles calculés (non en ligne). Il s'agit d'une méthode de l'élément sélectionné qui doit être invoquée avant l'analyse ou l'utilisation d'autres méthodes.
  • attributeStyleMap : pour analyser et modifier les styles en ligne. Il s'agit d'une propriété disponible sur un élément sélectionné.
 // Récupère les styles calculés à partir de la feuille de style (valeur initiale)
selectedElement.computedStyleMap (). get ("font-size"); // {valeur: 20, unité: "px"}

// Définir des styles en ligne
selectedElement.attributeStyleMap.set ("taille de police", CSS.em (2)); // Définit le style en ligne
selectedElement.attributeStyleMap.set ("couleur", "bleu"); // Définit le style en ligne

// Le style calculé reste le même (valeur initiale)
selectedElement.computedStyleMap (). get ("font-size"); // {valeur: 20, unité: "px"}

// Obtenez un nouveau style en ligne
selectedElement.attributeStyleMap.get ("font-size"); // {valeur: 2, unité: "em"}

Remarquez comment des types CSS spécifiques sont utilisés lors de la définition d'une nouvelle valeur numérique. En utilisant cette syntaxe, de nombreux problèmes potentiels liés au type peuvent être évités et le code résultant est plus fiable et sans bogue.

Les méthodes get et set ne sont qu'une petite sous-ensemble de toutes les méthodes disponibles définies par l'API Typed OM. Certains d'entre eux incluent:

  • clear : supprime tous les styles en ligne
  • supprime : supprime une propriété CSS spécifiée et sa valeur des styles en ligne
  • a : renvoie un booléen si une propriété CSS spécifiée est définie
  • append : ajoute une valeur supplémentaire à une propriété qui prend en charge plusieurs valeurs
  • etc.

Détection d'entité

 var selectedElement = document.getElementById ("exemple");

if (selectedElement.attributeStyleMap) {
  / * ... * /
}

if (selectedElement.computedStyleMap) {
  / * ... * /
}

État des spécifications W3C

Prise en charge du navigateur

Google Chrome Microsoft Edge Navigateur Opera Firefox Safari
Pris en charge Pris en charge Pris en charge Non prise en charge Prise en charge partielle (*)

* prise en charge avec «Fonctionnalités de la plateforme Web expérimentale» ou autre indicateur de fonctionnalité activé.

Source de données: Houdini est-il déjà prêt?

API Propriétés et valeurs personnalisées

L'API Propriétés et valeurs CSS permet aux développeurs d'étendre les variables CSS en ajoutant un type, une valeur initiale et de définir l'héritage. Les développeurs peuvent définir des propriétés personnalisées CSS en les enregistrant à l'aide de la méthode registerProperty qui indique aux navigateurs comment effectuer la transition et gérer le repli en cas d'erreur.

 CSS.registerProperty ({
  nom: "--colorPrimary",
  syntaxe: "",
  hérite: faux,
  initialValue: "blue",
});

Cette méthode accepte un argument d'entrée qui est un objet avec les propriétés suivantes:

  • nom : le nom de la propriété personnalisée
  • syntaxe : indique au navigateur comment pour analyser une propriété personnalisée. Ce sont des valeurs prédéfinies comme etc.
  • hérite : indique au navigateur si la propriété personnalisée hérite de celle de son parent
  • initialValue : indique la valeur initiale utilisée jusqu'à ce qu'elle soit remplacée et utilisée comme solution de rechange en cas d'erreur.

Dans l'exemple suivant, le type personnalisé la propriété est en cours de définition. Cette propriété personnalisée va être utilisée dans la transition de dégradé. Vous pensez peut-être que le CSS actuel ne prend pas en charge les transitions pour les dégradés d'arrière-plan et vous auriez raison. Remarquez comment la propriété personnalisée elle-même est utilisée dans la transition au lieu d'une propriété d'arrière-plan qui serait utilisée pour les transitions régulières de couleur d'arrière-plan .

. gradientBox {
  fond: gradient linéaire (45deg, rgba (255,255,255,1) 0%, var (- colorPrimary) 60%);
  transition: --colorPrimary 0.5s facilité;
  / * ... * /
}

.gradientBox: hover {
  - couleur Primaire: rouge
  / * ... * /
}

Le navigateur ne sait pas comment gérer la transition de dégradé, mais il sait comment gérer les transitions de couleur car la propriété personnalisée est spécifiée comme type . Sur un navigateur qui prend en charge Houdini, une transition de dégradé se produit lorsque l'élément est survolé. Le pourcentage de position du dégradé peut également être remplacé par une propriété personnalisée CSS (enregistrée en tant que type ) et ajouté à une transition de la même manière que dans l'exemple.

Si registerProperty est supprimé et un CSS standard la propriété personnalisée est enregistrée dans un sélecteur : root la transition de dégradé ne fonctionnera pas. Il est nécessaire que registerProperty soit utilisé pour que le navigateur sache qu'il doit le traiter comme une couleur.

Dans l'implémentation future de cette API, il serait possible d'enregistrer une propriété personnalisée directement dans CSS. [19659031] @property –colorPrimary {
  syntaxe: "";
  hérite: faux;
  valeur initiale: bleu;
}

Exemple

Cet exemple simple présente une couleur dégradée et une transition de position lors d'un survol en utilisant des propriétés personnalisées CSS enregistrées pour la couleur et la position respectivement. Le code source complet est disponible dans l'exemple de référentiel .

Couleur et position du dégradé animé à l'aide de l'API Custom Properties & Values. Délai pour chaque propriété ajoutée pour effet dans la propriété de transition CSS. ( Grand aperçu )

Détection de fonction

 if (CSS.registerProperty) {
  / * ... * /
}

État des spécifications W3C

Prise en charge du navigateur

Google Chrome Microsoft Edge Navigateur Opera Firefox Safari
Pris en charge Pris en charge Pris en charge Non pris en charge Non pris en charge

Source de données: Houdini est-il encore prêt?

API de métriques de police

L'API de métriques de polices est encore à un stade très précoce de développement, donc ses spécifications pourraient changer à l'avenir. Dans sa version actuelle, API de mesure des polices fournira des méthodes pour mesurer les dimensions des éléments de texte qui sont rendus à l'écran afin de permettre aux développeurs d'affecter la façon dont les éléments de texte sont rendus à l'écran. Ces valeurs sont difficiles ou impossibles à mesurer avec les fonctionnalités actuelles, donc cette API permettra aux développeurs de créer plus facilement des fonctionnalités CSS liées au texte et aux polices. La troncature de texte dynamique sur plusieurs lignes est un exemple de l'une de ces fonctionnalités.

État des spécifications W3C

Prise en charge du navigateur

Google Chrome Microsoft Edge Navigateur Opera Firefox Safari [19659054] Non pris en charge Non pris en charge Non pris en charge Non pris en charge Non pris en charge

Source de données: Houdini est-il déjà prêt?

Worklets

Avant de passer à l'autre API, il est important d'expliquer le concept Worklets. Les worklets sont des scripts qui s'exécutent pendant le rendu et sont indépendants de l'environnement JavaScript principal. Ils sont un point d'extension pour les moteurs de rendu. Ils sont conçus pour le parallélisme (avec 2 instances ou plus) et agnostiques aux threads, ont un accès réduit à la portée globale et sont appelés par le moteur de rendu en cas de besoin. Les worklets peuvent être exécutés uniquement sur HTTPS (sur l'environnement de production) ou sur l'hôte local (à des fins de développement).

Houdini présente les worklets suivants pour étendre le moteur de rendu du navigateur:

  • Paint Worklet – Paint API
  • Animation Worklet – Animation API
  • Layout Worklet – Layout API

Paint API

L'API Paint permet aux développeurs d'utiliser des fonctions JavaScript pour dessiner directement dans l'arrière-plan, la bordure ou le contenu d'un élément à l'aide de Contexte de rendu 2D qui est un sous-ensemble de l'API HTML5 Canvas. L'API Paint utilise Paint Worklet pour dessiner une image qui répond dynamiquement aux changements dans CSS (changements dans les variables CSS, par exemple). Toute personne familiarisée avec l'API Canvas se sentira à l'aise avec l'API Paint de Houdini.

La définition d'un Worklet Paint nécessite plusieurs étapes:

  1. Écrivez et enregistrez un Worklet Paint à l'aide de la fonction registerPaint
  2. ] Appelez le Worklet dans un fichier HTML ou un fichier JavaScript principal à l'aide de la fonction CSS.paintWorklet.addModule
  3. Utilisez la fonction paint () en CSS avec un nom de Worklet et des arguments d'entrée facultatifs.

Jetons un coup d'oeil à la fonction registerPaint qui est utilisée pour enregistrer un Worklet de peinture et définir sa fonctionnalité.

 registerPaint ("paintWorketExample", classe {
  static get inputProperties () {return ["--myVariable"]; }
  static get inputArguments () {return [""]; }
  static get contextOptions () {return {alpha: true}; }

  peinture (ctx, taille, propriétés, args) {
    / * ... * /
  }
});

La fonction registerPaint se compose de plusieurs parties:

  • inputProperties :
    Un tableau de propriétés personnalisées CSS dont le Worklet gardera trace. Ce tableau représente les dépendances d'un worklet de peinture.
  • inputArguments :
    Un tableau d'arguments d'entrée pouvant être transmis à partir de paint fonctionne depuis l'intérieur du CSS.
  • contextOptions : autorise ou interdit l'opacité des couleurs. Si la valeur est false toutes les couleurs seront affichées en pleine opacité.
  • paint : la fonction principale qui fournit les arguments suivants:
    • ctx : dessin 2D contexte, presque identique au contexte de dessin 2D de l'API Canvas.
    • taille : objet contenant la largeur et la hauteur de l'élément. Les valeurs sont déterminées par le processus de rendu de mise en page. La taille du canevas est la même que la taille réelle de l'élément.
    • propriétés : variables d'entrée définies dans inputProperties
    • args : tableau d'entrées arguments passés dans fonction paint dans CSS

Une fois le Worklet enregistré, il doit être invoqué dans le fichier HTML en fournissant simplement un chemin d'accès au fichier.

 CSS.paintWorklet.addModule ("chemin / vers / worklet / fichier.js");

Tout worklet peut également être ajouté à partir d'une URL externe (à partir d'un réseau de diffusion de contenu, par exemple), ce qui les rend modulaires et réutilisables.

 CSS.paintWorklet.addModule ("https: // url / to / worklet / fichier.js ");

Une fois le Worklet appelé, il peut être utilisé dans CSS à l'aide de la fonction paint . Cette fonction accepte le nom enregistré du Worklet comme premier argument d'entrée et chaque argument d'entrée qui le suit est un argument personnalisé qui peut être transmis à un Worklet (défini dans les InputArguments input du Worklet). À partir de ce moment, le navigateur détermine à quel moment appeler le Worklet et à quelles actions utilisateur et à quelle valeur de propriétés personnalisées CSS il faut répondre.

 .exampleElement {
  / * paintWorkletExample - nom du worklet
     bleu - argument passé à un Worklet * /
  image de fond: peinture (paintWorketExample, bleu);
}

Exemple

L'exemple suivant présente l'API Paint et la réutilisabilité et la modularité générales du Worklet. Il utilise le Worklet d'entraînement directement à partir du référentiel Google Chrome Labs et s'exécute sur un élément différent avec des styles différents. Le code source complet est disponible dans le référentiel d'exemples .

Exemple d'effet d'ondulation (utilise Ripple Worklet de Google Chrome Labs) ( Grand aperçu )

Détection de fonctionnalité

 si ("paintWorklet" en CSS) {
  / * ... * /
}


@supports (arrière-plan: paint (paintWorketExample)) {
  / * ... * /
}

État des spécifications W3C

Prise en charge du navigateur

Google Chrome Microsoft Edge Navigateur Opera Firefox Safari
Pris en charge Pris en charge Pris en charge Non pris en charge Non pris en charge

Source de données: Houdini est-il encore prêt?

API d'animation

L'API Animation étend les animations Web avec des options pour écouter divers événements (défilement, survolez, cliquez, etc.) et améliore les performances en exécutant des animations sur leur propre thread dédié à l'aide d'un Worklet d'animation. Il permet à l'utilisateur de contrôler le flux d'animation qui s'exécute de manière performante et non bloquante.

Comme tout worklet, le worklet d'animation doit d'abord être enregistré.

 registerAnimator ("animationWorkletExample", classe {
  constructeur (options) {
    / * ... * /
  }
  animate (currentTime, effect) {
    / * ... * /
  }
});

Cette classe comprend deux fonctions:

  • constructeur : appelé lorsqu'une nouvelle instance est créée. Utilisé pour la configuration générale.
  • animate : la fonction principale qui contient la logique d'animation. Fournit les arguments d'entrée suivants:
    • currentTime : la valeur d'heure actuelle de la chronologie définie
    • effet : un tableau d'effets que cette animation utilise

Une fois le worklet d'animation enregistré, il doit être inclus dans le fichier JavaScript principal l'animation (élément, images clés, options) doit être définie et l'animation est instanciée avec la chronologie sélectionnée. Les concepts de la chronologie et les principes de base de l'animation Web seront expliqués dans la section suivante.

 / * Inclure le worklet d'animation * /
attendre CSS.animationWorklet.addModule ("chemin / vers / worklet / fichier.js") ;;

/ * Sélectionnez l'élément qui va être animé * /
const elementExample = document.getElementById ("elementExample");

/ * Définir l'animation (effet) * /
const effectExample = new KeyframeEffect (
  elementExample, / * Élément sélectionné qui va être animé * /
  [ /* ... */ ]/ * Images clés d'animation * /
  {/ * ... * /}, / * Options d'animation - durée, délai, itérations, etc. * /
);

/ * Créez une nouvelle instance de WorkletAnimation et exécutez-la * /
nouvelle WorkletAnimation (
  "animationWorkletExample" / * Nom du worklet * /
  effectExample, / * Chronologie d'animation (effet) * /
  document.timeline, / * Chronologie d'entrée * /
  {}, / * Options passées au constructeur * /
).jouer(); / * Lire l'animation * /

Mappage de chronologie

L'animation Web est basée sur des chronologies et de mappage de l'heure actuelle sur une chronologie de l'heure locale d'un effet . Par exemple, regardons une animation linéaire répétitive avec 3 images clés (début, milieu, dernière) qui s'exécute 1 seconde après le chargement d'une page (délai) et avec une durée de 4 secondes.

Chronologie des effets de l'exemple ressemblerait à ceci (avec la durée de 4 secondes sans délai):

Chronologie des effets (durée de 4 s) Image clé
0 ms Première image clé – l'animation démarre
2000 ms Image clé centrale – animation en cours
4000ms Dernière image clé – l'animation se termine ou se réinitialise sur la première image clé

Afin de mieux comprendre effect.localTime en définissant sa valeur à 3000ms (en tenant compte de 1000ms délai), l'animation résultante va être verrouillée sur une image clé du milieu dans la chronologie d'effet (délai de 1000 ms + 2000 ms pour une image clé du milieu). Le même effet va se produire en définissant la valeur sur 7000 ms et 11 000 ms car l'animation se répète à 4000 ms d'intervalle (durée de l'animation).

 animate (currentTime, effect) {
  effect.localTime = 3000; // Délai de 1000 ms + image clé du milieu de 2000 ms
}

Aucune animation ne se produit lorsque la valeur effect.localTime est constante car l'animation est verrouillée dans une image clé spécifique. Afin d'animer correctement un élément, son effect.localTime doit être dynamique. Il est nécessaire que la valeur soit une fonction qui dépend de l'argument d'entrée currentTime ou d'une autre variable.

Le code suivant montre une représentation fonctionnelle du mappage 1: 1 (fonction linéaire) d'une chronologie vers effect local time.

 animate (currentTime, effect) {
  effect.localTime = currentTime; // y = x fonction linéaire
}
Chronologie ( document.timeline ) Effet mappé heure locale Image clé
startTime + 0 ms (temps écoulé) startTime + 0ms First
startTime + 1000ms (temps écoulé) startTime + 1000ms (retard) + 0ms First
startTime + 3000ms (temps écoulé) startTime + 1000ms (retard) + 2000ms Moyen
startTime + 5000ms (temps écoulé) [19659055] startTime + 1000ms (délai) + 4000ms Dernier / Premier
startTime + 7000ms (temps écoulé) startTime + 1000ms ( retard) + 6000 ms Moyen
startTime + 9000 ms (temps écoulé) startTime + 1000 ms (retard) + 8000 ms Dernier / premier

La chronologie n'est pas limitée à 1 : 1 mappage pour effectuer l'heure locale. L'API d'animation permet aux développeurs de manipuler le mappage de la chronologie dans la fonction d'animation en utilisant des fonctions JavaScript standard pour créer des chronologies complexes. L'animation n'a pas non plus à se comporter de la même manière à chaque itération (si l'animation est répétée).

L'animation n'a pas à dépendre de la chronologie du document qui ne commence à compter les millisecondes qu'à partir du moment où il est chargé. Les actions de l'utilisateur comme les événements de défilement peuvent être utilisées comme chronologie pour l'animation en utilisant un objet ScrollTimeline . Par exemple, une animation peut démarrer lorsqu'un utilisateur a défilé jusqu'à 200 pixels et peut se terminer lorsqu'un utilisateur a défilé jusqu'à 800 pixels sur un écran.

 const scrollTimelineExample = new ScrollTimeline ({
  scrollSource: scrollElement, / * élément DOM dont l'action de défilement est suivie * /
  orientation: "vertical", / * Sens de défilement * /
  startScrollOffset: "200px", / * Début de la chronologie de défilement * /
  endScrollOffset: "800px", / * Fin de la chronologie de défilement * /
  timeRange: 1200, / * Durée à mapper pour faire défiler les valeurs * /
  fill: "forwards" / * Mode de remplissage d'animation * /
});

...

L'animation s'adaptera automatiquement à la vitesse de défilement de l'utilisateur et restera fluide et réactive. Étant donné que les worklets d'animation s'exécutent sur le thread principal et sont connectés au moteur de rendu d'un navigateur, l'animation qui dépend du défilement de l'utilisateur peut s'exécuter sans problème et être très performante.

Exemple

L'exemple suivant montre comment une implémentation de chronologie non linéaire . Il utilise la fonction gaussienne modifiée et applique une animation de translation et de rotation avec la même chronologie. Le code source complet est disponible dans le référentiel d'exemples .

Animation créée avec l'API d'animation qui utilise le mappage temporel de la fonction gaussienne modifiée ( Grand aperçu )

Détection de fonctionnalité

 if (CSS.animationWorklet) {
  / * ... * /
}

État des spécifications W3C

Prise en charge du navigateur

Google Chrome Microsoft Edge Navigateur Opera Firefox Safari
Prise en charge partielle (*) Prise en charge partielle (*) Prise en charge partielle (*) Non prise en charge Non prise en charge

* prise en charge avec l'indicateur «Fonctionnalités de la plateforme Web expérimentale» activé.

Source de données: ] Houdini est-il encore prêt?

API de mise en page

L'API Mise en page permet aux développeurs d'étendre le processus de rendu de mise en page du navigateur en définissant de nouveaux modes de mise en page qui peuvent être utilisés dans l'affichage CSS . propriété. L'API de mise en page présente de nouveaux concepts, est très complexe et offre de nombreuses options pour développer des algorithmes de mise en page personnalisés.

Comme pour les autres Worklets, le Worklet de mise en page doit être enregistré et défini en premier.

 registerLayout ('exampleLayout', class {
  static get inputProperties () {return ['--exampleVariable']; }

  static get childrenInputProperties () {return ['--exampleChildVariable']; }

  statique get layoutOptions () {
    revenir {
      childDisplay: 'normal',
      dimensionnement: "en bloc"
    };
  }

  intrinsicSizes (enfants, bords, styleMap) {
    / * ... * /
  }

  layout (enfants, arêtes, contraintes, styleMap, breakToken) {
    / * ... * /
  }
});

Le registre du worklet contient les méthodes suivantes:

  • inputProperties :
    Un tableau de propriétés personnalisées CSS dont le worklet gardera trace appartient à un élément Layout parent, c'est-à-dire l'élément qui appelle cette disposition. Ce tableau représente les dépendances d'un Worklet de mise en page.
  • childrenInputProperties :
    Un tableau de propriétés personnalisées CSS dont le Worklet gardera trace qui appartiennent aux éléments enfants d'un élément Layout parent, c'est-à-dire les enfants des éléments qui définissent cette disposition.
  • layoutOptions : définit les propriétés de disposition suivantes:
    • childDisplay : peut avoir une valeur prédéfinie de bloc ou normal . Détermine si les cases seront affichées sous forme de blocs ou en ligne.
    • dimensionnement : peut avoir une valeur prédéfinie de en forme de bloc ou manuel . Il indique au navigateur de pré-calculer la taille ou de ne pas pré-calculer (sauf si une taille est explicitement définie), respectivement.
  • intrinsicSizes : définit comment une boîte ou
    • enfants : éléments enfants d'un élément Parent Layout, c'est-à-dire les enfants de l'élément qui appelle cette disposition.
    • bords : Layout Edges of a boîte
    • styleMap : styles OM dactylographiés d'une boîte
  • mise en page : la fonction principale qui effectue une mise en page.
    • enfants : éléments enfants d'un élément Parent Layout, c'est-à-dire les enfants de l'élément qui appelle cette disposition.
    • bords : Layout Edges of a box
    • contraintes : contraintes d'un Disposition parent
    • styleMap : styles OM tapés d'une boîte
    • breakToken : jeton de rupture utilisé pour reprendre une mise en page t en cas de pagination ou d'impression.

Comme dans le cas d'une API Paint, le moteur de rendu du navigateur détermine quand le Worklet de peinture est appelé. Il suffit de l'ajouter à un fichier HTML ou JavaScript principal.

 CSS.layoutWorklet.addModule ('path / to / worklet / file.js');

Et, enfin, il doit être référencé dans un fichier CSS

 .exampleElement {
  affichage: mise en page (exampleLayout);
}

Comment l'API de mise en page exécute la mise en page

Dans l'exemple précédent, exampleLayout a été défini à l'aide de l'API de mise en page.

 .exampleElement {
  affichage: mise en page (exampleLayout);
}

Cet élément est appelé Disposition parent qui est inclus avec Layout Edges qui se compose de rembourrages, de bordures et de barres de défilement. La disposition parent consiste en éléments enfants appelés Présentations actuelles . Current Layouts are the actual target elements whose layout can be customized using the Layout API. For example, when using display: flex; on an element, its children are being repositioned to form the flex layout. This is similar to what is being done with the Layout API.

Each Current Layout consists of Child Layout which is a layout algorithm for the LayoutChild (element, ::before and ::after pseudo-elements) and LayoutChild is a CSS generated box that only contains style data (no layout data). LayoutChild elements are automatically created by browser rendering engine on style step. Layout Child can generate a Fragment which actually performs layout render actions.

Example

Similarly to the Paint API example, this example is importing a masonry layout Worklet directly from Google Chrome Labs repositorybut in this example, it’s used with image content instead of text. Complete source code is available on the example repository.

Masonry layout example (uses Masonry Worklet by Google Chrome Labs (Large preview)

Feature Detection

if (CSS.layoutWorklet) {
  /* ... */
}

W3C Specification Status

Browser Support

Google ChromeMicrosoft EdgeOpera BrowserFirefoxSafari
Partial support (*)Partial support (*)Partial support (*)Not supportedNot supported

*supported with “Experimental Web Platform features” flag enabled.

Data source: Is Houdini Ready Yet?

Houdini And Progressive Enhancement

Even though CSS Houdini doesn’t have optimal browser support yet, it can be used today with progressive enhancement in mind. If you are unfamiliar with Progressive enhancement, it would be worth to check out this handy article which explains it really well. If you decide on implementing Houdini in your project today, there are few things to keep in mind:

  • Use feature detection to prevent errors.
    Each Houdini API and Worklet offers a simple way of checking if it’s available in the browser. Use feature detection to apply Houdini enhancements only to browsers that support it and avoid errors.
  • Use it for presentation and visual enhancement only.
    Users that are browsing a website on a browser that doesn’t yet support Houdini should have access to the content and core functionality of the website. User experience and the content presentation shouldn’t depend on Houdini features and should have a reliable fallback.
  • Make use of a standard CSS fallback.
    For example, regular CSS Custom Properties can be used as a fallback for styles defined using Custom Properties & Values API.

Focus on developing a performant and reliable website user experience first and then use Houdini features for decorative purposes as a progressive enhancement.

Conclusion

Houdini APIs will finally enable developers to keep the JavaScript code used for style manipulation and decoration closer to the browser’s rendering pipeline, resulting in better performance and stability. By allowing developers to hook into the browser rendering process, they will be able to develop various CSS polyfills that can be easily shared, implemented and, potentially, added to CSS specification itself. Houdini will also make developers and designers less constrained by the CSS limitations when working on styling, layouts, and animations, resulting in new delightful web experiences.

CSS Houdini features can be added to projects today, but strictly with progressive enhancement in mind. This will enable browsers that do not support Houdini features to render the website without errors and offer optimal user experience.

It’s going to be exciting to watch what the developer community will come up with as Houdini gains traction and better browser support. Here are some awesome examples of Houdini API experiments from the community:

References

Smashing Editorial(ra, il)






Source link