État du CSS 2022

Fonctionnalités de stylisation Web d'aujourd'hui et de demain, présentées lors de Google IO 2022, ainsi que quelques extras.

L'année 2022 s'annonce comme l'une des plus belles années pour le CSS, tant en termes de fonctionnalités que de versions de fonctionnalités de navigateur coopératives, avec un objectif collaboratif d'implémenter 14 fonctionnalités.

Présentation

Cet article reprend la conférence donnée lors de Google IO 2022. Il ne s'agit pas d'un guide détaillé sur chaque fonctionnalité, mais plutôt d'une introduction et d'un bref aperçu pour piquer votre intérêt, en offrant une vue d'ensemble plutôt qu'une analyse approfondie. Si vous êtes intéressé, consultez les liens vers des ressources à la fin de chaque section pour en savoir plus.

Sommaire

Utilisez la liste ci-dessous pour accéder aux sujets qui vous intéressent :

Compatibilité du navigateur

La principale raison pour laquelle de nombreuses fonctionnalités CSS sont définies pour être publiées de manière coopérative est due aux efforts de Interop 2022. Avant d'étudier les efforts d'interopérabilité, il est important d'examiner les efforts de Compat 2021.

Compat 2021

Les objectifs de 2021, basés sur les commentaires des développeurs via des enquêtes, étaient de stabiliser les fonctionnalités actuelles, d'améliorer la suite de tests et d'augmenter les scores de réussite des navigateurs pour cinq fonctionnalités :

  1. Positionnement sticky
  2. Taille aspect-ratio
  3. Mise en page flex
  4. Mise en page grid
  5. Positionnement et animation transform

Les résultats des tests ont été globalement augmentés, démontrant ainsi une stabilité et une fiabilité accrues. Félicitations à toutes les équipes !

Interop 2022

Cette année, les navigateurs se sont réunis pour discuter des fonctionnalités et des priorités sur lesquelles ils comptaient travailler, unissant ainsi leurs efforts. Elle prévoit de fournir les fonctionnalités Web suivantes aux développeurs:

  1. @layer
  2. Espaces colorimétriques et fonctions
  3. Confinement
  4. <dialog>
  5. Compatibilité des formulaires
  6. Défilement
  7. Sous-grille
  8. Typographie
  9. Unités de la fenêtre d'affichage
  10. Compatibilité Web

C'est une liste passionnante et ambitieuse que j'ai hâte de voir se concrétiser.

Nouveautés pour 2022

Sans surprise, l'état du CSS 2022 est fortement affecté par le travail d'Interop 2022.

Calques en cascade

Navigateurs pris en charge

  • Chrome: 99
  • Edge: 99
  • Firefox: 97
  • Safari : 15.4.

Source

Avant @layer, il était très important de découvrir l'ordre des feuilles de style chargées, car les styles chargés en dernier peuvent remplacer les styles précédemment chargés. Cela a conduit à des feuilles de style d'entrée gérées avec minutie, où les développeurs devaient charger d'abord les styles moins importants, puis les styles plus importants. Des méthodologies complètes existent pour aider les développeurs à gérer cette importance, comme ITCSS.

Avec @layer, le fichier d'entrée peut prédéfinir les calques et leur ordre à l'avance. Ensuite, à mesure que les styles sont chargés ou définis, ils peuvent être placés dans une couche, ce qui permet de préserver l'importance du forçage de style, mais sans l'orchestration de chargement minutieusement gérée.

La vidéo montre comment les calques de cascade définis permettent un processus d'écriture et de chargement plus libre et plus libre, tout en conservant la cascade si nécessaire.

Les outils pour les développeurs Chrome permettent de visualiser les styles provenant de quelles couches :

Capture d&#39;écran de la barre latérale &quot;Styles&quot; des outils pour les développeurs Chrome, mettant en évidence l&#39;apparence des styles dans les nouveaux groupes de calques.

Ressources

Sous-grille

Navigateurs pris en charge

  • Chrome : 117.
  • Edge: 117
  • Firefox : 71.
  • Safari: 16.

Source

Avant subgrid, une grille à l'intérieur d'une autre grille ne pouvait pas s'aligner sur ses cellules ou lignes de grille parentes. Chaque mise en page de grille était unique. De nombreux concepteurs placent une seule grille sur l'ensemble de leur conception et alignent constamment les éléments, ce qui n'est pas possible en CSS.

Après subgrid, un enfant d'une grille peut adopter les colonnes ou les lignes de ses parents comme siennes, et s'aligner lui-même ou ses enfants sur elles.

Dans la démonstration suivante, l'élément "body" crée une grille classique de trois colonnes : la colonne du milieu est appelée main, et les colonnes de gauche et de droite nomment leurs lignes fullbleed. Ensuite, chaque élément du corps, <nav> et <main>, adopte les lignes nommées du corps en définissant grid-template-columns: subgrid.

​​body {
  display: grid;
  grid-template-columns:
    [fullbleed-start]
    auto [main-start] min(90%, 60ch) [main-end] auto
    [fullbleed-end]
  ;
}

body > * {
  display: grid;
  grid-template-columns: subgrid;
}

Enfin, les enfants de <nav> ou <main> peuvent s'aligner ou se redimensionner à l'aide des colonnes et des lignes fullbleed et main.

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}

Les outils de développement peuvent vous aider à voir les lignes et les sous-grilles (pour le moment, uniquement dans Firefox). Dans l'image suivante, la grille parente et les sous-grilles ont été superposées. Il ressemble maintenant à ce que les concepteurs pensaient à la mise en page.

Capture d&#39;écran d&#39;une démonstration de sous-grille, utilisant les outils de superposition de grille de Chrome DevTools pour afficher les lignes définies par CSS.

Dans le panneau des éléments des outils de développement, vous pouvez voir quels éléments sont des grilles et des sous-grilles, ce qui est très utile pour déboguer ou valider la mise en page.

Capture d&#39;écran du panneau &quot;Elements&quot; des outils pour les développeurs Chrome indiquant quels éléments ont une mise en page sous forme de grille ou de sous-grille.
Screenshot from Firefox Devtools

Ressources

Requêtes de conteneur

Navigateurs pris en charge

  • Chrome : 105
  • Edge : 105.
  • Firefox: 110
  • Safari : 16.

Source

Avant @container, les éléments d'une page Web ne pouvaient répondre qu'à la taille de l'ensemble de la fenêtre d'affichage. Cela est idéal pour les mises en page macro, mais pour les micro-mises en page, dont le conteneur externe ne correspond pas à l'ensemble du viewport, il est impossible que la mise en page s'ajuste en conséquence.

