2 points par GN⁺ 2024-09-05 | 1 commentaires | Partager sur WhatsApp
  • Avec la prise en charge de CSS @property dans l’ensemble des navigateurs modernes, il devient possible de préciser pour des propriétés personnalisées la syntaxe, la valeur initiale et l’héritage, et de laisser le navigateur interpoler naturellement les valeurs
  • Le bouton CTA d’exemple définit --gradient-angle comme un <angle> afin de passer de 0deg à 360deg, et crée une bordure brillante en rotation avec conic-gradient
  • L’effet au survol attribue un type à des propriétés comme --gradient-percent, --gradient-angle-offset et --gradient-shine pour que la longueur et la luminosité de la brillance évoluent en douceur
  • La vitesse de rotation est gérée en déclarant deux fois la même animation, la seconde étant en sens inverse et en pause, puis ralentie de moitié depuis sa position courante au survol
  • Les définitions de propriétés personnalisées basées sur @property rendent possibles des expressions CSS auparavant difficiles à implémenter, avec un potentiel réel pour les applications de grande taille et les design systems

Les animations de propriétés personnalisées rendues possibles par @property

  • @property est une règle qui permet de déclarer pour une propriété personnalisée CSS la syntaxe autorisée, la valeur initiale et si elle est héritée ou non
  • Cette fonctionnalité est liée à l’API CSS Properties and Values API de CSS Houdini, et elle est désormais prise en charge par tous les navigateurs modernes
  • Lorsque le navigateur connaît le type d’une propriété personnalisée, il peut interpoler les valeurs intermédiaires, ce qui facilite la création de transitions et d’animations plus fluides qu’avec de simples variables CSS

Une bordure brillante rotative pour un bouton CTA

  • L’exemple reproduit en CSS un style de bouton CTA scintillant que l’on voit souvent sur le web
  • La propriété personnalisée clé est --gradient-angle, dont la syntaxe <angle> et la valeur initiale 0deg sont déclarées avec @property
@property --gradient-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
  • Grâce à cette définition, le navigateur peut effectuer une transition naturelle de 0deg à 360deg, ce qui donne l’impression que conic-gradient tourne
@keyframes rotate-gradient {
  to { --gradient-angle: 360deg; }
}

.rotate-gradient {
  background: conic-gradient(from var(--gradient-angle), transparent, black);
  animation: rotate-gradient 10s linear infinite;
}
  • Le démo CodePen permet de voir ce concept avec un minimum de code

Une brillance de bordure créée avec des calques d’arrière-plan

  • La bordure brillante est construite en combinant linear-gradient et conic-gradient dans background, avec une origine différente pour chaque arrière-plan
    • linear-gradient utilise padding-box, ce qui l’empêche de déborder dans la zone de bordure
    • conic-gradient utilise border-box, ce qui lui permet de s’étendre jusque dans l’espace créé par l’épaisseur de bordure
    • Une bordure transparente de 1px est ajoutée pour révéler le conic-gradient en rotation
.border-gradient {
  background:
    linear-gradient(black, black) padding-box,
    conic-gradient(from var(--gradient-angle), transparent 25%, white, transparent 50%) border-box;
  border: 1px solid transparent;
}

Un dégradé qui change en douceur au survol

  • Chaque propriété personnalisée nécessaire à la transition au survol déclare sa syntax via @property afin que le navigateur puisse interpoler les changements de valeur
  • L’arrière-plan du bouton se compose d’un linear-gradient pour la couleur interne et d’un conic-gradient pour la brillance de bordure
  • --gradient-percent détermine la taille de la zone brillante, et passe à un pourcentage plus élevé au survol pour allonger la traînée lumineuse
  • --gradient-angle-offset sert à réaligner l’angle du dégradé afin que la brillance ne donne pas l’impression de bondir vers l’avant ou l’arrière pendant le survol
  • La luminosité --gradient-shine est réduite pour mieux se fondre avec les couleurs de surbrillance autour du bouton

