Les actualités du Lundi 01 juin 2020 dans les métiers du web - Marmits.com - Reims

Le: 01 06 2020 à 23:48 WebdesignerNews

https://thenextweb.com/syndication/2020/05/31/7-strategies-to-design-landing-pages-that-convert-in-2020/

Le: 01 06 2020 à 23:04 korben.info Auteur: Korben

Attention les amis, vous n’allez pas en croire vos yeux, mais un simple fond d’écran à la faculté de faire crasher certains smartphones Android dont certains Samsung Galaxy comme le Note 9 ou le S20 Ultra ou encore des smartphones de chez Google comme le Pixel 3 XL. Le problème … Suite

Le: 01 06 2020 à 22:01 WebdesignerNews

https://dribbble.com/stories/2020/06/01/design-with-your-inner-child

Le: 01 06 2020 à 21:57 presse-citron.net Auteur: Christopher Klippel

Message PS5 Evenement Repoussé

C'est officiel, l'événement pour dévoiler les premiers jeux PS5 le 4 juin 2020 est repoussé à une date inconnue en raison des violentes émeutes aux États-Unis.

Le: 01 06 2020 à 21:57 WebdesignerNews

https://www.fastcompany.com/90511044/google-search-will-now-favor-websites-with-great-ux

Le: 01 06 2020 à 21:00 presse-citron.net Auteur: Setra

logo Apple

De plus en plus de sources suggèrent que les prochains iPhone d’Apple pourraient arriver sur le marché au mois d’octobre au lieu du mois de septembre.

Le: 01 06 2020 à 20:26 WebdesignerNews

https://designshack.net/articles/trends/transparent-text-bold-background/

Le: 01 06 2020 à 20:00 presse-citron.net Auteur: Hadrien Augusto

Vivo X50

Comme promis, le module photo embarque une toute nouvelle technologie permettant une stabilisation professionnelle de l’image.

Le: 01 06 2020 à 19:58 Framablog Auteur: Framalang

Pour la culture libre, le problème du financement est souvent crucial. Voici la proposition d’une sorte de petite bourse de « débutant sur PeerTube » qui nous fait plaisir et que nous vous invitons à considérer. Sourcehut qui fait cette offre est … Lire la suite­­

Le: 01 06 2020 à 19:53 WebdesignerNews

https://www.designweek.co.uk/issues/1-7-june-2020/furlough-freelance-scheme-change/

Le: 01 06 2020 à 19:30 presse-citron.net Auteur: Hadrien Augusto

YouTube don George Floyd

Précédemment critiqué à ce sujet, YouTube s’est impliqué dans la lutte contre les injustices sociales, à la suite de la mort de George Floyd.

Le: 01 06 2020 à 19:00 presse-citron.net Auteur: Louise Millon

salto rentree 2020

La plateforme de streaming Salto entre dans une nouvelle étape de tests qui durera jusqu'à son lancement prévu pour cet automne.

Le: 01 06 2020 à 18:32 WebdesignerNews

https://speckyboy.com/freelance-web-design-business-post-pandemic/

Le: 01 06 2020 à 18:10 presse-citron.net Auteur: Florian Pauly

Bon plans VPN

La fin des French Days approche, il ne vous reste que quelques heures pour profiter de promos pour vous offrir un VPN à prix cassé.

Le: 01 06 2020 à 18:00 presse-citron.net Auteur: Setra

iPad Pro 2020

Apple aurait demandé à un fournisseur de produire rapidement des panneaux LCD pour l’iPad à cause d’une forte hausse de la demande pour ses tablettes en Asie.

Le: 01 06 2020 à 17:46 WebdesignerNews

https://www.awwwards.com/sites/ivan-toma

Le: 01 06 2020 à 17:15 presse-citron.net Auteur: Setra

test xiaomi mi 10 design

Gartner indique que durant le premier trimestre, « les ventes mondiales de smartphones aux utilisateurs finaux » ont diminué de 20,2 %. Parmi les 5 principaux constructeurs, seul Xiaomi a vu ses ventes augmenter (de 1,4 %) durant ces trois premiers mois.

Le: 01 06 2020 à 17:10 WebdesignerNews

https://www.webdesignerdepot.com/2020/06/3-essential-design-trends-june-2020/

Le: 01 06 2020 à 17:01 Journal du Net Développeurs

Nous parlons aujourd'hui de trois moyens pour évaluer les campagnes de netlinking. En utilisant les trois méthodes suivantes, vous pouvez mesurer et vous rendre compte du succès et de vos efforts en matière de création de liens.

Le: 01 06 2020 à 17:00 korben.info Auteur: Korben

Vous connaissez tous sans aucun doute, Audacity, le logiciel libre qui permet de retravailler tout ce qui est du domaine de l’audio. Mais pour un besoin encore plus ponctuel, sans rien installer, je vous invite à tester AudioMass, un éditeur audio 100% web que vous pouvez même installer chez vous … Suite

Le: 01 06 2020 à 16:38 WebdesignerNews

https://designxplorer.co/best-ui-interactions-of-the-month-may-2020/

Le: 01 06 2020 à 16:30 presse-citron.net Auteur: Setra

Xiaomi logo

Le prochain bracelet connecté de Xiaomi devrait être présenté le 11 juin. Parmi les nouveautés, il pourrait y avoir la prise en charge de l’assistant Alexa, un capteur SpO2, ainsi qu’un module NFC.

Le: 01 06 2020 à 15:45 presse-citron.net Auteur: Jean-Yves Alric

Trump

La plupart des salariés du secteur soutiennent l’initiative de Twitter.

Le: 01 06 2020 à 15:35 codrops Auteur: Mary Lou

Some modern UI animation shots to keep you up-to-date with the freshest trends.

The post UI Interactions & Animations Roundup #7 appeared first on Codrops.

Le: 01 06 2020 à 15:32 Journal du Net Développeurs

Le secteur de la vente au détail a beaucoup souffert ces dernières semaines. Selon une étude MacKinsey, 44% des emplois du secteur du commerce de gros et de détail seraient menacés en Europe et ce, alors même qu'il est soumis à une énorme pression pour assurer un service le plus normal possible.

Le: 01 06 2020 à 15:30 Les dossiers référencement de WebRankInfo Auteur: Olivier Duffez

Avez-vous des pages zombies sur votre site ? Avec une performance SEO nulle ou très mauvaise, un contenu et un intérêt très faibles, elles plombent votre référencement. RM Tech les détecte, les classe et vous aide à savoir quoi en faire.

Le: 01 06 2020 à 15:23 korben.info Auteur: Korben

Nouvel épisode de notre émission hebdomadaire avec l’ami Rémi de DansTonChat ! Et cette semaine nous revenons avec un 3e Quizosaure histoire de jouer tous ensemble (comme environ chaque mois dorénavant). Et comme nous aimons bien tester de nouvelles choses régulièrement le jeu de cette semaine est différent des 2 … Suite

Le: 01 06 2020 à 15:18 Journal du Net Développeurs

Un des enseignements majeurs de la crise que nous traversons, c'est que la distanciation sociale appelle la digitalisation ! Moins de contacts physiques implique plus de contacts dématérialisés. Pour les marques, le digital n'est pas seulement une opportunité mais un devoir dans le monde post-confiné.

Le: 01 06 2020 à 15:00 presse-citron.net Auteur: Arthur Vera

Mark Zuckerberg

Zuckerberg a fait une déclaration surprenante qu'il pourrait rapidement regretté.

Le: 01 06 2020 à 14:40 CreativeJuiz blog Auteur: Geoffrey Crofte

Lorsque vous devez travailler sur des interfaces, le contraste des couleurs est une réalité dont vous devez tenir compte pour la rendre accessible. Vous avez le droit de craindre de perdre une partie de l’esthétique de votre interface, notamment si vous êtes habitué à un mauvais rapport de contraste. L’accessibilité a ses contraintes, mais finalement […]

Le: 01 06 2020 à 14:37 Alsacreations.com - Actualités Auteur: iamvdo

Avant de rentrer dans le vif du sujet, un peu de contexte.

En 2013, un collectif crée l’extensible web manifesto, en faveur d’un web extensible. L’objectif affiché est clair : réfléchir à une nouvelle forme de standards, qui laissent la liberté aux concepteurs de définir leurs propres fonctionnalités. Le but est donc de fournir des APIs plus bas niveau, un accès au cœur du navigateur, et ainsi inclure les concepteurs dans le processus d’innovation sans les restreindre aux seuls consensus définis par les standards historiques.

Dans l’univers HTML, on peut évoquer les composants web (web components) qui résultent de cette philosophie. Plusieurs standards ont été mis au point pour nous aider à créer nos propres composants HTML, et ainsi étendre le langage HTML. Cette solution étant bien entendu basée sur HTML, CSS et JavaScript.

Coté CSS, c’est justement l’ambition d’Houdini : de nouveaux standards pour concevoir nos propres effets graphiques, nos propres modes de positionnement, et pourquoi pas nos propres extensions (de nouveaux sélecteurs, de nouvelles propriétés, de nouvelles fonctions ,etc.), et bien plus encore. En un mot, étendre CSS à notre envie.