Après @container, les éléments peuvent répondre à la taille ou au style d'un conteneur parent. La seule mise en garde est que les conteneurs doivent se déclarer en tant que cibles de requête possibles, ce qui est une petite exigence pour un avantage important.

/* establish a container */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}

Ces styles permettent aux colonnes Lun, Mar, Mer, Jeu et Ven de la vidéo suivante d'être interrogées par les éléments d'événement.

Démonstration par Una Kravets

Voici le code CSS permettant d'interroger le conteneur calendar-day pour connaître sa taille, puis d'ajuster la mise en page et la taille des polices:

@container calendar-day (max-width: 200px) {
  .date {
    display: block;
  }

  .date-num {
    font-size: 2.5rem;
    display: block;
  }
}

Voici un autre exemple : un composant de livre s'adapte à l'espace disponible dans la colonne vers laquelle il est glissé :

Démonstration par Max Böck

Una a raison d'évaluer la situation comme étant la nouvelle réactivité. Vous devez prendre de nombreuses décisions de conception intéressantes et significatives lorsque vous utilisez @container.

Ressources

accent-color

Navigateurs pris en charge

  • Chrome : 93.
  • Edge: 93
  • Firefox: 92
  • Safari : 15.4.

Source

Avant accent-color, lorsque vous souhaitiez créer un formulaire avec des couleurs correspondant à la marque, vous pouviez vous retrouver avec des bibliothèques ou des solutions CSS complexes qui devenaient difficiles à gérer au fil du temps. Bien qu'il vous ait donné toutes les options et qu'il ait probablement inclus l'accessibilité, le choix d'utiliser les composants intégrés ou d'adopter les vôtres devient fastidieux.

Après accent-color, une ligne de CSS apporte une couleur de marque aux composants intégrés. En plus d'une teinte, le navigateur choisit intelligemment les couleurs contrastantes appropriées pour les parties annexes du composant et s'adapte aux jeux de couleurs du système (clair ou sombre).

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

Éléments HTML avec des accents clairs et sombres côte à côte à des fins de comparaison.

Pour en savoir plus sur accent-color, consultez mon article sur web.dev, où je présente de nombreux autres aspects de cette propriété CSS utile.

Ressources

Niveaux de couleur 4 et 5

Le Web a été dominé par le sRGB au cours des dernières décennies, mais dans un monde numérique en pleine expansion d'écrans haute définition et d'appareils mobiles prééquipés d'écrans OLED ou QLED, le sRGB ne suffit plus. De plus, des pages dynamiques qui s'adaptent aux préférences des utilisateurs sont attendues, et la gestion des couleurs est devenue une préoccupation croissante pour les concepteurs, les systèmes de conception et les responsables du code.

Mais pas en 2022. Le CSS propose un certain nombre de nouvelles fonctions et espaces de couleurs : - Couleurs qui exploitent les capacités de couleur HD des écrans. : espaces colorimétriques correspondant à un intent, comme l'uniformité perceptuelle. - Espaces de couleurs pour les dégradés qui modifient considérablement les résultats d'interpolation. - Fonctions de couleur pour vous aider à mélanger et à contraster, et à choisir l'espace dans lequel vous travaillez.

Avant toutes ces fonctionnalités de couleur, les systèmes de conception devaient précalculer les couleurs contrastantes appropriées et s'assurer que les palettes étaient suffisamment vives, tandis que les préprocesseurs ou JavaScript effectuaient le gros du travail.

Après toutes ces fonctionnalités de couleur, le navigateur et le CSS peuvent effectuer tout le travail, de manière dynamique et juste à temps. Au lieu d'envoyer de nombreux ko de CSS et de JavaScript aux utilisateurs pour activer la thématisation et les couleurs de visualisation des données, le CSS peut effectuer l'orchestration et les calculs. Le CSS est également mieux adapté pour vérifier la compatibilité avant utilisation ou gérer les solutions de remplacement de manière appropriée.

@media (dynamic-range: high) {
  .neon-pink {
    --neon-glow: color(display-p3 1 0 1);
  }
}

@supports (color: lab(0% 0 0)) {
  .neon-pink {
    --neon-glow: lab(150% 160 0);
  }
}

hwb()

Navigateurs pris en charge

  • Chrome : 101.
  • Edge: 101.
  • Firefox: 96
  • Safari : 15.

Source

HWB signifie teinte, blancheur et noirceur. Il s'agit d'un moyen facile d'articuler la couleur, car il ne s'agit que d'une teinte et d'une quantité de blanc ou de noir pour éclaircir ou assombrir. Les artistes qui mélangent des couleurs avec du blanc ou du noir apprécieront peut-être cette nouvelle syntaxe de couleur.

L'utilisation de cette fonction de couleur permet d'obtenir des couleurs dans l'espace colorimétrique sRVB, comme les valeurs HSL et RVB. En termes de nouveautés pour 2022, cela ne vous donne pas de nouvelles couleurs, mais cela peut faciliter certaines tâches pour les fans de la syntaxe et du modèle mental.

Ressources

Espaces colorimétriques

La façon dont les couleurs sont représentées est déterminée par un espace colorimétrique. Chaque espace de couleurs offre différentes fonctionnalités et compromis pour travailler avec les couleurs. Certains peuvent empaqueter toutes les couleurs vives, tandis que d'autres peuvent les aligner d'abord en fonction de leur luminosité.

Le CSS 2022 devrait proposer 10 nouveaux espaces de couleurs, chacun avec des fonctionnalités uniques pour aider les concepteurs et les développeurs à afficher, choisir et mélanger des couleurs. Auparavant, sRVB était la seule option permettant d'utiliser la couleur, mais le CSS offre désormais un nouveau potentiel et un nouvel espace colorimétrique par défaut, LCH.

color-mix()

Navigateurs pris en charge

  • Chrome : 111.
  • Edge : 111.
  • Firefox : 113.
  • Safari: 16.2.

Source

Avant color-mix(), les développeurs et les concepteurs avaient besoin de préprocesseurs tels que Sass pour mélanger les couleurs avant que le navigateur ne les voie. La plupart des fonctions de mélange de couleurs ne permettaient pas non plus de spécifier l'espace de couleurs à utiliser pour le mélange, ce qui entraînait parfois des résultats confus.