Comment ralentir la rotation au survol

  • L’astuce CSS pour ralentir la vitesse de rotation consiste à déclarer deux fois la même animation de rotation
  • La seconde animation est définie en sens inverse, avec une durée divisée par deux, et reste en paused par défaut
  • Au survol, animation-play-state: running remplace paused, ce qui ralentit la rotation à la moitié de la vitesse
  • Lorsque le survol se termine, l’animation ne revient pas brusquement à sa position de départ et accélère de nouveau depuis sa position actuelle
  • L’animation du bouton CTA utilise cette méthode pour que rotation et mouvement restent synchronisés même quand la vitesse change

Petits scintillements et surbrillance interne

  • Le petit motif de points à l’intérieur du bouton est rendu via un arrière-plan radial-gradient sur le pseudo-élément ::before
  • --gradient-angle y est également réutilisée, tandis qu’un masque conic-gradient en rotation ne révèle qu’une partie du motif de points
  • L’angle du dégradé du masque reçoit un décalage de 45deg pour rester aligné avec la rotation de la bordure brillante
.shiny-cta::before {
  mask-image: conic-gradient(
    from calc(var(--gradient-angle) + 45deg),
    black,
    transparent 10% 90%,
    black
  );
}
  • Le pseudo-élément ::after reçoit un dégradé incluant des couleurs de surbrillance afin de tourner avec la zone brillante
  • Cette surbrillance interne renforce l’impression d’une lumière qui circule à l’intérieur du bouton

Ajuster les couleurs au survol et peaufiner le rendu

  • Comme ::before et ::after sont déjà utilisés sur le bouton, le texte est enveloppé dans un span
  • L’un des pseudo-éléments du span reçoit un box-shadow flou avec la couleur de surbrillance, étendu jusqu’à la taille du bouton
  • Au survol, ce pseudo-élément grandit lentement puis rétrécit, créant un effet respiratoire subtil
  • Combiné à la couleur de surbrillance en rotation à l’intérieur, cela complète l’effet final du bouton CTA

Un potentiel qui va jusqu’aux design systems