Concrètement, c’est nous donner accès à toutes les phases qui sont effectuées par un navigateur pour passer d’un fichier texte à un rendu écran. On peut décomposer sommairement les actions réalisées par les navigateurs de la sorte :

  • la première étape est le Parsing, le navigateur lit et « déchiffre » les documents HTML et CSS
  • le navigateur crée le DOM et le CSSOM, des représentations objets de ces fichiers textes
  • en découle le Render Tree, ou Layer Tree, une sorte de liste des styles à appliquer pour dessiner chaque élément de la page
  • enfin, le navigateur dessine les éléments en passant par 3 phases :
    • Layout, le navigateur applique les règles de positionnement (display, tailles, marges, etc.) et construit donc l’architecture. On parle aussi de reflow.
    • Paint, le navigateur applique les règles de dessin (arrières-plans, bordures, images de fond). On parle aussi de repaint.
    • Composite, une phase de compositing, c’est à dire de l’empilement des différents calques créés par certaines propriétés CSS (transformations, opacité, etc.). Souvent effectuée par la carte graphique et dans un thread séparé.

Actuellement, si l’on souhaite créer un effet visuel innovant pour une interface, il nous faut alors modifier le DOM. C’est la seule porte d’entrée au mécanisme interne des navigateurs.

Pipeline de rendu des navigateurs web, avec le DOM comme porte d’entrée

L’ambition de CSS Houdini, c’est de nous permettre d’accéder à toutes les étapes internes d’un navigateur, comme le montre l’image ci-dessous.

Pipeline de rendu des navigateurs web, avec toutes les étapes comme portes d’entrées (futur)

Pour cela, c’est donc bien tout un ensemble d’API (notamment JavaScript) qui sont en cours de standardisation.

Remarquez au passage que CSSOM (plutôt complexe et mal implémenté par les navigateurs) est plus ou moins remplacé par Typed OM. Ce standard plus robuste définit un ensemble de classes d’objets permettant de manipuler CSS (les différents fichiers, les at-rules, les sélecteurs, les déclarations, les propriétés, les valeurs, etc.).

Typed OM est par conséquent utile à tous les autres standards, son principal intérêt étant la structuration du code JS qui manipule CSS, comme par exemple pour en finir avec les concaténations hasardeuses :

// CSSOM
el.style.setProperty('transform', 'translate(' + x + 'px, ' + y + 'px)')
// Typed OM
el.attributeStyleMap.set('transform', new CSSTranslate(CSS.px(x), CSS.px(y)))

Ou bien tout simplement, pour récupérer les valeurs sous forme d’objet au lieu de chaine de caractères :

// CSSOM
getComputedStyle(el).getPropertyValue('width')      // '50px'
// Typed OM
el.computedStyleMap().get('width')                  // CSSUnitValue {value: 50, unit: 'px'}

Note : vous pouvez retrouver le support de CSS Houdini sur https://ishoudinireadyyet.com. Vous remarquez que Chrome est en tête sur l’implémentation, mais c’est légèrement enjolivé (et oui, le site est maintenu par les équipes de Google). Je préciserais plus en détails dans la suite de l’article. Par exemple, pour Typed OM, le support n’est effectif que pour une partie uniquement, mais il existe une liste.

Créer ses propres propriétés

À présent, listons quelques cas d’usages d’Houdini.

Depuis quelques années, il est déjà possible de créer ses propres propriétés CSS. C’est le standard des propriétés personnalisées (custom properties), que l’on connaît également sous le nom des variables CSS.

Prenons la propriété box-shadow. Si l’on souhaite changer l’une de ses valeurs, il est nécessaire de réécrire la règle entièrement, comme dans cet exemple où l’on modifie la valeur de flou au survol

.el {
  box-shadow: 0 3px 3px black;
}
.el:hover {
  box-shadow: 0 3px 10px black;
}

Grâce aux propriétés custom de CSS, on peut définir une propriété --box-shadow-blur pour cela et seule cette propriété pourra être modifiée. Elle est appliquée depuis l’état initial à l’aide la fonction var()

.el {
  --box-shadow-blur: 3px;
  box-shadow: 0 3px var(--box-shadow-blur) black;
}
.el:hover {
  --box-shadow-blur: 10px;
}

Cela s’avère pratique, mais dans ce cas précis, il est impossible d’animer cette nouvelle propriété. En effet, le navigateur n’a aucune connaissance du type de valeur attendue et ne sait donc pas comment faire.

C’est là où l’API Properties & Values de Houdini entre en jeu. Cette spécification définit la nouvelle at-rule @property (en CSS) ainsi que la méthode CSS.registerProperty() (en JS) qui permettent d’enregistrer une propriété personnalisée, et notamment en précisant le type CSS attendu. L’un des avantages est que le navigateur saura maintenant comment l’animer (si c’est possible). Reprenons le cas précédent, en ajoutant l’animation, et en déclarant notre nouvelle propriété

.el {
  --box-shadow-blur: 3px;
  box-shadow: 0 3px var(--box-shadow-blur) black;
  transition: --box-shadow-blur .45s;
}
.el:hover {
  --box-shadow-blur: 10px;
}

@property --box-shadow-blur {
  syntax: "<length>";
  inherits: false;
  initial-value: 0;
}

Et voilà, une belle animation au survol, qui ne modifie que la propriété souhaitée.

See the Pen CSS Houdini: Register a new property by Vincent De Oliveira (@iamvdo) on CodePen.

C’est une première étape pour étendre CSS: on demande au navigateur d’apprendre une nouvelle propriété, inconnue auparavant. Et les animations ne sont pas le seul intérêt à l’utilisation des propriétés customs. Cela peut également apporter un gain de performance, en précisant par exemple qu’une propriété custom ne s’hérite pas (ce qui évite notamment au navigateur d’appliquer des changements aux éléments enfants).

En passant, évitez d’appliquer trop de propriétés custom via le sélecteur :root, comme vous forcent certains plugins de l’univers de PostCSS par exemple. Des problèmes de performance sont à noter.

Le support est actuellement uniquement dans les navigateurs basés sur le moteur Blink (Chrome, Opera, Edge), et seulement la méthode JS. La nouvelle at-rule @property sera supportée très bientôt. Cependant, dans les 2 cas, tous les types ne sont pas encore implémentés (lié aussi à Typed OM), sans avoir de liste exhaustive.

Créer ses propres effets graphiques

Actuellement, les seuls effets graphiques réalisables sont ceux définis par le langage CSS. Des couleurs de fond, des bordures, des dégradés, des coins arrondis, des ombres, bref, vous connaissez tout ça.

Le futur standard CSS Paint API, comme son nom l’indique, nous donne accès à l’étape Paint des navigateurs. Ce standard définit un environnement d’exécution isolé (un worklet), dans lequel on peut dessiner programmatiquement une image, à l’instar de la balise <canvas> de HTML. Cette image peut ensuite être appliquée depuis les propriétés CSS qui les acceptent, principalement background-image, border-image et mask-image.

Ce nouveau standard définit donc :

  • CSS.paintWorklet.addModule('paint.js') pour charger un worklet
  • registerPaint() pour réaliser le dessin au sein du worklet (dans un fichier séparé)
  • la fonction CSS paint() pour utiliser le worklet

Le code d’un worklet est donc isolé du reste de la page, et n’est appelé que lors de la phase de Paint, ce qui rends le dessin plus performant, car le navigateur n’effectue plus toutes les étapes habituelles de mise à jour. De plus, les navigateurs peuvent facilement améliorer la performance de ce code spécifique (exécution dans un thread séparé notamment).

Prenons un effet graphique basique, mais pourtant pas si simple à réaliser en CSS : un élément dont le bord droit est incliné, comme sur cette image :

Effet de bord incliné que l’on souhaite réaliser

On devrait pouvoir s’en sortir avec un dégradé linéaire, ou encore des transformations CSS, mais difficile de gérer correctement le responsive (avec des tailles de polices différentes). Des éléments supplémentaires seront surement nécessaires.

Avec Houdini, cela devient un jeu d’enfant. Première étape, enregistrer le worklet, avec nos instructions de dessins, nommé slanted :

registerPaint('slanted', class {
  paint (ctx, geom) {
    ctx.fillStyle = 'hsl(296, 100%, 50%)';
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(geom.width, 0);
    ctx.lineTo(geom.width - 20, geom.height);
    ctx.lineTo(0, geom.height);
    ctx.fill();
  }
})

Sa méthode paint() est composée d’instructions de dessin qui crée la forme inclinée, et a accès à 2 variables :

  • ctx est le contexte de dessin
  • geom est un objet contenant la taille de l’élément où le dessin sera appliqué

Le dessin s’effectue donc à l’aide des instructions classiques du contexte de dessin lié à la balise <canvas> HTML : moveTo() pour se déplacer, lineTo() pour créer ligne droite, etc.

Ensuite, il nous faut charger ce worklet puis l’utiliser depuis notre CSS :

.el {
  background-image: paint(slanted);
}

Et voilà ! Le rendu est responsive par défaut, et redessiné automatiquement à chaque changement de taille de l’élément (essayez d’éditer le texte).

See the Pen CSS Paint API by Vincent De Oliveira (@iamvdo) on CodePen.

Là où ça devient vraiment intéressant, c’est lorsque l’on va récupérer les valeurs de propriétés custom dans le worklet, et que l’on utilise le tout avec des animations. Pour commencer, créeons un nouveau worklet, et dessinons un cercle qui s’adapte automatiquement à la plus petite largeur de notre élément :

