Un style Web nouvelle génération

Découvrez certaines des fonctionnalités intéressantes des CSS modernes.

Une tonne de nouveautés passionnantes se déroulent en ce moment dans les CSS. et nombre d'entre eux sont déjà compatibles avec les navigateurs actuels ! Notre conférence au CDS 2019, que vous pouvez regarder ci-dessous, présente plusieurs fonctionnalités nouvelles et à venir qui, selon nous, devraient attirer votre attention.

Cet article porte sur les fonctionnalités que vous pouvez utiliser dès aujourd'hui, alors ne manquez pas de regarder la vidéo pour en savoir plus sur les fonctionnalités à venir, comme Houdini. Vous trouverez également des démonstrations de toutes les fonctionnalités dont nous avons parlé sur notre Page CSS@CDS

Sommaire

Défilement et ancrage

La fonctionnalité Scroll Snap vous permet de définir des points d'ancrage lorsque l'utilisateur fait défiler votre contenu verticalement, horizontalement ou les deux. Il offre une inertie et une décélération lors du défilement, et est compatible avec les commandes tactiles.

Cet exemple de code configure le défilement horizontal dans un élément <section> avec des points d'ancrage alignés sur le côté gauche des éléments <picture> enfants:

section {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
}

section > picture {
  scroll-snap-align: start;
}

Le principe est le suivant :

  • Dans l'élément parent <section>, <ph type="x-smartling-placeholder">
      </ph>
    • overflow-x est défini sur auto pour permettre le défilement horizontal.
    • overscroll-behavior-x est défini sur contain pour empêcher le défilement des éléments parents lorsque l'utilisateur atteint les limites de la zone de défilement de l'élément <section>. Ce n'est pas obligatoire pour l'ancrage, mais c'est généralement une bonne idée.
    • scroll-snap-type est défini sur x (pour l'ancrage horizontal) et sur mandatory (pour que la fenêtre d'affichage s'aligne toujours sur le point d'ancrage le plus proche).
  • Sur les éléments <picture> enfants, scroll-snap-align est défini sur "start" (début), ce qui définit les points d'ancrage sur le côté gauche de chaque image (en supposant que direction est défini sur ltr).

Voici une démonstration en direct:

<ph type="x-smartling-placeholder">

Vous pouvez également consulter les démonstrations pour l'accrochage du défilement vertical et l'ancrage du défilement matriciel.

:focus-within

:focus-within résout un problème d'accessibilité qui existe depuis longtemps: dans de nombreux cas, le choix d'un élément enfant doit affecter la présentation d'un élément parent afin que l'interface utilisateur soit accessible aux utilisateurs de technologies d'assistance.

Par exemple, si vous disposez d'un menu déroulant contenant plusieurs éléments, il doit rester visible tant que l'un des éléments est sélectionné. Sinon, le menu disparaît pour les utilisateurs de clavier.

:focus-within indique au navigateur d'appliquer un style lorsque le curseur est placé sur n'importe quel élément enfant d'un élément spécifié. Pour revenir à l'exemple de menu, en définissant :focus-within sur l'élément de menu, vous pouvez vous assurer qu'il reste visible lorsqu'un élément de menu est sélectionné:

.menu:focus-within {
  display: block;
  opacity: 1;
  visibility: visible;
}

Illustration montrant la différence de comportement entre la mise au point et la mise au point intérieure.

Essayez de parcourir les éléments sélectionnables dans la démo ci-dessous. Notez que les menus restent visibles lorsque vous sélectionnez les éléments de menu:

<ph type="x-smartling-placeholder">

Requêtes média, niveau 5

Les nouvelles requêtes média nous offrent des moyens efficaces d'ajuster l'expérience utilisateur de nos applications en fonction des préférences de l'appareil. En fait, le navigateur sert de proxy pour les préférences système auxquelles nous pouvons répondre dans notre CSS à l'aide du groupe de requêtes média prefers-*:

Schéma illustrant les requêtes multimédias qui interprètent les préférences utilisateur au niveau du système

Voici les nouvelles requêtes qui intéresseront le plus les développeurs:

Ces requêtes sont un énorme avantage pour l'accessibilité. Auparavant, nous n'avions aucun moyen de savoir, par exemple, qu'un utilisateur avait configuré son système d'exploitation sur le mode Contraste élevé. Si vous souhaitez proposer un mode Contraste élevé pour une application Web qui reste fidèle à votre marque, vous devez demander aux utilisateurs de le choisir dans l'UI de votre application. Vous pouvez désormais détecter le paramètre de contraste élevé du système d'exploitation à l'aide de prefers-contrast.