Après color-mix(), les développeurs et les concepteurs peuvent mélanger des couleurs dans le navigateur, ainsi que tous leurs autres styles, sans exécuter de processus de compilation ni inclure de code JavaScript. De plus, ils peuvent spécifier l'espace colorimétrique dans lequel effectuer le mélange ou utiliser l'espace colorimétrique par défaut de LCH.

Souvent, une couleur de la marque est utilisée comme base et des variantes sont créées à partir de celle-ci, comme des couleurs plus claires ou plus foncées pour les styles de survol. Voici à quoi cela ressemble avec color-mix() :

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(var(--brand) 25%, black);
  --lighter: color-mix(var(--brand) 25%, white);
}

Si vous souhaitez mélanger ces couleurs dans un autre espace colorimétrique, comme srgb, modifiez-le :

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}

Voici une démonstration de thématisation à l'aide de color-mix(). Essayez de modifier la couleur de la marque et regardez le thème se mettre à jour :

Profitez de mélanger des couleurs dans différents espaces de couleurs dans vos feuilles de style en 2022.

Ressources

color-contrast()

Navigateurs pris en charge

  • Chrome: non compatible.
  • Edge : non compatible.
  • Firefox : non compatible.
  • Safari: derrière un drapeau.

Source

Avant color-contrast(), les auteurs de feuilles de style devaient connaître à l'avance les couleurs accessibles. Une palette affiche souvent du texte noir ou blanc sur un nuancier de couleur pour indiquer à l'utilisateur du système de couleurs la couleur de texte nécessaire pour contraster correctement avec ce nuancier.

Capture d&#39;écran de trois palettes Material, montrant 14 couleurs et leurs couleurs de contraste blanc ou noir appropriées pour le texte.
Exemple tiré des palettes de couleurs Material Design 2014

Après color-contrast(), les auteurs de feuilles de style peuvent décharger entièrement la tâche sur le navigateur. Vous pouvez non seulement utiliser le navigateur pour choisir automatiquement une couleur noire ou blanche, mais vous pouvez lui fournir une liste de couleurs appropriées du système de conception et lui demander de choisir la première couleur pour transmettre le rapport de contraste souhaité.

Voici une capture d'écran d'une démonstration de jeu de palette de couleurs HBW, où les couleurs du texte sont choisies automatiquement par le navigateur en fonction de la couleur de l'échantillon :

Capture d&#39;écran de la démonstration de la palette HWB, où chaque palette est associée à un texte clair ou sombre différent, selon le navigateur.
Essayer la démonstration

Voici les principes de base de la syntaxe, où le gris est transmis à la fonction et le navigateur détermine si le noir ou le blanc présente le plus de contraste :

color: color-contrast(gray);

La fonction peut également être personnalisée avec une liste de couleurs, parmi lesquelles elle sélectionnera la couleur la plus contrastée :

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);

Enfin, si vous préférez ne pas choisir la couleur la plus contrastée de la liste, vous pouvez fournir un rapport de contraste cible, et la première couleur qui le dépasse est choisie :

color: color-contrast(
  var(--bg-blue-1)
  vs
  var(--text-lightest), var(--text-light), var(--text-subdued)
  to AA /* 4.5 could also be passed */
);

Cette fonction peut être utilisée pour autre chose que la couleur du texte, même si j'estime qu'il s'agit de son principal cas d'utilisation. Réfléchissez à la facilité avec laquelle il sera possible de fournir des interfaces accessibles et lisibles une fois que le choix des couleurs contrastées aura été intégré au langage CSS lui-même.

Ressources

Syntaxe des couleurs relatives

Navigateurs pris en charge

  • Chrome: 111
  • Edge : 111.
  • Firefox : 113.
  • Safari : 15.

Source

Avant la syntaxe de couleur relative, pour calculer la couleur et effectuer des ajustements, les canaux de couleur devaient être placés individuellement dans des propriétés personnalisées. Cette limitation a également fait du TSL la fonction de couleur principale pour manipuler les couleurs, car la teinte, la saturation ou la luminosité pouvaient toutes être ajustées de manière simple avec calc().

Après la syntaxe de couleur relative, n'importe quelle couleur dans n'importe quel espace peut être décomposée, modifiée et renvoyée sous forme de couleur, le tout sur une seule ligne de CSS. Plus de limites au HSL : les manipulations peuvent être effectuées dans n'importe quel espace de couleurs souhaité, et beaucoup moins de propriétés personnalisées doivent être créées pour faciliter le processus.

Dans l'exemple de syntaxe suivant, une couleur hexadécimale de base est fournie et deux nouvelles couleurs sont créées en fonction de celle-ci. La première couleur --absolute-change crée une nouvelle couleur en LCH à partir de la couleur de base, puis remplace la luminosité de la couleur de base par 75%, tout en conservant le chroma (c) et la teinte (h). La deuxième couleur --relative-change crée une nouvelle couleur en LCH à partir de la couleur de base, mais cette fois, elle réduit le chroma (c) de 20 %.

.relative-color-syntax {
  --color: #0af;
  --absolute-change: lch(from var(--color) 75% c h);
  --relative-change: lch(from var(--color) l calc(c-20%) h);
}

C'est comme mélanger des couleurs, mais c'est plus semblable à une altération qu'à un mélange de couleurs. Vous pouvez caster une couleur à partir d'une autre, ce qui vous permet d'accéder aux trois valeurs de canal nommées par la fonction de couleur utilisée, et d'ajuster ces canaux. Dans l'ensemble, il s'agit d'une syntaxe très intéressante et puissante pour la couleur.

Dans la démonstration suivante, j'ai utilisé la syntaxe de couleur relative pour créer des variantes plus claires et plus foncées d'une couleur de base, et j'ai utilisé color-contrast() pour m'assurer que les libellés avaient un contraste approprié :

Capture d&#39;écran à 3 colonnes, chaque colonne est plus sombre ou plus claire que la colonne centrale.
Essayer la démonstration

Cette fonction peut également être utilisée pour générer des palettes de couleurs. Voici une démonstration dans laquelle des palettes entières sont générées à partir d'une couleur de base fournie. Cet ensemble de CSS alimente toutes les différentes palettes, chaque palette fournissant simplement une base différente. En prime, depuis que j'ai utilisé LCH, regardez à quel point même les palettes sont perceptuelles : pas de zone chaude ou morte à voir, grâce à cet espace de couleur.