// New worklet
registerPaint('circle', class {
  paint(ctx, geom, props) {
    // Get the center point and radius
    const x = geom.width / 2;
    const y = geom.height / 2;
    const radius = Math.min(x, y);

    // Draw the circle
    ctx.fillStyle = 'deeppink';
    ctx.beginPath();
    ctx.arc(x, y, radius, 0, 2 * Math.PI);
    ctx.fill();
  }
}

See the Pen CSS Paint API: Draw circle by Vincent De Oliveira (@iamvdo) on CodePen.

Continuons avec l’utilisation d’une propriété custom --circle-color définie en CSS et utilisée depuis le worklet, à l’aide du troisième argument de la méthode paint(), nommé props :

.el {
  --circle-color: deepskyblue;
  background-image: paint(circle);
}

@property --circle-color {
  syntax: "<color>";
  inherits: false;
  initial-value: currentcolor;
}
registerPaint('circle', class {
  static get inputProperties() { return ['--circle-color'] }
  paint(ctx, geom, props) {
    ...
    ctx.fillStyle = props.get('--circle-color').value;
    ...
  }
}

See the Pen CSS Paint API: Draw circle with custom props by Vincent De Oliveira (@iamvdo) on CodePen.

Dernière étape, créons trois nouvelles propriétés custom, --circle-x et --circle-y pour préciser le centre de notre cercle et --circle-radius pour sa taille. Ces trois propriétés sont utilisées dans le worklet

registerPaint('circle', class {
  static get inputProperties() { 
    return [ 
      '--circle-color', '--circle-radius', '--circle-x', '--circle-y'
    ]
  }
  paint(ctx, geom, props) {
    const x = props.get('--circle-x').value;
    const y = props.get('--circle-y').value;
    const radius = props.get('--circle-radius').value;
  }
}

À l’état initial, le cercle a une taille à 0, et cette propriété sera animable en CSS.

.el {
  --circle-radius: 0;
  --circle-color: deepskyblue;
  background-image: paint(circle-ripple);
}
.el.animating {
  transition: --circle-radius 1s,
              --circle-color 1s;
  --circle-radius: 300;
  --circle-color: transparent;
}

Et enfin, le centre est défini en JS à l’endroit où l’utilisateur clique sur l’élément. L’ajout de classe permet d’animer la taille du cercle.

el.addEventListener('click', e => {
  el.classList.add('animating');
  el.attributeStyleMap.set('--circle-x', e.offsetX);
  el.attributeStyleMap.set('--circle-y', e.offsetY);
});

See the Pen CSS Paint API: Animations by Vincent De Oliveira (@iamvdo) on CodePen.

Boom ! Le fameux effet ripple de Google Material en quelques lignes de code. Et le tout, de manière performante.

Grâce à ce type de worklet, on peut envisager pas mal d’effets nouveaux, ou tout du moins se simplifier la création de certains effets courants. Parmi mes expérimentations, vous pourrez notamment retrouver la création de flèche d’infobulles, d’une superellipse (des coins arrondis à la mode iOS), des bordures qui simulent un trait de crayon ou des surlignages type Stabilo, des dégradés des coins, ou pourquoi pas une grille irrégulière aléatoire si l’on mixe cette technique avec les masques CSS.

Mosaique des effets disponibles sur css-houdini.rocks

Le support de CSS Paint API est uniquement dans les navigateurs basés sur le moteur Blink. Et pas à 100% : les attributs de la fonction CSS paint() ne sont pas pris en charge notamment. Le fait de passer des attributs permet par exemple d'appeler le même worklet plusieurs fois sur le même élément, et ainsi obtenir des résultats différents, comme c’est le cas dans cet exemple de bordures « internes ».

De plus, les APIs de Houdini sont étroitement liées les unes aux autres. Par exemple, pour récupérer une propriété custom dans un worklet et l’utiliser sour forme d’objet, il faut que les navigateurs implémentent l’API Properties & Values (pour enregistrer le type de la propriété), mais également Typed OM. Même Chrome a une implémentation imprévisible. Beaucoup de tests sont nécessaires pour savoir ce qui est supporté ou non.

Créer ses propres modes de positionnement

Dans la même veine, il existe un worklet spécifique à la création de son propre mode de positionnement. C’est ce que définit le standard CSS Layout API.

À la manière de Flexbox et Grid, vous pouvez donc écrire votre propre moteur de placement d’éléments au sein d’un élément parent. Comment ? Et bien, comme pour CSS Paint API :

  • CSS.layoutWorklet.addModule('layout.js') pour charger un worklet
  • registerLayout() pour construire les règles du positionnement dans le worklet
  • la fonction CSS layout() pour utiliser le worklet avec la propriété display

Bien que Flexbox et Grid ouvrent beaucoup de possibilités, il y a encore certains layout non réalisable en CSS. L’un des plus populaires est le layout Masonry. Avec cette nouvelle API, cela devient possible, avec environ 40 lignes de JS :

// Code from https://github.com/GoogleChromeLabs/houdini-samples/blob/master/layout-worklet/masonry/masonry.js 
registerLayout('masonry', class {
  async layout(children, edges, constraints, styleMap) {
    const inlineSize = constraints.fixedInlineSize;

    let columns = Math.ceil(inlineSize / 350);
    let padding = 10;

    // Layout all children with simply their column size.
    const childInlineSize = (inlineSize - ((columns + 1) * padding)) / columns;
    const childFragments = await Promise.all(children.map((child) => {
      return child.layoutNextFragment({fixedInlineSize: childInlineSize});
    }));

    let autoBlockSize = 0;
    const columnOffsets = Array(columns).fill(0);
    for (let childFragment of childFragments) {
      // Select the column with the least amount of stuff in it.
      const min = columnOffsets.reduce((acc, val, idx) => {
        if (!acc || val < acc.val) {
          return {idx, val};
        }

        return acc;
      }, {val: +Infinity, idx: -1});

      childFragment.inlineOffset = padding + (childInlineSize + padding) * min.idx;
      childFragment.blockOffset = padding + min.val;

      columnOffsets[min.idx] = childFragment.blockOffset + childFragment.blockSize;
      autoBlockSize = Math.max(autoBlockSize, columnOffsets[min.idx] + padding);
    }

    return {autoBlockSize, childFragments};
  }
});

Puis, coté CSS

.el {
  display: layout(masonry);
}

Pour voir le résultat, chargez le CodePen suivant, dans un navigateur basé sur Blink, avec le flag Web Platform actif

See the Pen pojPXKx by Vincent De Oliveira (@iamvdo) on CodePen.

Certes, le code JS parait complexe, mais pas tant que ça au final. Et surtout, ce code est isolé du reste de la page, et n’est appelé que lors de la phase de Layout, ce qui le rends plus performant, comme expliqué précédemment.

Bien entendu, on peut donc envisager d’autres modes de positionnement, comme ceux utilisés pour le développement d’applications natives (iOS, Android). Les développeurs de Google ont par exemple écrit un worklet pour porter le RelativeLayout d’Android. On peut également être plus créatifs, et créer un mode où les éléments sont positionnés le long d’un chemin SVG, défini par une propriété custom :

.el {
  display: layout(svg-path);
  --path: path("M100,300c100,-100,150,-120,300,0c150,50,300,0,400,-200");
}
Les éléments HTML sont positionnés le long d’un chemin SVG (une vague)

Dans ce cas précis, cela nous évite des positionnements absolus à la louche et difficilement responsive. Certes, il est possible d’obtenir un résultat équivalent avec le module CSS Motion (pas Houdini) et la propriété offset, mais le tracé SVG n’est pas adaptatif par défaut (donc du JS est nécessaire) et le CSS doit prévoir à l’avance le nombre d’éléments à positionner.

Le support actuel de CSS Layout API est assez limité, car uniquement dans les navigateurs basés sur le moteur Blink avec le flag Web Platform. Ce ne sont que les premières implémentations.

Encore plus ?

Il existe un dernier type de worklet au sein d’Houdini, dédié à la performance des animations, c’est l’Animation Worklet API, basée sur WAAPI (Web Animations API). Comme pour les autres worklets, le code de l’animation est donc isolé, mais surtout, il autorise une baseline basée sur d’autres paramètres que le temps. C’est notamment utile pour obtenir des animations performantes basées sur les interactions utilisateurs, comme le scroll (manuel, mais aussi animé) :

Prenons un exemple, un worklet qui enregistre une simple animation linéaire 1 pour 1

registerAnimator('simple', class {
  animate(currentTime, effect) {
    effect.localTime = currentTime;
  }
});

Ce worklet est chargé, puis une animation est créée en JS :

  • elle met à jour une propriété custom CSS --angle pour une durée de 1 (avec une valeur de 0 à 1 tour complet)
  • elle est basée sur le scroll (new ScrollTimeline avec scrollSource: scrollElement) et le « temps » équivalent est défini à 1
CSS.animationWorklet.addModule('...').then(r => {
  new WorkletAnimation('simple',
    new KeyframeEffect(el, [
        { '--angle': 0 },
        { '--angle': '1turn' }
      ],
      { duration: 1 }
    ),
    new ScrollTimeline({
      scrollSource: scrollElement,
      timeRange: 1
    }),
  ).play();
});

Finalement, la propriété --angle est utilisée en CSS pour pivoter l’intégralité d’un cube en 3D

.cube {
  --angle: 0;
  transform: rotateX(var(--angle)) rotateZ(45deg) rotateY(-45deg);
}

Pour voir le résultat, chargez le CodePen suivant, dans un navigateur basé sur Blink, avec le flag Web Platform actif

See the Pen CSS Houdini Animation API: Scroll by Vincent De Oliveira (@iamvdo) on CodePen.

Le support est actuellement limité aux navigateurs basés sur le moteur Blink avec le flag Web Platform.

L’ambition de CSS Houdini, c’est d’aller encore plus loin. Rien n’existe encore vraiment à ce stade, mais on peut citer :

  • l’API CSS Parser pour avoir accès à la première étape des navigateurs : la lecture du fichier. J’imagine donc qu’il serait possible de créer ses propres fonctions, ses propres sélecteurs, etc. puisque l’on pourrait les parser nous-mêmes. Reste à savoir ce que l’on pourrait en faire.
  • l’API Font Metrics pour accéder aux métriques des fontes en CSS. Et ça serait super pour éviter les petits désagréments actuels.

Mais alors, véritable magie ou simple poudre aux yeux ?

On peut être enthousiaste à l’idée de toutes ces nouveautés offertes par Houdini. Mais il faut quand même prendre en considérations quelques points.

Nouvelles possibilités offertes

Toutes ces nouvelles API augmentent la créativité et aide à mettre en place des effets qui étaient jusque là impossibles ou alors très compliqués à réaliser.

Comme vu plus haut, on peut spécifier ses propres propriétés, mais malheureusement on ne peut pas vraiment étendre des fonctionnalités existantes. Dans le cas de création d’une propriété pour le flou d’une ombre, il est par exemple impossible de créer un flou directionnel en divisant --box-shadow-blur en deux sous-propriétés, --box-shadow-blur-x et --box-shadow-blur-y. Il n’existe pas de solution pour «hacker» le dessin des ombres du navigateur.

Même si l’API Paint paraît révolutionnaire en soit, ce n’est finalement qu’une version performante de -webkit-canvas() qui existe depuis 2008, mais qui est maintenant retirée de Chrome.

Le dessin est effectué dans un canvas, via son contexte de type CanvasRendering2D (et encore, une version plus limitée). Il existe des centaines d’effets impossibles aujourd’hui, qui ne pourront pas être réalisés avec CSS Houdini. Ce contexte de dessin n’est pas initialement prévu pour CSS et il a donc de nombreuses contraintes :

  • pas de gestion simple des bordures (border-clip, bordures multiples, etc.), ni des ombres, ni des images d’arrière-plan (répétition, position, taille, etc.)
  • pas pratique de dessiner en dehors d’un élément (mais possible en combinant border-image + border-outset), comme pour les ombres
  • pas de gestion des textes
  • rien de nouveau pour styler les formulaires
  • etc.

Dans beaucoup de cas, SVG est un choix bien plus simple et pratique.

Concernant l’API Layout, ce sont uniquement des modes de positionnement complets qui sont réalisables (comme Flexbox ou Grid). C’est déjà très bien me direz-vous, mais cela ne permet pas de modifier la façon dont CSS fonctionne.

Impossible donc d’agir sur la taille, ou les marges, d’un seul élément, de changer son containing block (dans le cas d’un élément en position absolue) ou son contexte d’empilement (notamment en cas de conflit avec certaines propriétés), ni même d’ajouter de nouveaux pseudo-éléments ou d’autres entités (mais c’est peut être du ressort des web components ?).

Polyfill

Un des critères avancé est la possibilité de créer ses propres polyfills (combler le manque de support d’un navigateur par son propre code). C’est vrai, Houdini peut aider, mais il ne faut pas oublier que les navigateurs supportant Houdini mais ne supportant pas telle ou telle fonctionnalité, sont plutôt rares. Il existe pourtant quelques contre-exemples :

Cependant, pas de miracle, la grande majorité de CSS est non polyfillable1.

Performance

C’est le cheval de bataille de CSS Houdini : la performance de rendu. Et c’est tout à fait légitime. Aujourd’hui, en 2020, on est encore restreints dans la création d’effets visuels, et surtout lorsqu’ils sont animés. Les propriétés CSS de layout (width, height, margin, left etc.) ou mêmes des propriétés de dessin (background-color, background-size, etc.) sont très coûteuses en temps de rendu. C’est pour cela que les propriétés transform et opacity sont préférées, car sont traitées pendant la phase de compositing des navigateurs, et souvent effectuées par un thread séparé.

Regardez par exemple comment on peut animer une ombre portée (box-shadow) sans réellement animer l’ombre portée (spoiler: on anime l’opacité d’un pseudo-élément qui a l’ombre portée).

L’utilisation des worklets, isolés du reste de la page et du fameux thread principal2, permet donc d’obtenir des résultats performants, sans recourir exclusivement aux propriétés transform/opacity.

Concernant le worklet Animation API, je ne suis personnellement pas un grand fan de cette solution. Le standard WAAPI est à mon sens bien suffisant pour réaliser des animations performantes, et pour gérer facilement les transitions/animations CSS. Pour la partie animation au scroll, je préfère nettement la spécification Scroll-linked Animations et notamment la propriété animation-timeline et l’at-rule @scroll-timeline, mais qui ne font pas partie de Houdini.

Innovation des moteurs de rendu

On ne peut pas parler de performance de rendu, sans évoquer les moteurs de rendu. Actuellement il existe 3 moteurs principaux de navigateur : Blink qui alimente Chrome, Opera, Edge, etc., WebKit pour Safari, et Gecko pour Firefox.

Les APIs de CSS Houdini sont basées sur un consensus de rendu, qui est plus ou moins celui de chaque navigateur, mais on se doit d’évoquer le nouveau moteur de rendu de Firefox : WebRender. Ce nouveau composant a l’ambition de modifier fondamentalement les techniques de rendu : dorénavant les phases Paint et Compositing sont fusionnées et c’est le GPU qui se charge de l’intégralité du rendu, à la manière des jeux vidéos. C’est encore récent, mais quand ce sera en place, les techniques à base de transform/opacity seront obsolètes pour ce navigateur. Selon @gsnedders, c’est même pire, car les APIs Houdini qui sont une réponse aux problèmes de performance de rendu dans le contexte actuel, seraient complexes à exécuter dans un contexte différent.

Et ça, c’est problématique, soit pour l’innovation, soit pour Houdini.

Tout en JavaScript

On peut également regretter que seules des APIs JavaScript soient en cours de standardisation. CSS Houdini, ce n’est finalement que du JS-in-CSS. Pas de JS, pas de styles.

Personnellement, j’aurais bien aimé pouvoir utiliser SVG dans un worklet. Le déclaratif, ça a du bon quelque fois. Mais pour être performant, il faudrait déjà que Blink/WebKit l’accélèrent matériellement. C’est pour bientôt dans WebKit.

Quoi qu’il en soit, ce qu’il en ressort est un code assez complexe à écrire et à mettre en oeuvre. Mais surtout, c’est souvent bien plus difficile que du JS « classique », via le DOM.

Sans rentrer dans des détails trop techniques, les worklets sont des environnements autonomes, qui ne doivent pas gérer d’état. Pour être sûr de cela, le navigateur doit créer deux instances pour chaque worklets, et utiliser indifféremment l’un ou l’autre pour le rendu. Cela complique énormément des effets qui semblent pourtant simple, comme dans cet exemple de bordures où chaque repaint crée des bordures différentes. Je me suis déjà cassé les dents plusieurs fois sur des effets à cause de cela. Il existe des solutions pour contourner ce problème, mais encore une fois, ça complexifie le code et crée souvent des effets de bords.

Plus basiquement, il ne faut pas sous-estimer le temps de chargement des scripts JS, voire tout simplement de leur non présence. Mais également du support de Houdini. Actuellement, les styles appliqués via paint() et layout() provoquent des FOUC (Flash of Unstyled Content).

La notion d’enrichissement progressif est plus que jamais d’actualité. Mais sera plus complexe à mettre en œuvre.

Sécurité

Enfin, dès que l’on ouvre un peu plus le coeur des navigateurs, s’en suivent des considérations de sécurité. Le principal frein est que l’utilisation des worklets ne peut se faire que sur un site en HTTPS. Pas de site sécurisé, pas de CSS. Et c’est un peu regrettable3.

Malgré cela, des chercheurs sont tout de même parvenus à exploiter une faille, qui permet de récupérer assez facilement un historique de navigation. La solution de contournement prise par les équipes de Chrome a été d’interdire l’utilisation de la fonction paint() sur les liens HTML. Là encore, c’est à mon avis une très grosse contrainte qui va en limiter l’adoption si cela en reste là.

Et surtout, combien de temps encore pour que d’autres failles soient découvertes ? Est-ce que l’avenir de CSS Houdini est lié à celui des CSS Shaders (des filtres CSS customs qui permettaient d’appliquer des shaders WebGL à la volée) qui ont disparus du jour au lendemain des navigateurs qui les avaient implémentés ?

Conclusion

Cette nouvelle façon de concevoir des standards est intéressante. Elle ouvre la porte aux concepteurs, et permet de les inclure dans le processus d’innovation. Avec CSS Houdini, de nouveaux effets sont possibles, et ces effets sont rendus de manière plus performante dans les navigateurs actuels. Mais cela implique quand même quelques contraintes : du JavaScript supplémentaire, plus complexe à mettre en oeuvre, etc.

Dans tous les cas, CSS Houdini est surtout pensé pour la performance, pas vraiment pour la créativité.

On peut aussi voir ces APIs comme une opportunité pour l’évolution des standards classiques. Si un effet visuel, ou un mode de positionnement, devient populaire, il pourrait alors être standardisé, pour être inclus directement en CSS. Mais qu’en sera t’il de la gestion des performances si l’on conserve les méthodes de rendus actuelles ?

Alors, vous, que pensez-vous de tout ça ?

Publié par Alsacreations.com

Le: 01 06 2020 à 14:37 Alsacreations.com - Apprendre Auteur: iamvdo

Avant de rentrer dans le vif du sujet, un peu de contexte.

En 2013, un collectif crée l’extensible web manifesto, en faveur d’un web extensible. L’objectif affiché est clair : réfléchir à une nouvelle forme de standards, qui laissent la liberté aux concepteurs de définir leurs propres fonctionnalités. Le but est donc de fournir des APIs plus bas niveau, un accès au cœur du navigateur, et ainsi inclure les concepteurs dans le processus d’innovation sans les restreindre aux seuls consensus définis par les standards historiques.

Dans l’univers HTML, on peut évoquer les composants web (web components) qui résultent de cette philosophie. Plusieurs standards ont été mis au point pour nous aider à créer nos propres composants HTML, et ainsi étendre le langage HTML. Cette solution étant bien entendu basée sur HTML, CSS et JavaScript.

Coté CSS, c’est justement l’ambition d’Houdini : de nouveaux standards pour concevoir nos propres effets graphiques, nos propres modes de positionnement, et pourquoi pas nos propres extensions (de nouveaux sélecteurs, de nouvelles propriétés, de nouvelles fonctions ,etc.), et bien plus encore. En un mot, étendre CSS à notre envie.

Concrètement, c’est nous donner accès à toutes les phases qui sont effectuées par un navigateur pour passer d’un fichier texte à un rendu écran. On peut décomposer sommairement les actions réalisées par les navigateurs de la sorte :

  • la première étape est le Parsing, le navigateur lit et « déchiffre » les documents HTML et CSS
  • le navigateur crée le DOM et le CSSOM, des représentations objets de ces fichiers textes
  • en découle le Render Tree, ou Layer Tree, une sorte de liste des styles à appliquer pour dessiner chaque élément de la page
  • enfin, le navigateur dessine les éléments en passant par 3 phases :
    • Layout, le navigateur applique les règles de positionnement (display, tailles, marges, etc.) et construit donc l’architecture. On parle aussi de reflow.
    • Paint, le navigateur applique les règles de dessin (arrières-plans, bordures, images de fond). On parle aussi de repaint.
    • Composite, une phase de compositing, c’est à dire de l’empilement des différents calques créés par certaines propriétés CSS (transformations, opacité, etc.). Souvent effectuée par la carte graphique et dans un thread séparé.

Actuellement, si l’on souhaite créer un effet visuel innovant pour une interface, il nous faut alors modifier le DOM. C’est la seule porte d’entrée au mécanisme interne des navigateurs.

Pipeline de rendu des navigateurs web, avec le DOM comme porte d’entrée

L’ambition de CSS Houdini, c’est de nous permettre d’accéder à toutes les étapes internes d’un navigateur, comme le montre l’image ci-dessous.

Pipeline de rendu des navigateurs web, avec toutes les étapes comme portes d’entrées (futur)

Pour cela, c’est donc bien tout un ensemble d’API (notamment JavaScript) qui sont en cours de standardisation.

Remarquez au passage que CSSOM (plutôt complexe et mal implémenté par les navigateurs) est plus ou moins remplacé par Typed OM. Ce standard plus robuste définit un ensemble de classes d’objets permettant de manipuler CSS (les différents fichiers, les at-rules, les sélecteurs, les déclarations, les propriétés, les valeurs, etc.).

Typed OM est par conséquent utile à tous les autres standards, son principal intérêt étant la structuration du code JS qui manipule CSS, comme par exemple pour en finir avec les concaténations hasardeuses :

// CSSOM
el.style.setProperty('transform', 'translate(' + x + 'px, ' + y + 'px)')
// Typed OM
el.attributeStyleMap.set('transform', new CSSTranslate(CSS.px(x), CSS.px(y)))

Ou bien tout simplement, pour récupérer les valeurs sous forme d’objet au lieu de chaine de caractères :

// CSSOM
getComputedStyle(el).getPropertyValue('width')      // '50px'
// Typed OM
el.computedStyleMap().get('width')                  // CSSUnitValue {value: 50, unit: 'px'}

Note : vous pouvez retrouver le support de CSS Houdini sur https://ishoudinireadyyet.com. Vous remarquez que Chrome est en tête sur l’implémentation, mais c’est légèrement enjolivé (et oui, le site est maintenu par les équipes de Google). Je préciserais plus en détails dans la suite de l’article. Par exemple, pour Typed OM, le support n’est effectif que pour une partie uniquement, mais il existe une liste.

Créer ses propres propriétés

À présent, listons quelques cas d’usages d’Houdini.

Depuis quelques années, il est déjà possible de créer ses propres propriétés CSS. C’est le standard des propriétés personnalisées (custom properties), que l’on connaît également sous le nom des variables CSS.

Prenons la propriété box-shadow. Si l’on souhaite changer l’une de ses valeurs, il est nécessaire de réécrire la règle entièrement, comme dans cet exemple où l’on modifie la valeur de flou au survol

.el {
  box-shadow: 0 3px 3px black;
}
.el:hover {
  box-shadow: 0 3px 10px black;
}

Grâce aux propriétés custom de CSS, on peut définir une propriété --box-shadow-blur pour cela et seule cette propriété pourra être modifiée. Elle est appliquée depuis l’état initial à l’aide la fonction var()

.el {
  --box-shadow-blur: 3px;
  box-shadow: 0 3px var(--box-shadow-blur) black;
}
.el:hover {
  --box-shadow-blur: 10px;
}

Cela s’avère pratique, mais dans ce cas précis, il est impossible d’animer cette nouvelle propriété. En effet, le navigateur n’a aucune connaissance du type de valeur attendue et ne sait donc pas comment faire.

C’est là où l’API Properties & Values de Houdini entre en jeu. Cette spécification définit la nouvelle at-rule @property (en CSS) ainsi que la méthode CSS.registerProperty() (en JS) qui permettent d’enregistrer une propriété personnalisée, et notamment en précisant le type CSS attendu. L’un des avantages est que le navigateur saura maintenant comment l’animer (si c’est possible). Reprenons le cas précédent, en ajoutant l’animation, et en déclarant notre nouvelle propriété

.el {
  --box-shadow-blur: 3px;
  box-shadow: 0 3px var(--box-shadow-blur) black;
  transition: --box-shadow-blur .45s;
}
.el:hover {
  --box-shadow-blur: 10px;
}

@property --box-shadow-blur {
  syntax: "<length>";
  inherits: false;
  initial-value: 0;
}

Et voilà, une belle animation au survol, qui ne modifie que la propriété souhaitée.

See the Pen CSS Houdini: Register a new property by Vincent De Oliveira (@iamvdo) on CodePen.

C’est une première étape pour étendre CSS: on demande au navigateur d’apprendre une nouvelle propriété, inconnue auparavant. Et les animations ne sont pas le seul intérêt à l’utilisation des propriétés customs. Cela peut également apporter un gain de performance, en précisant par exemple qu’une propriété custom ne s’hérite pas (ce qui évite notamment au navigateur d’appliquer des changements aux éléments enfants).

En passant, évitez d’appliquer trop de propriétés custom via le sélecteur :root, comme vous forcent certains plugins de l’univers de PostCSS par exemple. Des problèmes de performance sont à noter.

Le support est actuellement uniquement dans les navigateurs basés sur le moteur Blink (Chrome, Opera, Edge), et seulement la méthode JS. La nouvelle at-rule @property sera supportée très bientôt. Cependant, dans les 2 cas, tous les types ne sont pas encore implémentés (lié aussi à Typed OM), sans avoir de liste exhaustive.

Créer ses propres effets graphiques

Actuellement, les seuls effets graphiques réalisables sont ceux définis par le langage CSS. Des couleurs de fond, des bordures, des dégradés, des coins arrondis, des ombres, bref, vous connaissez tout ça.

Le futur standard CSS Paint API, comme son nom l’indique, nous donne accès à l’étape Paint des navigateurs. Ce standard définit un environnement d’exécution isolé (un worklet), dans lequel on peut dessiner programmatiquement une image, à l’instar de la balise <canvas> de HTML. Cette image peut ensuite être appliquée depuis les propriétés CSS qui les acceptent, principalement background-image, border-image et mask-image.

Ce nouveau standard définit donc :

  • CSS.paintWorklet.addModule('paint.js') pour charger un worklet
  • registerPaint() pour réaliser le dessin au sein du worklet (dans un fichier séparé)
  • la fonction CSS paint() pour utiliser le worklet

Le code d’un worklet est donc isolé du reste de la page, et n’est appelé que lors de la phase de Paint, ce qui rends le dessin plus performant, car le navigateur n’effectue plus toutes les étapes habituelles de mise à jour. De plus, les navigateurs peuvent facilement améliorer la performance de ce code spécifique (exécution dans un thread séparé notamment).

Prenons un effet graphique basique, mais pourtant pas si simple à réaliser en CSS : un élément dont le bord droit est incliné, comme sur cette image :

Effet de bord incliné que l’on souhaite réaliser

On devrait pouvoir s’en sortir avec un dégradé linéaire, ou encore des transformations CSS, mais difficile de gérer correctement le responsive (avec des tailles de polices différentes). Des éléments supplémentaires seront surement nécessaires.

Avec Houdini, cela devient un jeu d’enfant. Première étape, enregistrer le worklet, avec nos instructions de dessins, nommé slanted :

registerPaint('slanted', class {
  paint (ctx, geom) {
    ctx.fillStyle = 'hsl(296, 100%, 50%)';
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(geom.width, 0);
    ctx.lineTo(geom.width - 20, geom.height);
    ctx.lineTo(0, geom.height);
    ctx.fill();
  }
})

Sa méthode paint() est composée d’instructions de dessin qui crée la forme inclinée, et a accès à 2 variables :

  • ctx est le contexte de dessin
  • geom est un objet contenant la taille de l’élément où le dessin sera appliqué

Le dessin s’effectue donc à l’aide des instructions classiques du contexte de dessin lié à la balise <canvas> HTML : moveTo() pour se déplacer, lineTo() pour créer ligne droite, etc.

Ensuite, il nous faut charger ce worklet puis l’utiliser depuis notre CSS :

.el {
  background-image: paint(slanted);
}

Et voilà ! Le rendu est responsive par défaut, et redessiné automatiquement à chaque changement de taille de l’élément (essayez d’éditer le texte).

See the Pen CSS Paint API by Vincent De Oliveira (@iamvdo) on CodePen.

Là où ça devient vraiment intéressant, c’est lorsque l’on va récupérer les valeurs de propriétés custom dans le worklet, et que l’on utilise le tout avec des animations. Pour commencer, créeons un nouveau worklet, et dessinons un cercle qui s’adapte automatiquement à la plus petite largeur de notre élément :

// New worklet
registerPaint('circle', class {
  paint(ctx, geom, props) {
    // Get the center point and radius
    const x = geom.width / 2;
    const y = geom.height / 2;
    const radius = Math.min(x, y);

    // Draw the circle
    ctx.fillStyle = 'deeppink';
    ctx.beginPath();
    ctx.arc(x, y, radius, 0, 2 * Math.PI);
    ctx.fill();
  }
}

See the Pen CSS Paint API: Draw circle by Vincent De Oliveira (@iamvdo) on CodePen.

Continuons avec l’utilisation d’une propriété custom --circle-color définie en CSS et utilisée depuis le worklet, à l’aide du troisième argument de la méthode paint(), nommé props :

.el {
  --circle-color: deepskyblue;
  background-image: paint(circle);
}

@property --circle-color {
  syntax: "<color>";
  inherits: false;
  initial-value: currentcolor;
}
registerPaint('circle', class {
  static get inputProperties() { return ['--circle-color'] }
  paint(ctx, geom, props) {
    ...
    ctx.fillStyle = props.get('--circle-color').value;
    ...
  }
}

See the Pen CSS Paint API: Draw circle with custom props by Vincent De Oliveira (@iamvdo) on CodePen.

Dernière étape, créons trois nouvelles propriétés custom, --circle-x et --circle-y pour préciser le centre de notre cercle et --circle-radius pour sa taille. Ces trois propriétés sont utilisées dans le worklet

registerPaint('circle', class {
  static get inputProperties() { 
    return [ 
      '--circle-color', '--circle-radius', '--circle-x', '--circle-y'
    ]
  }
  paint(ctx, geom, props) {
    const x = props.get('--circle-x').value;
    const y = props.get('--circle-y').value;
    const radius = props.get('--circle-radius').value;
  }
}

À l’état initial, le cercle a une taille à 0, et cette propriété sera animable en CSS.

.el {
  --circle-radius: 0;
  --circle-color: deepskyblue;
  background-image: paint(circle-ripple);
}
.el.animating {
  transition: --circle-radius 1s,
              --circle-color 1s;
  --circle-radius: 300;
  --circle-color: transparent;
}

Et enfin, le centre est défini en JS à l’endroit où l’utilisateur clique sur l’élément. L’ajout de classe permet d’animer la taille du cercle.

el.addEventListener('click', e => {
  el.classList.add('animating');
  el.attributeStyleMap.set('--circle-x', e.offsetX);
  el.attributeStyleMap.set('--circle-y', e.offsetY);
});

See the Pen CSS Paint API: Animations by Vincent De Oliveira (@iamvdo) on CodePen.

Boom ! Le fameux effet ripple de Google Material en quelques lignes de code. Et le tout, de manière performante.

Grâce à ce type de worklet, on peut envisager pas mal d’effets nouveaux, ou tout du moins se simplifier la création de certains effets courants. Parmi mes expérimentations, vous pourrez notamment retrouver la création de flèche d’infobulles, d’une superellipse (des coins arrondis à la mode iOS), des bordures qui simulent un trait de crayon ou des surlignages type Stabilo, des dégradés des coins, ou pourquoi pas une grille irrégulière aléatoire si l’on mixe cette technique avec les masques CSS.

Mosaique des effets disponibles sur css-houdini.rocks

Le support de CSS Paint API est uniquement dans les navigateurs basés sur le moteur Blink. Et pas à 100% : les attributs de la fonction CSS paint() ne sont pas pris en charge notamment. Le fait de passer des attributs permet par exemple d'appeler le même worklet plusieurs fois sur le même élément, et ainsi obtenir des résultats différents, comme c’est le cas dans cet exemple de bordures « internes ».

De plus, les APIs de Houdini sont étroitement liées les unes aux autres. Par exemple, pour récupérer une propriété custom dans un worklet et l’utiliser sour forme d’objet, il faut que les navigateurs implémentent l’API Properties & Values (pour enregistrer le type de la propriété), mais également Typed OM. Même Chrome a une implémentation imprévisible. Beaucoup de tests sont nécessaires pour savoir ce qui est supporté ou non.

Créer ses propres modes de positionnement

Dans la même veine, il existe un worklet spécifique à la création de son propre mode de positionnement. C’est ce que définit le standard CSS Layout API.

À la manière de Flexbox et Grid, vous pouvez donc écrire votre propre moteur de placement d’éléments au sein d’un élément parent. Comment ? Et bien, comme pour CSS Paint API :

  • CSS.layoutWorklet.addModule('layout.js') pour charger un worklet
  • registerLayout() pour construire les règles du positionnement dans le worklet
  • la fonction CSS layout() pour utiliser le worklet avec la propriété display

Bien que Flexbox et Grid ouvrent beaucoup de possibilités, il y a encore certains layout non réalisable en CSS. L’un des plus populaires est le layout Masonry. Avec cette nouvelle API, cela devient possible, avec environ 40 lignes de JS :

// Code from https://github.com/GoogleChromeLabs/houdini-samples/blob/master/layout-worklet/masonry/masonry.js 
registerLayout('masonry', class {
  async layout(children, edges, constraints, styleMap) {
    const inlineSize = constraints.fixedInlineSize;

    let columns = Math.ceil(inlineSize / 350);
    let padding = 10;

    // Layout all children with simply their column size.
    const childInlineSize = (inlineSize - ((columns + 1) * padding)) / columns;
    const childFragments = await Promise.all(children.map((child) => {
      return child.layoutNextFragment({fixedInlineSize: childInlineSize});
    }));

    let autoBlockSize = 0;
    const columnOffsets = Array(columns).fill(0);
    for (let childFragment of childFragments) {
      // Select the column with the least amount of stuff in it.
      const min = columnOffsets.reduce((acc, val, idx) => {
        if (!acc || val < acc.val) {
          return {idx, val};
        }

        return acc;
      }, {val: +Infinity, idx: -1});

      childFragment.inlineOffset = padding + (childInlineSize + padding) * min.idx;
      childFragment.blockOffset = padding + min.val;

      columnOffsets[min.idx] = childFragment.blockOffset + childFragment.blockSize;
      autoBlockSize = Math.max(autoBlockSize, columnOffsets[min.idx] + padding);
    }

    return {autoBlockSize, childFragments};
  }
});

Puis, coté CSS

.el {
  display: layout(masonry);
}

Pour voir le résultat, chargez le CodePen suivant, dans un navigateur basé sur Blink, avec le flag Web Platform actif

See the Pen pojPXKx by Vincent De Oliveira (@iamvdo) on CodePen.

Certes, le code JS parait complexe, mais pas tant que ça au final. Et surtout, ce code est isolé du reste de la page, et n’est appelé que lors de la phase de Layout, ce qui le rends plus performant, comme expliqué précédemment.

Bien entendu, on peut donc envisager d’autres modes de positionnement, comme ceux utilisés pour le développement d’applications natives (iOS, Android). Les développeurs de Google ont par exemple écrit un worklet pour porter le RelativeLayout d’Android. On peut également être plus créatifs, et créer un mode où les éléments sont positionnés le long d’un chemin SVG, défini par une propriété custom :

.el {
  display: layout(svg-path);
  --path: path("M100,300c100,-100,150,-120,300,0c150,50,300,0,400,-200");
}
Les éléments HTML sont positionnés le long d’un chemin SVG (une vague)

Dans ce cas précis, cela nous évite des positionnements absolus à la louche et difficilement responsive. Certes, il est possible d’obtenir un résultat équivalent avec le module CSS Motion (pas Houdini) et la propriété offset, mais le tracé SVG n’est pas adaptatif par défaut (donc du JS est nécessaire) et le CSS doit prévoir à l’avance le nombre d’éléments à positionner.

Le support actuel de CSS Layout API est assez limité, car uniquement dans les navigateurs basés sur le moteur Blink avec le flag Web Platform. Ce ne sont que les premières implémentations.

Encore plus ?

Il existe un dernier type de worklet au sein d’Houdini, dédié à la performance des animations, c’est l’Animation Worklet API, basée sur WAAPI (Web Animations API). Comme pour les autres worklets, le code de l’animation est donc isolé, mais surtout, il autorise une baseline basée sur d’autres paramètres que le temps. C’est notamment utile pour obtenir des animations performantes basées sur les interactions utilisateurs, comme le scroll (manuel, mais aussi animé) :

Prenons un exemple, un worklet qui enregistre une simple animation linéaire 1 pour 1

registerAnimator('simple', class {
  animate(currentTime, effect) {
    effect.localTime = currentTime;
  }
});

Ce worklet est chargé, puis une animation est créée en JS :

  • elle met à jour une propriété custom CSS --angle pour une durée de 1 (avec une valeur de 0 à 1 tour complet)
  • elle est basée sur le scroll (new ScrollTimeline avec scrollSource: scrollElement) et le « temps » équivalent est défini à 1
CSS.animationWorklet.addModule('...').then(r => {
  new WorkletAnimation('simple',
    new KeyframeEffect(el, [
        { '--angle': 0 },
        { '--angle': '1turn' }
      ],
      { duration: 1 }
    ),
    new ScrollTimeline({
      scrollSource: scrollElement,
      timeRange: 1
    }),
  ).play();
});

Finalement, la propriété --angle est utilisée en CSS pour pivoter l’intégralité d’un cube en 3D

.cube {
  --angle: 0;
  transform: rotateX(var(--angle)) rotateZ(45deg) rotateY(-45deg);
}

Pour voir le résultat, chargez le CodePen suivant, dans un navigateur basé sur Blink, avec le flag Web Platform actif

See the Pen CSS Houdini Animation API: Scroll by Vincent De Oliveira (@iamvdo) on CodePen.

Le support est actuellement limité aux navigateurs basés sur le moteur Blink avec le flag Web Platform.

L’ambition de CSS Houdini, c’est d’aller encore plus loin. Rien n’existe encore vraiment à ce stade, mais on peut citer :

  • l’API CSS Parser pour avoir accès à la première étape des navigateurs : la lecture du fichier. J’imagine donc qu’il serait possible de créer ses propres fonctions, ses propres sélecteurs, etc. puisque l’on pourrait les parser nous-mêmes. Reste à savoir ce que l’on pourrait en faire.
  • l’API Font Metrics pour accéder aux métriques des fontes en CSS. Et ça serait super pour éviter les petits désagréments actuels.

Mais alors, véritable magie ou simple poudre aux yeux ?

On peut être enthousiaste à l’idée de toutes ces nouveautés offertes par Houdini. Mais il faut quand même prendre en considérations quelques points.

Nouvelles possibilités offertes

Toutes ces nouvelles API augmentent la créativité et aide à mettre en place des effets qui étaient jusque là impossibles ou alors très compliqués à réaliser.

Comme vu plus haut, on peut spécifier ses propres propriétés, mais malheureusement on ne peut pas vraiment étendre des fonctionnalités existantes. Dans le cas de création d’une propriété pour le flou d’une ombre, il est par exemple impossible de créer un flou directionnel en divisant --box-shadow-blur en deux sous-propriétés, --box-shadow-blur-x et --box-shadow-blur-y. Il n’existe pas de solution pour «hacker» le dessin des ombres du navigateur.

Même si l’API Paint paraît révolutionnaire en soit, ce n’est finalement qu’une version performante de -webkit-canvas() qui existe depuis 2008, mais qui est maintenant retirée de Chrome.

Le dessin est effectué dans un canvas, via son contexte de type CanvasRendering2D (et encore, une version plus limitée). Il existe des centaines d’effets impossibles aujourd’hui, qui ne pourront pas être réalisés avec CSS Houdini. Ce contexte de dessin n’est pas initialement prévu pour CSS et il a donc de nombreuses contraintes :

  • pas de gestion simple des bordures (border-clip, bordures multiples, etc.), ni des ombres, ni des images d’arrière-plan (répétition, position, taille, etc.)
  • pas pratique de dessiner en dehors d’un élément (mais possible en combinant border-image + border-outset), comme pour les ombres
  • pas de gestion des textes
  • rien de nouveau pour styler les formulaires
  • etc.

Dans beaucoup de cas, SVG est un choix bien plus simple et pratique.

Concernant l’API Layout, ce sont uniquement des modes de positionnement complets qui sont réalisables (comme Flexbox ou Grid). C’est déjà très bien me direz-vous, mais cela ne permet pas de modifier la façon dont CSS fonctionne.

Impossible donc d’agir sur la taille, ou les marges, d’un seul élément, de changer son containing block (dans le cas d’un élément en position absolue) ou son contexte d’empilement (notamment en cas de conflit avec certaines propriétés), ni même d’ajouter de nouveaux pseudo-éléments ou d’autres entités (mais c’est peut être du ressort des web components ?).

Polyfill

Un des critères avancé est la possibilité de créer ses propres polyfills (combler le manque de support d’un navigateur par son propre code). C’est vrai, Houdini peut aider, mais il ne faut pas oublier que les navigateurs supportant Houdini mais ne supportant pas telle ou telle fonctionnalité, sont plutôt rares. Il existe pourtant quelques contre-exemples :

Cependant, pas de miracle, la grande majorité de CSS est non polyfillable1.

Performance

C’est le cheval de bataille de CSS Houdini : la performance de rendu. Et c’est tout à fait légitime. Aujourd’hui, en 2020, on est encore restreints dans la création d’effets visuels, et surtout lorsqu’ils sont animés. Les propriétés CSS de layout (width, height, margin, left etc.) ou mêmes des propriétés de dessin (background-color, background-size, etc.) sont très coûteuses en temps de rendu. C’est pour cela que les propriétés transform et opacity sont préférées, car sont traitées pendant la phase de compositing des navigateurs, et souvent effectuées par un thread séparé.

Regardez par exemple comment on peut animer une ombre portée (box-shadow) sans réellement animer l’ombre portée (spoiler: on anime l’opacité d’un pseudo-élément qui a l’ombre portée).

L’utilisation des worklets, isolés du reste de la page et du fameux thread principal2, permet donc d’obtenir des résultats performants, sans recourir exclusivement aux propriétés transform/opacity.

Concernant le worklet Animation API, je ne suis personnellement pas un grand fan de cette solution. Le standard WAAPI est à mon sens bien suffisant pour réaliser des animations performantes, et pour gérer facilement les transitions/animations CSS. Pour la partie animation au scroll, je préfère nettement la spécification Scroll-linked Animations et notamment la propriété animation-timeline et l’at-rule @scroll-timeline, mais qui ne font pas partie de Houdini.

Innovation des moteurs de rendu

On ne peut pas parler de performance de rendu, sans évoquer les moteurs de rendu. Actuellement il existe 3 moteurs principaux de navigateur : Blink qui alimente Chrome, Opera, Edge, etc., WebKit pour Safari, et Gecko pour Firefox.

Les APIs de CSS Houdini sont basées sur un consensus de rendu, qui est plus ou moins celui de chaque navigateur, mais on se doit d’évoquer le nouveau moteur de rendu de Firefox : WebRender. Ce nouveau composant a l’ambition de modifier fondamentalement les techniques de rendu : dorénavant les phases Paint et Compositing sont fusionnées et c’est le GPU qui se charge de l’intégralité du rendu, à la manière des jeux vidéos. C’est encore récent, mais quand ce sera en place, les techniques à base de transform/opacity seront obsolètes pour ce navigateur. Selon @gsnedders, c’est même pire, car les APIs Houdini qui sont une réponse aux problèmes de performance de rendu dans le contexte actuel, seraient complexes à exécuter dans un contexte différent.

Et ça, c’est problématique, soit pour l’innovation, soit pour Houdini.

Tout en JavaScript

On peut également regretter que seules des APIs JavaScript soient en cours de standardisation. CSS Houdini, ce n’est finalement que du JS-in-CSS. Pas de JS, pas de styles.

Personnellement, j’aurais bien aimé pouvoir utiliser SVG dans un worklet. Le déclaratif, ça a du bon quelque fois. Mais pour être performant, il faudrait déjà que Blink/WebKit l’accélèrent matériellement. C’est pour bientôt dans WebKit.

Quoi qu’il en soit, ce qu’il en ressort est un code assez complexe à écrire et à mettre en oeuvre. Mais surtout, c’est souvent bien plus difficile que du JS « classique », via le DOM.

Sans rentrer dans des détails trop techniques, les worklets sont des environnements autonomes, qui ne doivent pas gérer d’état. Pour être sûr de cela, le navigateur doit créer deux instances pour chaque worklets, et utiliser indifféremment l’un ou l’autre pour le rendu. Cela complique énormément des effets qui semblent pourtant simple, comme dans cet exemple de bordures où chaque repaint crée des bordures différentes. Je me suis déjà cassé les dents plusieurs fois sur des effets à cause de cela. Il existe des solutions pour contourner ce problème, mais encore une fois, ça complexifie le code et crée souvent des effets de bords.

Plus basiquement, il ne faut pas sous-estimer le temps de chargement des scripts JS, voire tout simplement de leur non présence. Mais également du support de Houdini. Actuellement, les styles appliqués via paint() et layout() provoquent des FOUC (Flash of Unstyled Content).

La notion d’enrichissement progressif est plus que jamais d’actualité. Mais sera plus complexe à mettre en œuvre.

Sécurité

Enfin, dès que l’on ouvre un peu plus le coeur des navigateurs, s’en suivent des considérations de sécurité. Le principal frein est que l’utilisation des worklets ne peut se faire que sur un site en HTTPS. Pas de site sécurisé, pas de CSS. Et c’est un peu regrettable3.

Malgré cela, des chercheurs sont tout de même parvenus à exploiter une faille, qui permet de récupérer assez facilement un historique de navigation. La solution de contournement prise par les équipes de Chrome a été d’interdire l’utilisation de la fonction paint() sur les liens HTML. Là encore, c’est à mon avis une très grosse contrainte qui va en limiter l’adoption si cela en reste là.

Et surtout, combien de temps encore pour que d’autres failles soient découvertes ? Est-ce que l’avenir de CSS Houdini est lié à celui des CSS Shaders (des filtres CSS customs qui permettaient d’appliquer des shaders WebGL à la volée) qui ont disparus du jour au lendemain des navigateurs qui les avaient implémentés ?

Conclusion

Cette nouvelle façon de concevoir des standards est intéressante. Elle ouvre la porte aux concepteurs, et permet de les inclure dans le processus d’innovation. Avec CSS Houdini, de nouveaux effets sont possibles, et ces effets sont rendus de manière plus performante dans les navigateurs actuels. Mais cela implique quand même quelques contraintes : du JavaScript supplémentaire, plus complexe à mettre en oeuvre, etc.

Dans tous les cas, CSS Houdini est surtout pensé pour la performance, pas vraiment pour la créativité.

On peut aussi voir ces APIs comme une opportunité pour l’évolution des standards classiques. Si un effet visuel, ou un mode de positionnement, devient populaire, il pourrait alors être standardisé, pour être inclus directement en CSS. Mais qu’en sera t’il de la gestion des performances si l’on conserve les méthodes de rendus actuelles ?

Alors, vous, que pensez-vous de tout ça ?

Publié par Alsacreations.com

Le: 01 06 2020 à 14:19 WebdesignerNews

http://www.opengif.net/

Le: 01 06 2020 à 14:15 presse-citron.net Auteur: Arthur Vera

Google Chrome Batterie

La plupart des revenus de Google proviennent de la publicité et l'entreprise continue d'investir dans ce domaine.

Le: 01 06 2020 à 13:30 presse-citron.net Auteur: Louise Millon

HBO Max

Plutôt que de miser sur la puissance des algorithmes comme Netflix, HBO Max prévoit de se baser sur la curation où les contenus sont « recommandés par les humains ».

Le: 01 06 2020 à 13:16 WebdesignerTrends Auteur: Arnaud STECKLE

Votre dose mensuelle d’inspiration web design est arrivée pour vous en mettre plein les yeux !...

Le: 01 06 2020 à 12:48 WebdesignerNews

https://blog.alexdevero.com/javascript-generators/

Le: 01 06 2020 à 12:47 WebdesignerNews

https://www.smashingmagazine.com/2020/05/desktop-wallpaper-calendars-june-2020/

Le: 01 06 2020 à 12:45 presse-citron.net Auteur: Arthur Vera

Amazon Prime livraison

La demande étant supérieure à l'offre, des vendeurs sans scrupule parviennent à contourner la législation d'Amazon en vendant des produits bien plus cher.

Le: 01 06 2020 à 12:44 WebdesignerNews

https://uxdesign.cc/10-examples-of-custom-404-pages-ranked-from-best-to-worst-9c74825c18c9

Le: 01 06 2020 à 12:42 WebdesignerNews

https://csshint.com/css-slider/

Le: 01 06 2020 à 12:00 presse-citron.net Auteur: Louise Millon

Arnaque webcam ransomware Hadopi

La NSA indique que le groupe de pirates russes Sandworm s'attaquerait aux serveurs de messagerie Exim depuis l'été 2019.

Le: 01 06 2020 à 11:40 presse-citron.net Auteur: Jean-Yves Alric

stopcovid

Depuis quelques jours de la désinformation circule sur l’app du gouvernement.

Le: 01 06 2020 à 11:32 Journal du Net Développeurs

Après un long confinement ayant fragilisé leurs finances et leurs activités, le plus dur reste à venir pour les start-up. Beaucoup d'entre elles doivent repenser leur stratégie en faisant preuve d'inventivité.

Le: 01 06 2020 à 11:15 presse-citron.net Auteur: Arthur Vera

alibaba

Le géant chinois Alibaba sort de ses frontières et commence à venir discuter avec les influenceurs européens.

Le: 01 06 2020 à 11:15 presse-citron.net Auteur: Louise Millon

Apple T1

Le chercheur Bhavuk Jain a découvert l'existence d'une nouvelle faille dans le dispositif « Connexion avec Apple ». La marque à la pomme l'a récompensé à hauteur de 100 000 dollars dans le cadre de son programme Bug Bounty.

Le: 01 06 2020 à 11:00 korben.info Auteur: Korben

Les CSS c’est parfois la prise de tête. Mais c’est quand même bien pratique ! La développeuse Diana Smith, connue également sous le pseudo de CyanHarlow s’est essayé à l’art via CSS ! Et qu’est ce que ça donne ? Et bien voilà quelques-unes de ses oeuvres. Et si vous … Suite

Le: 01 06 2020 à 10:50 presse-citron.net Auteur: Stéphane Ficca

Image-Bug-Android

N'essayez pas de définir cette image comme fond d'écran sur votre smartphone Android, cela pourrait faire planter ce dernier...

Le: 01 06 2020 à 09:35 presse-citron.net Auteur: Louise Millon

NASA ISS SpaceX

Après un voyage de plusieurs heures, les astronautes Bob Behnken et Doug Hurley ont finalement retrouvé leurs trois collègues à bord de la Station Spatiale Internationale.

Le: 01 06 2020 à 09:10 presse-citron.net Auteur: Romain Vitt

iPad Pro 2020

En lançant l’iPad, Steve Jobs promettait une deuxième révolution après l’iPhone. Pari réussi puisque les tablettes tactiles font désormais partie de notre quotidien. Mais quelles sont les meilleures du marché ? Notre guide devrait vous éclairer.

Le: 01 06 2020 à 09:00 korben.info Auteur: Korben

Sur mon site je vous ai déjà parlé de nombreux outils permettant de jouer et transformer vos fichiers vidéo ou audio. MystiQ Video Converter est un logiciel libre supplémentaire à mettre dans votre arsenal, et cela que vous soyez utilisateur de Windows (7 et plus), macOS (toujours en bêta) et … Suite

Le: 01 06 2020 à 08:45 presse-citron.net Auteur: Stéphane Ficca

PS5 - 4 Juin 2020

Sony aurait demandé aux développeurs de s'assurer que tous les nouveaux jeux PS4 soient rétrocompatibles avec la future PS5.

Le: 01 06 2020 à 08:20 presse-citron.net Auteur: David Laurent

Reality Z - Netflix

Reality Z, une série brésilienne, va débarquer dans quelques jours sur la plateforme de streaming. Un programme de télé-réalité d'un genre très particulier.

Le: 01 06 2020 à 07:55 presse-citron.net Auteur: David Laurent

Upgrade film série

Avant Invisible Man, Leigh Whannell était sur d'autres projets moins connus du grand public. Upgrade en fait partie et le succès se confirme.

Le: 01 06 2020 à 07:42 Framablog Auteur: Khrys

Comme chaque lundi, un coup d’œil dans le rétroviseur pour découvrir les informations que vous avez peut-être ratées la semaine dernière. Brave New World Covid-19 : les (très) bonnes recettes de la Nouvelle-Zélande pour maîtriser le virus – Le Parisien (leparisien.fr) … Lire la suite­­

Le: 01 06 2020 à 07:30 presse-citron.net Auteur: David Laurent

Spider-Man 2 : Quand Sam Raimi faisait une référence à Doctor Strange

J.K. Simmons, l'acteur qui a interprété J. Jonah Jameson dans les films Spider-Man de Sam Raimi a dévoilé avoir signé pour plusieurs films avec le Marvel Cinematic Universe.

Le: 01 06 2020 à 07:07 korben.info Auteur: Korben

Loki n’est pas uniquement le frangin de Thor (le Dieu). C’est également un réseau permettant à ses utilisateurs de communiquer ou de réaliser des transactions de manière privée, sécurisée et anonyme via Internet au travers d’un système décentralisé. Loki serait-il le frère de Tor (le réseau) ? Loki combine un … Suite