L'une des conséquences intéressantes de ces requêtes média est que nous pouvons concevoir pour plusieurs combinaisons de préférences utilisateur au niveau du système afin de répondre à l'ensemble des préférences utilisateur et des besoins d'accessibilité. Si un utilisateur souhaite obtenir un mode sombre à contraste élevé dans des environnements à faible luminosité, c'est possible !

Il est important pour Adam de "préférer les mouvements réduits" n'est pas implémentée comme « aucun mouvement ». L'utilisateur dit qu'il préfère moins de mouvement, pas qu'il ne veut pas d'animation. Il affirme que la réduction du mouvement n'est pas un mouvement. Voici un exemple qui utilise une animation de fondu enchaîné lorsque l'utilisateur préfère un mouvement réduit:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">.

Propriétés logiques

Les propriétés logiques résolvent un problème qui a gagné en visibilité à mesure que de plus en plus de développeurs s'attaquent à l'internationalisation. De nombreuses propriétés de mise en page, telles que margin et padding, supposent une langue qui se lit de haut en bas et de gauche à droite.

Schéma illustrant les propriétés de mise en page CSS traditionnelles.

Lors de la conception de pages pour plusieurs langages avec différents modes d'écriture, les développeurs ont dû ajuster toutes ces propriétés individuellement pour plusieurs éléments, ce qui devient rapidement un cauchemar en termes de gestion.

Les propriétés logiques vous permettent de maintenir l'intégrité de la mise en page dans tous les modes de traduction et d'écriture. Elles sont mises à jour de manière dynamique en fonction de l'ordre sémantique du contenu plutôt que de son agencement spatial. Avec des propriétés logiques, chaque élément a deux dimensions:

  • La dimension bloc est perpendiculaire au flux de texte sur une ligne. (En anglais, block-size correspond à height.)
  • La dimension intégrée est parallèle au flux de texte sur une ligne. (En anglais, inline-size correspond à width.)

Ces noms de dimensions s'appliquent à toutes les propriétés de mise en page logique. Ainsi, en anglais, block-start est identique à top, et inline-end équivaut à right.

Schéma illustrant les nouvelles propriétés de mise en page logique CSS.

Avec des propriétés logiques, vous pouvez mettre à jour automatiquement votre mise en page pour d'autres langues en modifiant simplement les propriétés writing-mode et direction de votre page au lieu de mettre à jour des dizaines de propriétés de mise en page pour des éléments individuels.

Vous pouvez observer le fonctionnement des propriétés logiques dans la démonstration ci-dessous en définissant la propriété writing-mode de l'élément <body> sur des valeurs différentes:

<ph type="x-smartling-placeholder">

position: sticky

Un élément avec position: sticky reste dans le flux de blocs jusqu'à ce qu'il commence à sortir de l'écran, Le défilement s'arrête alors avec le reste de la page. et conserve la position spécifiée par la valeur top de l'élément. L'espace alloué pour cet élément reste dans le flux, et l'élément y retourne lorsque l'utilisateur fait défiler la page vers le haut.

Le positionnement persistant vous permet de créer de nombreux effets utiles qui nécessitaient auparavant JavaScript. Pour illustrer certaines des possibilités, nous avons créé plusieurs démos. Chaque démo utilise en grande partie le même code CSS et n'ajuste que légèrement le balisage HTML pour créer chaque effet.

Pile persistante

Dans cette démonstration, tous les éléments fixes partagent le même conteneur. Cela signifie que chaque élément collant glisse sur l'élément précédent lorsque l'utilisateur fait défiler la page vers le bas. Les éléments collants partagent la même position bloquée.

Diapositive persistante