:root {
  --_color-base: #339af0;

  --color-0:  lch(from var(--_color-base) 98% 10 h);
  --color-1:  lch(from var(--_color-base) 93% 20 h);
  --color-2:  lch(from var(--_color-base) 85% 40 h);
  --color-3:  lch(from var(--_color-base) 75% 46 h);
  --color-4:  lch(from var(--_color-base) 66% 51 h);
  --color-5:  lch(from var(--_color-base) 61% 52 h);
  --color-6:  lch(from var(--_color-base) 55% 57 h);
  --color-7:  lch(from var(--_color-base) 49% 58 h);
  --color-8:  lch(from var(--_color-base) 43% 55 h);
  --color-9:  lch(from var(--_color-base) 39% 52 h);
  --color-10: lch(from var(--_color-base) 32% 48 h);
  --color-11: lch(from var(--_color-base) 25% 45 h);
  --color-12: lch(from var(--_color-base) 17% 40 h);
  --color-13: lch(from var(--_color-base) 10% 30 h);
  --color-14: lch(from var(--_color-base) 5% 20 h);
  --color-15: lch(from var(--_color-base) 1% 5 h);
}
Capture d&#39;écran de 15 palettes, toutes générées dynamiquement par CSS.
Regarder la démonstration

J'espère que vous savez maintenant comment les espaces de couleur et les différentes fonctions de couleur peuvent tous être utilisés à des fins différentes, en fonction de leurs forces et de leurs faiblesses.

Ressources

Espaces colorimétriques de dégradé

Avant les espaces de couleurs de dégradé, l'espace de couleur sRVB était utilisé par défaut. Il est généralement fiable, mais présente quelques faiblesses, comme la zone morte grise.

Quatre dégradés dans une grille, tous allant du cyan au rose foncé. LCH et LAB offrent un éclat plus cohérent, tandis que sRGB est un peu désaturé au milieu.

Après les espaces de couleurs en dégradé, indiquez au navigateur l'espace colorimétrique à utiliser pour l'interpolation des couleurs. Les développeurs et les concepteurs peuvent ainsi choisir le dégradé de leur choix. L'espace colorimétrique par défaut passe également à LCH au lieu de sRVB.

L'ajout de syntaxe se place après la direction du dégradé, utilise la nouvelle syntaxe in et est facultatif :

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);

Voici un dégradé de base et essentiel du noir au blanc. Examinez la plage de résultats dans chaque espace de couleurs. Certains atteignent le noir foncé plus tôt que d'autres, certains passent au blanc trop tard.

11 espaces colorimétriques comparés au noir et au blanc.

Dans cet exemple, le noir passe au bleu, car il s'agit d'un espace à problème connu pour les dégradés. La plupart des espaces de couleurs passent au violet lors de l'interpolation des couleurs ou, comme je l'appelle, lorsque les couleurs se déplacent dans leur espace de couleurs du point A au point B. Étant donné que le dégradé suit une ligne droite du point A au point B, la forme de l'espace colorimétrique modifie considérablement les arrêts du chemin.

11 espaces de couleurs comparés au bleu et au noir.

Pour en savoir plus, consultez ce fil Twitter.

Ressources

inert

Navigateurs pris en charge

  • Chrome : 102.
  • Edge : 102.
  • Firefox : 112.
  • Safari : 15.5.

Source

Avant inert, il était recommandé de guider l'attention de l'utilisateur vers les zones de la page ou de l'application qui nécessitaient une attention immédiate. Cette stratégie de sélection guidée est devenue connue sous le nom de "focus trapping", car les développeurs placent le focus dans un espace interactif, écoutent les événements de changement de focus et, si le focus quitte l'espace interactif, il est forcé de revenir. Les utilisateurs qui utilisent des claviers ou des lecteurs d'écran sont redirigés vers l'espace interactif pour s'assurer que la tâche est terminée avant de passer à autre chose.

Après inert, aucun piégeage n'est requis, car vous pouvez figer ou protéger des sections entières de la page ou de l'application. Les clics et les tentatives de changement de focus ne sont tout simplement pas disponibles lorsque ces parties d'un document sont inactives. On pourrait également considérer cela comme des gardes au lieu d'un piège, où inert n'a pas envie de vous faire rester quelque part, plutôt que de rendre d'autres endroits indisponibles.

La fonction JavaScript alert() en est un bon exemple:

Le site Web est affiché comme interactif, puis une fonction alert() est appelée et la page n'est plus active.

Dans la vidéo précédente, notez que la page était accessible à la souris et au clavier jusqu'à ce qu'un alert() soit appelé. Une fois la boîte de dialogue d'alerte affichée, le reste de la page était figé, ou inert. Le curseur de l'utilisateur est placé dans la boîte de dialogue d'alerte et n'a aucune autre page à consulter. Une fois que l'utilisateur a interagi et répondu à la requête de la fonction d'alerte, la page redevient interactive. inert permet aux développeurs d'obtenir facilement cette même expérience de concentration guidée.

Voici un petit exemple de code pour illustrer son fonctionnement :

<body>
  <div class="modal">
    <h2>Modal Title</h2>
    <p>...<p>
    <button>Save</button>
    <button>Discard</button>
  </div>
  <main inert>
    <!-- cannot be keyboard focused or clicked -->
  </main>
</body>

Une boîte de dialogue est un excellent exemple, mais inert est également utile pour des éléments tels que l'expérience utilisateur du menu latéral coulissant. Lorsqu'un utilisateur fait glisser le menu latéral, il n'est pas acceptable de laisser la souris ou le clavier interagir avec la page derrière lui. Cela peut être un peu délicat pour les utilisateurs. À la place, lorsque le menu latéral s'affiche, rendez la page inerte. Les utilisateurs doivent alors fermer ou naviguer dans ce menu latéral, et ne se retrouveront jamais perdus ailleurs sur la page avec un menu ouvert.

Ressources

Polices COLRv1

Avant les polices COLRv1, le Web utilisait les polices OT-SVG, qui sont également un format ouvert pour les polices avec des dégradés, des couleurs et des effets intégrés. Cependant, ils pouvaient devenir très volumineux. Bien qu'ils permettent de modifier le texte, les possibilités de personnalisation étaient limitées.

Après les polices COLRv1, le Web propose des polices plus petites, vectorielles, redimensionnables, repositionnables, avec dégradé et mode de fusion, qui acceptent des paramètres pour personnaliser la police en fonction de l'utilisation ou pour l'adapter à une marque.

Visualisation de comparaison et graphique à barres montrant comment les polices COLRv1 sont plus nettes et plus petites.
Source de l'image : https://developer.chrome.com/blog/colrv1-fonts/