1 commentaires

 
GN⁺ 2024-09-05
Avis sur Hacker News
  • Je ne suis pas développeur web, mais j’ai créé des sites jouets sans framework et fait des tâches de base avec quelques frameworks web. Quand CSS est apparu, il suffisait d’un peu de temps pour tout avoir en tête et pouvoir l’utiliser.
    Le CSS du premier exemple CodePen ressemble presque à une syntaxe ésotérique illisible, et je me demande s’il faut vraiment avoir jusqu’à un petit langage de programmation d’animations dans le système de styles.
    J’ai l’impression que c’est quelque chose qu’on pourrait faire en JavaScript ; je comprends l’aversion envers l’usage de JS partout, mais si on parle d’un langage de programmation, ce genre de tâche semble quand même plus proche de son métier.

    • Je ne comprends pas bien ce ressenti. Si l’on n’est pas développeur web, et surtout pas développeur front-end, on n’a probablement pas souvent à créer des éléments HTML avec ce genre d’effets spectaculaires ; je ne vois donc pas pourquoi ce que CSS peut faire avec ses fonctionnalités avancées poserait problème.
      Bien sûr, on peut aussi le faire en JavaScript, et on peut même poser un canvas et programmer l’effet sur le GPU avec WebGL. En contrepartie, il faut réimplémenter soi-même toutes les fonctionnalités d’accessibilité d’un bouton HTML, et je doute que ce soit plus simple.
    • C’est une question de performances. En JS, il faut que ça tourne sans accroc 60 fois par seconde, mais JS est monothread : dès que le thread principal se bloque, on rate des frames.
      Même si les moteurs JS modernes sont impressionnants, ils ne sont pas aussi efficaces que du code natif ; l’utilisation CPU augmente, et au final ce n’est pas bon non plus pour l’autonomie de la batterie.
    • Toute occasion d’éviter JavaScript sur un site est la bienvenue, même si cela demande plus de travail. Les visiteurs qui désactivent JavaScript peuvent éviter beaucoup des exploits et traqueurs qui empoisonnent le Web d’aujourd’hui.
      Pour la même raison, j’apprécie les sites où JavaScript n’est pas obligatoire.
    • Ce n’est pas une bonne idée d’avoir besoin d’un langage de programmation complet pour des choses qui ne concernent que l’apparence d’une page.
      Certaines plateformes d’hébergement autorisent, pour des raisons de sécurité, la personnalisation en HTML et CSS mais bloquent JS. C’est le cas de sites comme Itch.io, où l’on peut personnaliser des jeux et des profils ; avec les animations CSS, on peut créer de beaux effets sans donner l’accès à JS, ce qui est justifié et utile.
    • J’ai l’impression que, sans bien comprendre le domaine du problème ni connaître la syntaxe, on voit comme un changement négatif ce qui n’est pas immédiatement compréhensible.
  • En lisant cet article, j’ai senti mon cerveau résister à des concepts inconnus. Avant de regarder les exemples du blog, je recommande de lire d’abord l’article MDN lié dans la première phrase.
    @property est quelque chose qu’il faut probablement manipuler soi-même pour en saisir l’intérêt ; si l’on veut implémenter des UI complexes tout en réduisant la dépendance à JS, connaître ce genre de fonctionnalité CSS obscure devient une arme puissante.

    • Même après avoir lu l’article MDN, je n’arrive vraiment pas à comprendre. J’ai l’impression que ce sont littéralement des variables CSS.
      Les variables CSS étaient déjà soumises à la cascade et pouvaient être surchargées par des classes, etc. ; des choses comme bg-opacity de Tailwind fonctionnent aussi comme ça, non ?
    • Même impression pour moi. Je trouve que cet article explique vraiment très mal.
      En regardant MDN, ça ressemble beaucoup aux anciennes variables CSS, mais avec une portée limitée à un élément précis ou à ses enfants, et avec en plus des contraintes qui reconnaissent des unités CSS comme les angles ou les pourcentages.
      Cela dit, je ne pense pas m’en servir. Ce petit avantage ne justifie pas le coût en complexité et en compatibilité, et j’essaie d’éviter les nouvelles syntaxes inutiles. Depuis les variables CSS, je me suis largement désintéressé des nouvelles fonctionnalités de CSS.
    • Je pensais être le seul, mais ça me paraît vraiment étrange.
      Je ne vois pas bien quel avantage cela apporte par rapport à l’usage de transform en CSS.
  • J’aime travailler avec CSS, mais comme je travaille aussi avec des collègues qui trouvent CSS difficile, je recommande vivement la chaîne YouTube de Kevin Powell.
    Il a abordé cette fonctionnalité plusieurs fois, et dans une vidéo publiée il y a une semaine, il montre une possibilité utile rendue possible par les propriétés enregistrées : https://youtu.be/U8NykwZNbGs
    Il existe aussi un article qui explique les propriétés enregistrées avec un exemple facile à suivre : https://moderncss.dev/providing-type-definitions-for-css-wit...

  • Les travaux récents sur CSS, en particulier Houdini, me rendent enthousiaste. Je n’avais pas ressenti ça depuis que j’avais vu un livre sur les fonctionnalités d’IE 5.5.
    Au cours des 14 dernières années, CSS a bien reçu beaucoup de nouvelles fonctionnalités, mais il s’agissait surtout de fonctions de base auxquelles on s’attendrait dans un framework de styles, comme de nouvelles options de mise en page ou des variables.
    Mais les développeurs d’IE étaient vraiment débridés, et on pouvait même transformer du code JS en module et l’attacher à des éléments via CSS. J’ai l’impression que ces fonctionnalités radicales reviennent enfin.
    Exemple : https://developer.chrome.com/docs/css-ui/houdini

    • Je ne sais pas trop si « débridés » est employé ici dans un sens positif ou négatif.
    • Ce n’était pas comme ça que fonctionnait css3pie (http://css3pie.com/) ?
  • C’est un article court et bon. Si vous voulez voir davantage d’exemples, surtout des exemples beaucoup plus simples qui permettent de saisir rapidement l’idée, je recommande un ancien article de CSS-Tricks.
    Il date de 2021, mais il reste valable et bien fait : https://css-tricks.com/exploring-property-and-its-animating-...
    Je pense que l’exemple de panneau à volets où défilent des chiffres d’aéroport / un minuteur devrait particulièrement vous plaire.

  • Je m’étais éloigné du développement web pendant un moment, et il m’a fallu beaucoup trop de temps pour comprendre ce que cette fonctionnalité fait concrètement. Je trouve que l’article ne l’explique pas très bien
    Si j’ai bien compris, au lieu d’une valeur brute comme 360deg, on écrit quelque chose comme from var(--gradient-angle), et cette valeur est remplacée par celle récupérée à l’endroit défini dans le bloc @property --gradient-angle {...}
    Il y a aussi inherits: false; : je vois bien le comportement, mais je ne comprends pas pourquoi c’est nécessaire. On peut déjà contrôler l’héritage avec des sélecteurs CSS, donc j’ai du mal à suivre si cela veut dire qu’on peut maintenant aussi le contrôler ailleurs
    Je me demande aussi pourquoi il faut définir un type dans le bloc @property. Ailleurs en CSS, on ne définit pas de type ; le navigateur ne pourrait-il pas l’inférer en regardant où @property est utilisé ?

    • Pour moi, le principal avantage, c’est que cette fonctionnalité permet d’animer des variables CSS
      Lors d’une ancienne expérimentation où je transformais le design de YouTube en quelque chose de néon, j’avais fait en sorte que la couleur principale soit contrôlée par une seule variable CSS, puis que sa teinte se déplace lentement sur tout le spectre
      Sans @property, on ne peut pas animer des variables CSS : il ne s’agit donc pas simplement d’utiliser une variable à la place d’une valeur brute, mais de pouvoir animer cette variable ainsi que tous les endroits où elle est référencée. Avec un seul @keyframes neon-flow { from { --dc-neon-hue: 0; } to { --dc-neon-hue: 360; } }, on peut faire bouger la couleur principale, les ombres, etc.
      inherits: false contrôle la manière dont une propriété personnalisée est héritée. On peut la faire hériter par les enfants, comme color: red, ou l’appliquer uniquement à l’élément concerné, comme display: flex
      Le type semble nécessaire pour savoir, au moment statique, quoi animer. Une variable CSS peut être n’importe quoi, alors que pour une propriété CSS normale, comme color, la propriété elle-même fournit l’information de type
      Ce qui est intéressant, c’est que cette syntaxe de type est la même que la syntaxe formelle qu’on voit sur MDN : https://developer.mozilla.org/en-US/docs/Web/CSS/color#forma... On a l’impression que les entrailles de CSS sont exposées comme une API utilisable par les développeurs
    • Les propriétés CSS existaient déjà avant @property : par exemple, on pouvait déclarer --my-prop: 10px, puis l’utiliser ailleurs avec var(--my-prop)
      La nouveauté de @property, c’est qu’elle permet de définir une propriété à l’avance, afin de préciser quel type syntaxique elle doit accepter, si elle doit hériter de la valeur du parent, et quelle est sa valeur par défaut, initial-value
      Ainsi, si une propriété déclarée comme un type angle reçoit --my-prop: 5px sur un élément, cette valeur est ignorée. Auparavant, elle devenait une valeur valide et pouvait produire des effets de bord inattendus selon l’endroit où elle était utilisée
      De plus, écrire quelque chose comme --my-prop: initial permet d’utiliser initial-value sans connaître exactement la valeur par défaut
    • Merci pour cette explication. Il est difficile de comprendre l’article quand il n’explique pas ce que fait @property ni comment l’utiliser
      Tout est complètement masqué par un exemple excessivement complexe
  • Ce site web me met de bonne humeur
    J’ai toujours aimé bricoler du CSS, mais après plus de 10 ans de développement web et un métier lié au web, j’ai aussi compris à quel point les gens détestent CSS
    Je peux passer un temps infini à explorer et expérimenter avec du HTML+CSS écrit à la main, et même le déployer pour voir ce que ça donne sur un vrai téléphone. 99 % de ces essais ne servent nulle part
    Pour la plupart des gens, ce serait une perte de temps, mais ce site m’a vraiment égayé la journée

    • J’aime vraiment CSS. Je trouve aussi que c’est suffisamment facile à comprendre
      Il est devenu plus complexe ces dix dernières années, mais les choses qu’on faisait il y a dix ans sont aujourd’hui bien plus simples, et le code de l’époque fonctionne toujours
    • Les gens qui proclament haut et fort qu’ils détestent CSS sont généralement des gens qui ne comprennent pas CSS
      Ce n’est pas grave. Moi non plus, je ne comprends pas APEX ou APL, ni le dernier framework à la mode du jour. Mais je comprends CSS, et du coup j’y prends pas mal de plaisir
      Certaines personnes accrochent, d’autres non. Le problème apparaît quand quelqu’un à qui CSS ne convient pas doit en faire dans son travail, et bien sûr il finit par le détester. Si mon boulot consistait à maintenir une installation Active Directory, je détesterais ça aussi. Mais CSS en soi n’est pas mauvais
    • CSS est amusant à bidouiller, et ses nouvelles fonctionnalités valent la peine d’être explorées. Cela dit, j’ai parfois l’impression que les fonctionnalités CSS naissent dans une ambiance du type « qu’est-ce qu’on pourrait encore fabriquer ? »
      Il existe sans doute quelque part un forum où ont lieu des discussions sérieuses, mais j’ai l’impression de passer à côté
    • C’est encore assez minimaliste, mais j’essaie d’écrire davantage de CSS à la main pour retrouver les sensations du travail en dehors d’outils comme Bootstrap ou Tailwind
      En production, j’ai surtout écrit presque tout le front-end en JSX, mais depuis que je suis tombé dans le terrier du web scraping, ma compréhension de la logique des sélecteurs s’est beaucoup améliorée
      Une idée provocatrice liée à ça : si, dans la pratique, on utilisait davantage d’éléments sémantiques, la logique des sélecteurs ne serait probablement pas aussi pénible qu’elle l’est aujourd’hui. Et on n’aurait pas non plus à maintenir soi-même des comportements que le HTML pur définit déjà, comme les modales
    • Dès qu’on ne se contente plus de cibler sa propre combinaison spécifique appareil·écran·navigateur·version de navigateur·OS, mais qu’on doit implémenter quelque chose de pris en charge assez largement, les subtiles violations de spécification deviennent vraiment agaçantes
      Autrefois, Microsoft était le contrevenant le plus célèbre aux spécifications ; aujourd’hui, je dirais que c’est Apple
  • Ces animations donnent à tout un air de publicités display des années 2000. Et pas dans le bon sens
    J’espère vraiment que cette esthétique ne deviendra pas tendance

    • Pareil pour moi. J’ai trouvé intéressant que l’exemple CodePen puisse être réalisé uniquement en CSS, mais c’était un peu excessif ; si j’avais vu le premier bouton d’appel à l’action sur un vrai site web, je l’aurais trouvé ringard et embarrassant
      Ces choses donnent fortement une impression de marketing et de manipulation. J’aimerais qu’on me laisse lire le site et décider quoi faire. Je n’ai pas envie qu’on m’interrompe en attirant artificiellement mon regard vers les éléments qui rapportent de l’argent
    • Au début, j’ai cru que CodePen essayait de me faire une montée en gamme
    • Ce sont des choses qui se font déjà dans le code des applications natives, donc il faut qu’il existe des fonctionnalités équivalentes sur le web
      Sinon, tout le monde les implémentera dans des écosystèmes fermés
  • PFM, autrement dit « pure magie », c’est exactement l’impression qu’on a en voyant ce que permettent les animations CSS
    Mais c’est tellement spécialisé pour CSS et uniquement pour CSS que c’est plus difficile à apprendre et à conceptualiser que de l’implémenter procéduralement en JS. Je n’arrive pas vraiment à penser de cette façon, et les options d’utilisation de CSS flex me suffisent déjà largement à me donner du fil à retordre

    • CSS donne vraiment l’impression d’être un territoire extraterrestre à part entière. Le fait que sa syntaxe soit peu familière pour la plupart des développeurs n’aide pas
      Mais c’est puissant, vraiment incroyablement puissant, et très efficace dans la plupart des navigateurs. L’écrasante majorité des développeurs d’apps web n’a pas besoin de 99 % de ce que CSS offre, mais c’est chouette de savoir que ces fonctionnalités existent
    • C’est pour ça que j’ai embauché un designer qui sait coder en HTML+CSS
      Je peux déposer sur la page des éléments sans style reliés à la logique métier, et le designer peut les styliser comme il le souhaite. Si nécessaire, on peut itérer ensuite pour peaufiner l’UI
    • C’est un paradigme déclaratif, comme SQL
      Vu d’un point de vue purement impératif, il faut un peu de temps pour lire les spécifications et expérimenter, mais je pense que c’est une façon de penser qui vaut davantage que le simple fait d’utiliser SQL et CSS. Bien sûr, SQL et CSS eux-mêmes valent déjà largement le coup
    • JS est toujours, vraiment toujours, le dernier recours. Ces dernières années, avec l’arrivée de fonctionnalités CSS dans la plupart des navigateurs, j’ai retiré beaucoup de JS du code, et j’aime rendre les pages JavaScript Zero
      Je serais ravi qu’on se décide seulement sur le nom de la fonctionnalité CSS « masonry »[1], pour pouvoir l’utiliser sans script
      [1] https://github.com/w3c/csswg-drafts/issues/9733
    • Dans ce cas, property fait partie de l’API CSS Houdini, et permet de manipuler CSS depuis JavaScript de façon bien plus puissante qu’auparavant
      https://developer.mozilla.org/en-US/docs/Web/API/Houdini_API...
  • L’enthousiasme de l’auteur pour ce nouveau morceau de CSS est d’un niveau que je n’avais presque pas vu depuis dix ans, et ça fait vraiment plaisir
    Si j’avais eu la vingtaine, j’aurais passé des heures, voire des jours, à bricoler avec les possibilités de cette fonctionnalité. J’aimais réussir à faire fonctionner quelque chose en CSS
    Aujourd’hui, grâce à flexbox, grid et au fait que la plupart des sites et apps web suivent des principes de design standard, c’est devenu assez facile, et je pense que l’UI web est en grande partie un problème résolu

    • Je me demande quels sont ces principes de design standard
    • Je ne vois pas bien ce qui aurait été résolu. La mise en page ?
      Il m’arrive encore de devoir relire les zones ambiguës de flex et grid. Le positionnement sticky est l’une des fonctionnalités les plus utiles, mais quand il ne marche pas pour une raison ou une autre, le déboguer et en comprendre la cause est très difficile, voire presque impossible. Il peut par exemple y avoir un overflow quelque part dans un parent
      Il est aussi difficile de trouver de la documentation qui explique bien ces cas limites, et déboguer du CSS uniquement à partir du code source, sans les outils de développement, est presque impossible : il faut inspecter les éléments à l’exécution
      La plupart des éléments de saisie natifs restent très limités côté stylisation, et on a aussi attendu des années les modales et popovers natifs. La dernière fois que j’ai vérifié, on ne pouvait toujours pas animer une hauteur de display: none vers block
      J’ai l’impression qu’on s’est tellement habitués aux nombreux problèmes de CSS qu’on a perdu tout esprit critique