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 :
- Positionnement
sticky
- Taille
aspect-ratio
- Mise en page
flex
- Mise en page
grid
- 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:
@layer
- Espaces colorimétriques et fonctions
- Confinement
<dialog>
- Compatibilité des formulaires
- Défilement
- Sous-grille
- Typographie
- Unités de la fenêtre d'affichage
- 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
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 :
Ressources
- Spécifications CSS Cascade 5
- Explication des couches en cascade
- Couches en cascade sur MDN
- Una Kravets : Cascade Layers
- Ahmad Shadeed: Bonjour, les couches CSS Cascade
Sous-grille
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.
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.
Ressources
- Spécifications de la sous-grille
- Subgrid sur MDN
- Bramus: tutoriels vidéo pratiques sur la sous-grille CSS
Requêtes de conteneur
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.
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é :
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
- Spécification des requêtes de conteneur
- Explication des requêtes de conteneur
- Requêtes de conteneur sur MDN
- Nouveau responsive sur web.dev
- Démonstration d'Agenda par Una
- Superbe collection de requêtes de conteneurs
- Comment nous avons créé Designcember sur web.dev
- Ahmad Shaded : Say Hello To CSS Container Queries
accent-color
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;
}
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
- spécifications de couleur d'accentuation
- accent-color sur MDN
- accent-color sur web.dev
- Bramus : Tint User-Interface Controls with CSS accent-color
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()
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
- Spécification de la technologie UWB
- HWB sur MDN
- Stefan Judis: hwb() – une notation de couleur pour les humains ?
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()
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
- Spécification color-mix()
- color-mix() sur MDN
- Démonstration de la thématisation
- Autre démonstration de thématisation
- Fabio Giolito : Créer un thème de couleurs avec ces fonctionnalités CSS à venir
color-contrast()
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.
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 :
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
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é :
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);
}
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
- Spécification de la syntaxe des couleurs relatives
- Créer des palettes de couleurs avec une syntaxe de couleurs relative
- Créer des variantes de couleur avec la syntaxe de couleur relative
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.
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.
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.
Pour en savoir plus, consultez ce fil Twitter.
Ressources
- Spécification de l'interpolation de dégradé
- Démo comparant les dégradés dans les espaces
- Notebook Observable comparant des dégradés
inert
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:
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.
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;
}
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
- Spécification Colrv1 sur GitHub
- Développeurs Chrome : polices Colrv1
- Vidéo d'explication pour les développeurs sur BlinkOn
Unités de la fenêtre d'affichage
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.
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:
.new-height-viewport-units { height: 100vh; height: 100dvh; height: 100svh; height: 100lvh; block-size: 100vb; block-size: 100dvb; block-size: 100svb; block-size: 100lvb; }
.new-width-viewport-units { width: 100vw; width: 100dvw; width: 100svw; width: 100lvw; inline-size: 100vi; inline-size: 100dvi; inline-size: 100svi; inline-size: 100lvi; }
.new-min-viewport-units { --size: 100vmin; --size: 100dvmin; --size: 100svmin; --size: 100lvmin; }
.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
- Spécification des unités relatives au viewport
- Bramus : Vues d'ensemble grandes, petites et dynamiques
:has()
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
- Spécification de :has()
- :has() sur le MDN
- Le sélecteur CSS
:has()
est bien plus qu'un "sélecteur parent"
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
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 :
.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;
}
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
- @property specification
- @propriété sur MDN
- @property sur web.dev
- Démonstration du focus avec zoom
- Astuces CSS: découvrir @property et ses pouvoirs d'animation
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
- Spécification de la syntaxe de la plage de requêtes multimédias
- Syntaxe de la plage de requêtes média sur MN
- Plug-in PostCSS de syntaxe de plage de requêtes multimédias
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
- Spécification des requêtes média personnalisées
- Plug-in PostCSS pour les requêtes multimédias personnalisées
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
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.
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
- Spécifications de la mise en page en maçonnerie
- Mise en page en maçonnerie sur MN
- Smashing Magazine: mise en page maçonnerie CSS native avec grille CSS
Le CSS ne peut pas aider les utilisateurs à réduire la quantité de données
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.
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.
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
- spécification prefers-reduced-data
- prefers-reduced-data sur le Réseau Display de Google
- Défi sur prefers-reduced-data dans une IUG
- Smashing Magazine : Improving Core Web Vitals, A Smashing Magazine Case Study
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
- Spécification provisoire de Scroll Snap 2
- Explications sur le défilement de la fenêtre
- Démonstrations de Snap
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;
}
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.