Voici un exemple tiré de l'article du blog des développeurs Chrome concernant les emoji. Vous avez peut-être remarqué que si vous agrandissez la taille de police d'un emoji, il ne reste pas net. C'est une image et non de l'art vectoriel. Dans les applications, lorsqu'un emoji est utilisé, il est souvent remplacé par un élément de meilleure qualité. Avec les polices COLRv1, les emoji sont vectoriels et beaux :

Les polices d'icônes peuvent faire des choses incroyables avec ce format, en proposant des palettes de couleurs duotone personnalisées, et plus encore. Le chargement d'une police COLRv1 est identique à celui de tout autre fichier de police :

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

La personnalisation de la police COLRv1 se fait avec @font-palette-values, une règle CSS spéciale permettant de regrouper et de nommer un ensemble d'options de personnalisation dans un bundle à des fins de référence ultérieure. Notez que vous spécifiez un nom personnalisé comme une propriété personnalisée, en commençant par -- :

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

Avec --colorized comme alias pour les personnalisations, la dernière étape consiste à appliquer la palette à un élément qui utilise la famille de polices de couleur :

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

.spicy {
  font-family: "Bungee Spice";
  font-palette: --colorized;
}
Capture d&#39;écran de la police Bungee Spice avec le mot &quot;DUNE&quot;.
Police Bungee Spice affichée avec des couleurs personnalisées, source : https://developer.chrome.com/blog/colrv1-fonts/

Avec de plus en plus de polices variables et de polices en couleur disponibles, la typographie Web est sur une voie très prometteuse vers une personnalisation riche et une expression créative.

Ressources

Unités de la fenêtre d'affichage

Illustration montrant comment l&#39;écran de l&#39;appareil, la fenêtre du navigateur et un iframe ont tous des vues différentes.

Avant les nouvelles variantes de vue, le Web proposait des unités physiques pour faciliter l'ajustement des vues. Il y en avait une pour la hauteur, la largeur, la plus petite taille (vmin) et le plus grand côté (vmax). Ils fonctionnaient bien pour de nombreuses choses, mais les navigateurs mobiles ont introduit une complexité.

Sur mobile, lorsque vous chargez une page, la barre d'état avec l'URL s'affiche, et cette barre occupe une partie de l'espace de la fenêtre d'affichage. Après quelques secondes et une certaine interactivité, la barre d'état peut se retirer pour offrir une expérience de vue plus grande à l'utilisateur. Toutefois, lorsque cette barre glisse, la hauteur de la fenêtre d'affichage change, et toutes les unités vh se déplacent et se redimensionnent à mesure que leur taille cible change. Au fil des ans, l'unité vh a dû décider spécifiquement de la taille de la vue du navigateur qu'elle allait utiliser, car cela causait des problèmes de mise en page visuelle sur les appareils mobiles. Il a été déterminé que vh représente toujours la plus grande fenêtre d'affichage.

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

Après les nouvelles variantes de fenêtre d'affichage, des unités de fenêtre d'affichage petites, grandes et dynamiques sont disponibles, avec l'ajout d'équivalents logiques aux physiques. L'idée est de permettre aux développeurs et aux concepteurs de choisir l'unité qu'ils souhaitent utiliser pour leur scénario donné. Il est peut-être acceptable d'avoir un léger changement de mise en page lorsque la barre d'état disparaît. dvh (hauteur de la vue dynamique) peut donc être utilisé sans problème.

Illustration représentant trois téléphones pour illustrer les DVH, LVH et SVH. L&#39;exemple de téléphone DVH comporte deux lignes verticales, l&#39;une entre le bas de la barre de recherche et le bas de la fenêtre d&#39;affichage, et l&#39;autre entre le haut de la barre de recherche (sous la barre d&#39;état système) et le bas de la fenêtre d&#39;affichage. Elles montrent que le DVH peut être l&#39;une de ces deux longueurs. La LVH est affichée au milieu, avec une ligne entre le bas de la barre d&#39;état de l&#39;appareil et le bouton de la fenêtre d&#39;affichage du téléphone. Le dernier est l&#39;exemple d&#39;unité SVH, avec une ligne reliant le bas de la barre de recherche du navigateur au bas de la fenêtre d&#39;affichage.

Voici la liste complète de toutes les nouvelles options d'unités de fenêtre d'affichage disponibles avec les nouvelles variantes de fenêtre d'affichage:

Unités de hauteur de la fenêtre d'affichage
​​.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}
Unités de largeur de la fenêtre d'affichage
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}
Plus petites unités de fenêtre d'affichage latérales
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
Unités latérales de la fenêtre d'affichage les plus grandes
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

Nous espérons que ces éléments donneront aux développeurs et aux concepteurs la flexibilité nécessaire pour réaliser leurs conceptions responsives de vue d'ensemble.

Ressources

:has()

Navigateurs pris en charge

  • Chrome : 105
  • Edge : 105.
  • Firefox : 121.
  • Safari : 15.4.

Source

Avant :has(), le sujet d'un sélecteur était toujours à la fin. Par exemple, l'objet de ce sélecteur est un élément de liste: ul > li. Les pseudo-sélecteurs peuvent modifier le sélecteur, mais pas l'objet: ul > li:hover ou ul > li:not(.selected).

Après :has(), un sujet situé plus haut dans l'arborescence des éléments peut rester le sujet tout en fournissant une requête sur les enfants : ul:has(> li). Il est facile de comprendre comment :has() a obtenu le nom commun de "sélecteur parent", car l'objet du sélecteur est désormais le parent dans ce cas.

Voici un exemple de syntaxe de base où la classe .parent reste l'objet, mais n'est sélectionnée que si un élément enfant possède la classe .child :

.parent:has(.child) {...}

Voici un exemple où un élément <section> est l'objet, mais que le sélecteur ne correspond qu'à l'un des enfants avec :focus-visible :

section:has(*:focus-visible) {...}

Le sélecteur :has() commence à devenir un utilitaire fantastique une fois que des cas d'utilisation plus pratiques deviennent apparents. Par exemple, il n'est actuellement pas possible de sélectionner des balises <a> lorsqu'elles encapsulent des images, ce qui rend difficile d'apprendre à la balise d'ancrage à modifier ses styles dans ce cas d'utilisation. Il est toutefois possible de le faire avec :has() :

a:has(> img) {...}