Ici, les éléments collants sont des cousins. (c'est-à-dire que leurs parents sont des frères et sœurs). Lorsqu'un élément collant atteint la limite inférieure de son conteneur, il se déplace avec celui-ci, ce qui donne l'impression que les éléments collants inférieurs se déplacent plus haut vers le haut. En d'autres termes, ils semblent entrer en concurrence pour la position bloquée.

Desperado collant

Tout comme les diapositives adhésives, les éléments persistants de cette démonstration sont des cousins. Toutefois, ils ont été placés dans des conteneurs définis sur une mise en page en grille à deux colonnes.

backdrop-filter

La propriété backdrop-filter vous permet d'appliquer des effets graphiques à la zone derrière un élément plutôt qu'à l'élément lui-même. Vous pouvez ainsi réaliser avec une seule ligne de code CSS de nombreux effets intéressants qui n'étaient auparavant réalisables qu'à l'aide de CSS et de scripts JavaScript complexes.

Par exemple, cette démonstration utilise backdrop-filter pour effectuer un floutage semblable à celui du système d'exploitation:

<ph type="x-smartling-placeholder">

Nous avons déjà publié un post formidable sur backdrop-filter. N'hésitez pas à consulter la page pour en savoir plus.

:is()

Bien que la pseudo-classe :is() date en réalité de plus de 10 ans, elle n'est pas aussi utilisée que nous le pensons. Elle utilise une liste de sélecteurs séparés par une virgule comme argument et correspond à tous les sélecteurs de cette liste. Cette flexibilité est incroyablement pratique et peut réduire considérablement la quantité de CSS que vous proposez.

Voici un exemple simple :

button.focus,
button:focus {
  
}

article > h1,
article > h2,
article > h3,
article > h4,
article > h5,
article > h6 {
  
}

/* selects the same elements as the code above */
button:is(.focus, :focus) {
  
}

article > :is(h1,h2,h3,h4,h5,h6) {
  
}

gap

La mise en page en grille CSS affiche gap (auparavant : grid-gap) depuis un certain temps. En spécifiant l'espacement interne d'un élément conteneur plutôt que l'espacement autour des éléments enfants, gap résout de nombreux problèmes de mise en page courants. Par exemple, avec un espace, vous n'avez pas à vous soucier des marges sur les éléments enfants, car elles risquent de provoquer des espaces blancs indésirables autour des bords d'un élément conteneur:

Illustration montrant comment la propriété &quot;gap&quot; évite les espaces indésirables autour des bords d&#39;un élément de conteneur.

Bonne nouvelle: gap arrive sur Flexbox et offre les mêmes avantages d'espacement que la grille:

  • Il n'y a qu'une seule déclaration d'espacement au lieu de plusieurs.
  • Il n'est pas nécessaire d'établir des conventions pour votre projet concernant les éléments enfants qui doivent disposer d'un espacement : l'élément contenant est propriétaire de l'espacement.
  • Ce code est plus facile à comprendre que d'anciennes stratégies, telles que la chouette lobotomisée.

La vidéo suivante présente les avantages de l'utilisation d'une seule propriété gap pour deux éléments, l'un avec une mise en page en grille et l'autre avec une mise en page flexible:

Pour le moment, seul FireFox accepte gap dans les mises en page Flex, mais essayez cette démo pour en comprendre le fonctionnement:

<ph type="x-smartling-placeholder">

CSS Houdini

Houdini est un ensemble d'API de bas niveau destinées au moteur de rendu du navigateur, qui vous permet d'indiquer au navigateur comment interpréter le code CSS personnalisé. En d'autres termes, il vous donne accès au modèle d'objet CSS, ce qui vous permet d'étendre le CSS via JavaScript. Cela présente plusieurs avantages :

  • Il vous permet de créer beaucoup plus de fonctionnalités CSS personnalisées.
  • Il est plus facile de séparer les problèmes de rendu de la logique d'application.
  • Il est plus performant que le polyfilling CSS que nous effectuons actuellement avec JavaScript, car le navigateur n'aura plus à analyser les scripts ni à effectuer un second cycle de rendu. Le code Houdini est analysé lors du premier cycle de rendu.

Illustration montrant le fonctionnement de Houdini par rapport aux polyfills JavaScript traditionnels.

Houdini est un nom générique pour plusieurs API. Pour en savoir plus à leur sujet et leur état actuel, accédez à la page Is Houdini Ready Yet? (Est-ce que Houdini est prêt pour l'instant ?) Lors de notre discussion, nous avons abordé l'API Properties and Values, l'API Paint et le Worklet d'animation, car ce sont actuellement les plus compatibles. Nous pourrions facilement dédier un post complet à chacune de ces API intéressantes. Pour le moment, nous vous invitons à lire notre présentation pour obtenir une présentation et des démonstrations intéressantes qui vous donneront une idée de ce que vous pouvez faire avec les API.

Dépassement

Il nous reste encore quelques points à aborder, mais nous n'avons pas eu le temps de les aborder plus en détail.⚡ Si vous n'avez pas encore entendu parler de certaines de ces fonctionnalités, regardez la dernière partie de la vidéo !

  • size: propriété qui vous permet de définir la hauteur et la largeur en même temps
  • aspect-ratio: propriété qui définit un format pour les éléments qui n'en ont pas intrinsèquement.
  • min(), max() et clamp(): fonctions qui vous permettent de définir des contraintes numériques sur n'importe quelle propriété CSS, et pas seulement sur la largeur et la hauteur.
  • list-style-type est une propriété existante, mais elle acceptera bientôt une plus grande plage de valeurs, y compris les emoji et les SVG.
  • display: outer inner: la propriété display acceptera bientôt deux paramètres, qui vous permettront de spécifier explicitement ses mises en page externe et interne au lieu d'utiliser des mots clés composés comme inline-flex.
  • Régions CSS: elles vous permettent de remplir une zone non rectangulaire spécifiée qui peut entrer et sortir du contenu.
  • Modules CSS: JavaScript peut demander un module CSS et récupérer un objet enrichi sur lequel il est facile d'effectuer des opérations.