Dans tous ces exemples, :has() ne ressemble qu'à un sélecteur parent. Considérez le cas d'utilisation des images à l'intérieur des éléments <figure> et ajustez les styles sur les images si la figure a un <figcaption>. Dans l'exemple suivant, nous sélectionnons des figures avec des légendes, puis des images dans ce contexte. :has() est utilisé et ne modifie pas le thème, car nous ciblons des images et non des chiffres:

figure:has(figcaption) img {...}

Les combinaisons semblent infinies. Combinez :has() avec des requêtes de quantité et ajustez les mises en page de grille CSS en fonction du nombre d'enfants. Combinez :has() avec des états de pseudo-classe interactifs et créez des applications qui répondent de manière créative.

La vérification de la compatibilité est simplifiée avec @supports et sa fonction selector(), qui vérifie si le navigateur comprend la syntaxe avant de l'utiliser :

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

Ressources

2022 et au-delà

Même après le déploiement de toutes ces fonctionnalités exceptionnelles en 2022, il restera encore de nombreuses choses difficiles à faire. La section suivante examine certains des problèmes restants et les solutions qui sont activement développées pour les résoudre. Ces solutions sont expérimentales, même si elles peuvent être spécifiées ou disponibles derrière des indicateurs dans les navigateurs.

Le résultat des sections suivantes devrait être de vous rassurer sur le fait que de nombreuses personnes de nombreuses entreprises cherchent à résoudre les problèmes listés, et non que ces solutions seront publiées en 2023.

Propriétés personnalisées à typage lâche

Navigateurs pris en charge

  • Chrome : 85.
  • Edge: 85
  • Firefox : 128.
  • Safari : 16.4.

Source

Les propriétés personnalisées CSS sont incroyables. Ils permettent de stocker toutes sortes de choses dans une variable nommée, qui peut ensuite être étendue, calculée, partagée, etc. En fait, ils sont tellement flexibles qu'il serait bien d'en avoir certains qui le sont moins.

Prenons l'exemple d'un box-shadow qui utilise des propriétés personnalisées pour ses valeurs :

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

Tout fonctionne correctement jusqu'à ce qu'une des propriétés soit remplacée par une valeur que le CSS n'accepte pas, comme --x: red. L'ombre entière est interrompue si l'une des variables imbriquées est manquante ou définie sur un type de valeur non valide.

C'est là que @property entre en jeu : --x peut devenir une propriété personnalisée typée, qui n'est plus souple et flexible, mais sécurisée avec des limites définies :

@property --x {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

Désormais, lorsque box-shadow utilise var(--x) et qu'une tentative de --x: red est effectuée par la suite, red est ignoré, car il ne s'agit pas d'un <length>. Cela signifie que l'ombre continue de fonctionner même si une valeur non valide a été attribuée à l'une de ses propriétés personnalisées. Au lieu d'échouer, elle revient à sa initial-value de 0px.

Animation

En plus de la sécurité des types, il ouvre également de nombreuses portes pour l'animation. La flexibilité de la syntaxe CSS rend l'animation de certains éléments impossible, comme les dégradés. @property est utile dans ce cas, car la propriété CSS typée peut informer le navigateur de l'intention d'un développeur dans le cadre d'une interpolation autrement trop complexe. Il limite essentiellement le champ des possibilités dans la mesure où un navigateur peut animer des aspects d'un style qu'il ne pouvait pas auparavant.

Prenons l'exemple de démonstration suivant, dans lequel un dégradé radial est utilisé pour créer une partie d'une superposition, créant ainsi un effet de mise au point clair. JavaScript définit les coordonnées X et Y de la souris lorsque la touche Alt/Opt est enfoncée, puis remplace la taille de mise au point par une valeur plus petite, par exemple 25 %, créant ainsi le cercle de mise au point du projecteur à la position de la souris :

Essayer la démonstration
.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );
}

Toutefois, les dégradés ne peuvent pas être animés. Ils sont trop flexibles et trop complexes pour que le navigateur puisse "déduire" simplement comment vous souhaitez les animer. Toutefois, avec @property, une propriété peut être saisie et animée de manière isolée, pour laquelle le navigateur peut facilement comprendre l'intention.

Les jeux vidéo qui utilisent cet effet de focus animent toujours le cercle, d'un grand cercle à un petit cercle. Voici comment utiliser @property avec notre démonstration afin que le navigateur anime le masque de dégradé:

@property --focal-size {
  syntax: '<length-percentage>';
  initial-value: 100%;
  inherits: false;
}

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );

  transition: --focal-size .3s ease;
}
Essayer la démonstration

Le navigateur peut désormais animer la taille du dégradé, car nous avons réduit la surface de la modification à une seule propriété et saisi la valeur afin que le navigateur puisse interpoler intelligemment les longueurs.

@property peut faire bien plus, mais ces petites activations peuvent faire toute la différence.

Ressources

S'est rendu à min-width ou max-width

Avant les plages de requêtes multimédias, une requête multimédia CSS utilise min-width et max-width pour articuler les conditions supérieures et inférieures. Cela peut se présenter comme suit :

@media (min-width: 320px) {
  
}

Après les plages de requêtes multimédias, la même requête multimédia peut se présenter comme suit :

@media (width >= 320px) {
  
}

Une requête média CSS utilisant à la fois min-width et max-width peut se présenter comme suit :

@media (min-width: 320px) and (max-width: 1280px) {
  
}

Une fois les plages de requêtes média, la même requête peut se présenter comme suit:

@media (320px <= width <= 1280px) {
  
}

En fonction de votre arrière-plan de codage, l'un d'eux semblera beaucoup plus lisible que l'autre. Grâce aux ajouts de spécifications, les développeurs pourront choisir celle qu'ils préfèrent ou même les utiliser de manière interchangeable.

Ressources

Aucune variable de requête média

Avant @custom-media, les requêtes multimédias devaient se répéter à plusieurs reprises ou s'appuyer sur des préprocesseurs pour générer la sortie appropriée en fonction de variables statiques au moment de la compilation.

Après @custom-media, CSS permet la création d'alias pour les requêtes média et leur référencement, comme pour une propriété personnalisée.

Nommer les éléments est très important : cela peut aligner l'objectif sur la syntaxe, ce qui facilite le partage et l'utilisation des éléments en équipe. Voici quelques requêtes multimédias personnalisées qui me suivent d'un projet à l'autre :

@custom-media --OSdark  (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);

@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse   (hover) and (pointer: fine);

@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);

Maintenant qu'ils sont définis, je peux utiliser l'un d'eux comme suit :

@media (--OSdark) {
  :root {
    
  }
}

Vous trouverez une liste complète des requêtes multimédias personnalisées que j'utilise dans ma bibliothèque de propriétés personnalisées CSS Open Props.

Ressources

L'imbrication des sélecteurs est très pratique

Avant @nest, les feuilles de style comportaient de nombreuses répétitions. Elle devenait particulièrement difficile à manier lorsque les sélecteurs étaient longs et que chacun ciblait de petites différences. La commodité de l'imbrication est l'une des raisons les plus courantes d'adopter un préprocesseur.

Après @nest, la répétition disparaît. Presque toutes les fonctionnalités de l'imbrication compatible avec le préprocesseur seront intégrées au CSS.

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

Pour moi, l'élément le plus important de l'imbrication, en plus de ne pas répéter article dans le sélecteur imbriqué, est que le contexte de stylisation reste dans un seul bloc de style. Au lieu de passer d'un sélecteur et de ses styles à un autre sélecteur avec des styles (exemple 1), le lecteur peut rester dans le contexte d'un article et voir les liens qui lui appartiennent. L'intent de relation et de style sont regroupés, de sorte que article semble posséder ses propres styles.

L'appropriation peut aussi être considérée comme une centralisation. Au lieu de rechercher des styles pertinents dans une feuille de style, vous pouvez les trouver tous imbriqués dans un contexte. Cela fonctionne avec les relations parent-enfant, mais aussi avec les relations enfant-parent.

Prenons l'exemple d'un composant enfant qui souhaite s'ajuster dans un contexte parent différent, au lieu que le parent soit propriétaire du style et modifie un enfant :

/* parent owns this, adjusting children */
section:focus-within > article {
  border: 1px solid hotpink;
}

/* with @nest becomes */

/* article owns this, adjusting itself when inside a section:focus-within */
article {
  @nest section:focus-within > & {
     border: 1px solid hotpink;
  }
}

@nest permet d'organiser, de centraliser et de gérer plus efficacement les styles. Les composants peuvent regrouper et posséder leurs propres styles, au lieu de les répartir entre d'autres blocs de style. Cela peut sembler anodin dans ces exemples, mais cela peut avoir des conséquences très importantes, à la fois pour la commodité et la lisibilité.

Ressources

Définir des styles de champ d'application est très difficile

Navigateurs pris en charge

  • Chrome : 118.
  • Edge : 118.
  • Firefox : derrière un indicateur.
  • Safari : 17.4.

Source

Avant @scope, de nombreuses stratégies existaient, car les styles CSS cascadent, héritent et ont une portée globale par défaut. Ces fonctionnalités du CSS sont très pratiques pour de nombreuses choses, mais pour les sites et applications complexes, avec potentiellement de nombreux styles de composants différents, l'espace global et la nature de la cascade peuvent donner l'impression que les styles fuient.

Après @scope, les styles ne peuvent pas seulement être limités à un contexte, comme une classe, mais ils peuvent également indiquer où les styles se terminent et ne continuent pas de se propager ou d'hériter.

Dans l'exemple suivant, le champ d'application de la convention de dénomination BEM peut être inversé dans l'intent réel. Le sélecteur BEM tente de limiter la couleur d'un élément header à un conteneur .card respectant des conventions de dénomination. Pour ce faire, l'en-tête doit comporter ce nom de classe, ce qui permet d'atteindre l'objectif. Avec @scope, aucune convention de dénomination n'est requise pour atteindre le même objectif sans balise l'élément d'en-tête :

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

Voici un autre exemple, moins spécifique au composant et plus axé sur la nature de portée globale du CSS. Les thèmes sombre et clair doivent coexister dans une feuille de style, où l'ordre est important pour déterminer le style gagnant. En général, cela signifie que les styles de thème sombre viennent après le thème clair. Le thème clair est donc défini comme style par défaut et le thème sombre comme style facultatif. Évitez les conflits d'ordre et de portée avec @scope :

​​@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

Pour compléter l'histoire, @scope permet également de déterminer où se termine le champ d'application du style. Cela ne peut pas être fait avec une convention de dénomination ni un préprocesseur. Il s'agit d'une fonctionnalité spéciale que seul le CSS intégré au navigateur peut effectuer. Dans l'exemple suivant, les styles img et .content sont appliqués exclusivement lorsqu'un enfant d'un .media-block est un frère ou un parent de .content :

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

Ressources

Aucune méthode CSS pour une mise en page en maçonnerie

Avant l'utilisation de maçonnerie CSS avec grille, JavaScript était le meilleur moyen d'obtenir une mise en page en maçonnerie, car les méthodes CSS avec colonnes ou flexbox ne représentaient pas l'ordre du contenu de manière inexacte.

Après la mise en page en maçonnerie CSS avec une grille, aucune bibliothèque JavaScript n'est requise et l'ordre des contenus est correct.

Capture d&#39;écran de la mise en page en maçonnerie qui montre des nombres qui se déplacent en haut, puis vers le bas.
Image et démonstration de Smashing Magazine
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

La démonstration précédente est réalisée avec le CSS suivant:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

Il est rassurant de savoir que cette stratégie de mise en page est considérée comme manquante. De plus, vous pouvez l'essayer dès aujourd'hui dans Firefox.

Ressources

Le CSS ne peut pas aider les utilisateurs à réduire la quantité de données

Navigateurs pris en charge

  • Chrome : derrière un drapeau.
  • Edge: derrière un drapeau.
  • Firefox : non compatible.
  • Safari : non compatible.

Source

Avant la requête média prefers-reduced-data, JavaScript et un serveur pouvaient modifier leur comportement en fonction de l'option "Économiseur de données" du système d'exploitation ou du navigateur d'un utilisateur, mais pas CSS.

Après la requête multimédia prefers-reduced-data, le CSS peut contribuer à améliorer l'expérience utilisateur et à économiser des données.

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

Le CSS précédent est utilisé dans ce composant de défilement multimédia, et les économies peuvent être énormes. Selon la taille de la fenêtre d'affichage du visiteur, vous pouvez réduire le temps de chargement de la page. L'enregistrement se poursuit lorsque les utilisateurs interagissent avec les défileurs multimédias. Les images comportent toutes des attributs loading="lazy", ce qui, combiné au CSS qui masque entièrement l'élément, signifie qu'aucune requête réseau n'est effectuée pour l'image.

Capture d&#39;écran d&#39;une interface de carrousel de séries TV avec de nombreuses miniatures et titres affichés.

Pour mes tests, sur une fenêtre d'affichage de taille moyenne, 40 requêtes et 700 Ko de ressources ont été chargés initialement. Lorsque l'utilisateur fait défiler la sélection de contenus multimédias, davantage de requêtes et de ressources sont chargées. Avec CSS et la requête média de données réduite, 10 requêtes et 172 Ko de ressources sont chargés. Cela représente un demi-mégaoctet d'économies et l'utilisateur n'a même fait défiler aucun des médias, auquel cas aucune requête supplémentaire n'est effectuée.

Capture d&#39;écran de l&#39;interface d&#39;un carrousel d&#39;émissions TV sans miniature et avec de nombreux titres affichés

Cette expérience de données réduites présente d'autres avantages que la simple économie de données. Plus de titres sont visibles et aucune image de couverture ne vient distraire l'attention. De nombreux utilisateurs naviguent en mode économie de données, car ils paient à la consommation. Il est vraiment agréable de voir que CSS peut les aider.

Ressources

Les fonctionnalités de glissement sont trop limitées

Avant ces propositions de recadrage par défilement, écrire votre propre code JavaScript pour gérer un carrousel, un curseur ou une galerie pouvait rapidement devenir complexe, avec tous les observateurs et la gestion de l'état. De plus, si vous n'y prenez pas garde, les vitesses de défilement naturelles peuvent être normalisées par script, ce qui peut rendre l'interaction utilisateur un peu moins naturelle et potentiellement maladroite.

Nouvelles API

snapChanging()

Dès que le navigateur a libéré un enfant de l'ancrage, cet événement se déclenche. Cela permet à l'UI de refléter l'absence d'enfant Snap et l'état d'ancrage indéterminé du conteneur de défilement, car il est désormais utilisé et atterrit sur un nouvel emplacement.

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()

Dès que le navigateur s'est calé sur un nouvel enfant et que la barre de défilement est à l'arrêt, cet événement se déclenche. Cela permet à toute interface utilisateur qui dépend de l'élément enfant ancré de mettre à jour et de refléter la connexion.

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
scroll-start

Le défilement ne commence pas toujours au début. Pensez à des composants balayables où le balayage vers la gauche ou la droite déclenche différents événements, ou à une barre de recherche qui, lors du chargement de la page, est initialement masquée jusqu'à ce que vous arriviez en haut. Cette propriété CSS permet aux développeurs de spécifier qu'un conteneur de défilement doit commencer à un point spécifique.

:root { --nav-height: 100px }

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
:snap-target

Ce sélecteur CSS correspond aux éléments d'un conteneur de recadrage de défilement actuellement recadrés par le navigateur.

.card {
  --shadow-distance: 5px;
  box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
  transition: box-shadow 350ms ease;
}

.card:snapped {
  --shadow-distance: 30px;
}

Après ces propositions de recadrage de défilement, la création d'un curseur, d'un carrousel ou d'une galerie est beaucoup plus facile, car le navigateur offre désormais des fonctionnalités pratiques pour cette tâche, en éliminant les observateurs et le code d'orchestration du défilement au profit de l'utilisation d'API intégrées.

Ces fonctionnalités CSS et JavaScript n'en sont qu'à leurs débuts, mais soyez à l'affût des polyfills qui pourront bientôt vous aider à les adopter et à les tester.

Ressources

Vélo entre des états connus

Avant toggle(), seuls les états intégrés au navigateur pouvaient déjà être exploités pour le style et les interactions. La saisie par case à cocher, par exemple, comporte :checked, un état de navigateur géré en interne pour l'entrée que le CSS peut utiliser pour modifier visuellement l'élément.

Après toggle(), des états personnalisés peuvent être créés sur n'importe quel élément pour que le CSS puisse les modifier et les utiliser pour le style. Il permet de créer des groupes, de faire défiler les éléments, d'activer/désactiver des éléments spécifiques, etc.

Dans l'exemple suivant, le même effet de barre de soulignement d'un élément de liste est obtenu, mais sans éléments de case à cocher :

<ul class='ingredients'>
   <li>1 banana
   <li>1 cup blueberries
  ...
</ul>

Et les styles CSS toggle() pertinents :

li {
  toggle-root: check self;
}

li:toggle(check) {
  text-decoration: line-through;
}

Si vous connaissez les machines à états, vous remarquerez peut-être le nombre de croisements avec toggle(). Cette fonctionnalité permettra aux développeurs de créer davantage de leur état dans le CSS, ce qui devrait permettre d'orchestrer l'interaction et l'état de manière plus claire et plus sémantique.

Ressources

Personnaliser certains éléments

Avant <selectmenu>, CSS ne permettait pas de personnaliser les éléments <option> avec du code HTML enrichi ni de modifier l'affichage d'une liste d'options. Cela a conduit les développeurs à charger des bibliothèques externes qui recréaient une grande partie des fonctionnalités d'un <select>, ce qui a fini par représenter beaucoup de travail.

Après <selectmenu>, les développeurs peuvent fournir du code HTML enrichi pour les éléments des options et les styliser autant qu'ils le souhaitent, tout en respectant les exigences d'accessibilité et en fournissant un code HTML sémantique.

Dans l'exemple suivant, tiré de la page d'explication de <selectmenu>, un nouveau menu de sélection est créé avec quelques options de base :

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

Le CSS peut cibler et styliser les parties de l'élément :

.my-select-menu::part(button) {
  color: white;
  background-color: red;
  padding: 5px;
  border-radius: 5px;
}

.my-select-menu::part(listbox) {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid red;
  border-radius: 5px;
}

Menu de sélection avec des couleurs d&#39;accentuation rouges.

Vous pouvez essayer l'élément <selectmenu> dans Chromium Canary avec le flag des tests Web activé. En 2023 et au-delà, vous découvrirez des éléments de menu personnalisables.

Ressources

Ancrer un élément à un autre

Avant anchor(), les positions absolue et relative étaient des stratégies de positionnement permettant aux développeurs de faire bouger les éléments enfants dans un élément parent.

Après anchor(), les développeurs peuvent positionner des éléments par rapport à d'autres éléments, qu'ils soient enfants ou non. Elle permet également aux développeurs de spécifier l'arête sur laquelle se positionner, et d'autres fonctionnalités pour créer des relations de position entre les éléments.

Si vous souhaitez en savoir plus, la vidéo explicative fournit quelques excellents exemples et exemples de code.

Ressources