Fermer

avril 23, 2021

Guide des sélecteurs de pseudoclasses CSS modernes et nouvellement pris en charge


À propos de l'auteur

Stephanie Eckles est une SWE front-end chez Microsoft. Elle est également l'auteur de ModernCSS.dev qui fournit des solutions modernes aux anciens problèmes CSS comme en profondeur…
En savoir plus sur
Stéphanie

Le brouillon de l'éditeur du groupe de travail CSS pour les sélecteurs de niveau 4 comprend plusieurs sélecteurs de pseudo-classes qui ont déjà des candidats de proposition dans la plupart des navigateurs modernes. Ce guide couvrira ceux qui ont actuellement le meilleur support avec des exemples pour montrer comment vous pouvez commencer à les utiliser aujourd'hui!

Les sélecteurs de pseudo-classes sont ceux qui commencent par le caractère deux-points ": " et correspondance basée sur un état de l'élément courant. L'état peut être relatif à l'arborescence du document, ou en réponse à un changement d'état tel que : hover ou : checked .

: focus-visible

Je parie que l'une des violations d'accessibilité les plus courantes sur le Web consiste à supprimer le contour des éléments interactifs tels que les liens, les boutons et les entrées de formulaire pour leur : état de mise au point . L'un des principaux objectifs de ce plan est de servir d'indicateur visuel pour les utilisateurs qui utilisent principalement des claviers pour naviguer. Un état de mise au point visible est essentiel en tant qu'outil d'orientation, car ces utilisateurs naviguent sur une interface et aident à renforcer ce qui est un élément interactif. Plus précisément, la mise au point visible est couverte dans le critère de succès WCAG 2.4.11: Apparence de la mise au point (minimum) .

La pseudo-classe : focus-visible est destinée à afficher uniquement un anneau de mise au point lorsque l'agent utilisateur détermine via heuristique qu'il doit être visible. En d'autres termes: les navigateurs détermineront quand appliquer : focus-visible en fonction de choses comme la méthode d'entrée, le type d'élément et le contexte de l'interaction. À des fins de test via un ordinateur de bureau avec entrée clavier et souris, vous devriez voir : styles focus-visible attachés lorsque vous tabulez dans un élément interactif mais pas lorsque vous cliquez dessus, à l'exception des entrées de texte et des zones de texte qui devrait afficher : focus-visible pour tous les types d'entrée de mise au point.

Note : Pour plus de détails, consultez le brouillon de travail du : focus-visible spec .

Les dernières versions des navigateurs Firefox et Chromium semblent désormais gérer : focus-visible sur les entrées de formulaire selon la spécification qui dit que l'UA doit supprimer les styles : focus lorsque : focus-visible correspond. Safari ne prend pas encore en charge : focus-visible nous devons donc nous assurer qu'un style : focus est inclus comme solution de secours pour éviter de supprimer le contour pour l'accessibilité. [19659014] Étant donné un bouton et une saisie de texte avec l'ensemble de styles suivant, voyons ce qui se passe:

 input: focus,
bouton: focus {
  contour: 2px bleu uni;
  contour-offset: 0,25em;
}

input: focus-visible {
  contour: 2px solide transparent;
  couleur de la bordure: bleu;
}

bouton: focus: not (: focus-visible) {
  contour: aucun;
}

bouton: focus-visible {
  contour: 2px solide transparent;
  boîte-ombre: 0 0 0 2px #fff, 0 0 0 4px bleu;
}

Entrée Chromium et Firefox


  • Supprimez correctement les styles : focus lorsque les éléments sont focalisés via l'entrée souris en faveur de : focus-visible résultant en un changement de ] border-color et masquer le contour lors de la saisie au clavier Bouton

  • N'utilise pas seulement : focus-visible sans la règle supplémentaire pour le bouton : focus: not (: focus-visible) qui supprime le contour sur : focus mais permettra la visibilité de la box-shadow uniquement sur une entrée au clavier

Safari

  • input
    Continue d'utiliser uniquement le bouton : focus styles
  • Ce semble maintenant respecter partiellement l'intention de : focus-visible sur le bouton en masquant les styles : focus au clic, mais affichant toujours les styles : focus sur le clavier interacti on

Donc pour l'instant, la recommandation serait de continuer à inclure les styles : focus et ensuite de les améliorer progressivement jusqu'à utiliser : focus-visible ce que le code de démonstration permet. Voici un CodePen pour que vous puissiez continuer à tester avec:

See the Pen [Testing application of :focus-visible] (https://codepen.io/smashingmag/pen/MWJZbew) par Stephanie Eckles .

See the Pen Test de l'application de: focus-visible par Stephanie Eckles .

: focus-within

The : focus-within pseudo-classe a un support parmi tous les navigateurs modernes, et agit presque comme un sélecteur parent, mais seulement pour une condition très spécifique. Lorsqu'il est attaché à un élément conteneur et qu'un élément enfant correspond à : focus des styles peuvent être ajoutés à l'élément conteneur et / ou tout autre élément dans le conteneur.

L'amélioration pour utiliser ce comportement consiste à styliser une étiquette de formulaire lorsque l'entrée associée a le focus. Pour que cela fonctionne, nous emballons l'étiquette et l'entrée dans un conteneur, puis attachons : focus-within à ce conteneur et sélectionnons l'étiquette:

 .form-group: focus-within label {
  Couleur bleue;
}

L'étiquette devient alors bleue lorsque l'entrée a le focus.

Cette démo CodePen inclut également l'ajout d'un contour directement au conteneur .form-group :

See the Pen [Testing application of :focus-within] (https://codepen.io/smashingmag/pen/xxgmREq) par Stephanie Eckles .

See the Pen Test de l'application de: focus-within par Stephanie Eckles .

: is ()

Aussi connu sous le nom de pseudo-classe «correspond à tout», : is () peut prendre une liste de sélecteurs pour essayer de faire correspondre contre. Par exemple, au lieu de lister les styles de titre individuellement, vous pouvez les regrouper sous le sélecteur de : is (h1, h2, h3) .

Quelques comportements uniques concernant le : is ( ) liste de sélecteurs:

  • Si un sélecteur répertorié n'est pas valide, la règle continuera à correspondre aux sélecteurs valides. Étant donné : is (-ua-invalid, article, p) la règle correspondra à article et p .
  • La spécificité calculée sera égale à celle du passé le sélecteur avec la spécificité la plus élevée. Par exemple, : is (#id, p) aura la spécificité de #id - 1.0.0 - alors que : is (p, a) aura une spécificité de 0.0.1.

Le premier comportement consistant à ignorer les sélecteurs invalides est un avantage clé. Lors de l'utilisation d'autres sélecteurs dans un groupe où un sélecteur est invalide, le navigateur rejettera la règle entière. Cela entre en jeu dans quelques cas où les préfixes de fournisseur sont encore nécessaires, et le regroupement de sélecteurs avec préfixe et sans préfixe entraîne l'échec de la règle parmi tous les navigateurs. Avec : is () vous pouvez regrouper ces styles en toute sécurité et ils s'appliqueront lorsqu'ils correspondent et seront ignorés lorsqu'ils ne le seront pas.

Pour moi, regroupant les styles de titres comme précédemment mentionné est déjà une grande victoire avec ce sélecteur. C'est aussi le type de règle que je me sentirais à l'aise d'utiliser sans solution de secours lors de l'application de styles non critiques, tels que:

: is (h1, h2, h3) {
  hauteur de ligne: 1,2;
}

: is (h2, h3): not (: first-child) {
  margin-top: 2em;
}

Dans cet exemple (qui provient de les styles de document de mon projet SmolCSS ), ayant la plus grande hauteur de ligne héritée des styles de base ou sans le margin-top n'est pas vraiment un problème pour les navigateurs non compatibles. C’est tout simplement loin d’être idéal. Ce que vous ne voudriez pas encore utiliser : is () serait styles de mise en page critiques tels que Grid ou Flex qui contrôlent considérablement votre interface.

De plus, lorsqu'ils sont enchaînés vers un autre sélecteur, vous pouvez tester si le sélecteur de base correspond à un sélecteur descendant dans : is () . Par exemple, la règle suivante sélectionne uniquement les paragraphes qui sont des descendants directs d'articles. Le sélecteur universel est utilisé comme référence au sélecteur de base p .

 p: is (article> *)

Pour le meilleur support actuel si vous souhaitez commencer à l'utiliser, vous voudrez également doubler les styles en incluant les règles de duplication en utilisant : -webkit-any () et : correspond () . N'oubliez pas de faire ces règles individuelles, ou même le navigateur de support les rejettera! En d'autres termes, incluez tous les éléments suivants:

: matches (h1, h2, h3) {}

: -webkit-any (h1, h2, h3) {}

: est (h1, h2, h3) {}

Il convient de mentionner à ce stade que, avec les nouveaux sélecteurs eux-mêmes, une version mise à jour de @supports qui est @supports selector . Ceci est également disponible sous @supports not selector .

Note : À l'heure actuelle (parmi les navigateurs modernes), seul Safari ne prend pas en charge cette règle.

Vous pouvez vérifier le support de : is () avec quelque chose comme ce qui suit, mais vous perdriez en fait le support de Safari puisque Safari prend en charge : is () mais ne prend pas en charge @supports selector .

 @supports selector (: is (h1)) {
  : est (h1, h2, h3) {
    hauteur de ligne: 1,1;
  }
}

: where ()

La pseudo-classe : where () est presque identique à : is () sauf pour une différence critique: elle ont toujours une spécificité nulle. Cela a des implications incroyables pour les gens qui construisent des cadres, des thèmes et des systèmes de conception . En utilisant : where () un auteur peut définir des valeurs par défaut et les développeurs en aval peuvent inclure des remplacements ou des extensions sans conflit de spécificité.

Considérez l'ensemble suivant de styles img . En utilisant : où () même avec un sélecteur de spécificité plus élevé, la spécificité reste nulle. Dans l'exemple suivant, quelle couleur de bordure pensez-vous que l'image aura?

: where (article img: not (: first-child)) {
    bordure: 5px rouge uni;
}

: où (article) img {
  bordure: 5px vert uni;
}

img {
  bordure: 5px orange uni;
}

La première règle a une spécificité nulle puisqu'elle est entièrement contenue dans : where () . Donc, directement contre la deuxième règle, la deuxième règle l'emporte. En introduisant le sélecteur d'élément uniquement img comme dernière règle, il va gagner en raison de la cascade. En effet, il calculera selon la même spécificité que la règle : where (article) img puisque la partie : where () n'augmente pas la spécificité.

Utilisation de : where () à côté des fallbacks est un peu plus difficile en raison de la fonctionnalité de spécificité zéro puisque cette fonctionnalité est probablement la raison pour laquelle vous voudriez l'utiliser dessus : is () . Et si vous ajoutez des règles de repli, celles-ci sont susceptibles de battre : where () en raison de sa nature même. Et, il a un meilleur support global que le sélecteur @supports donc essayer de l'utiliser pour créer une solution de secours n'est pas susceptible de fournir beaucoup (le cas échéant) de gain. Fondamentalement, soyez conscient de l'incapacité de créer correctement des solutions de secours pour : where () et vérifiez soigneusement vos propres données pour déterminer s'il est sûr de commencer à utiliser pour votre public unique.

Vous pouvez tester davantage ]: où () avec le CodePen suivant qui utilise les sélecteurs img ci-dessus:

See the Pen [Testing `:where()` specificity] (https://codepen.io/smashingmag/pen/jOyXVMg) par Stephanie Eckles .

See the Pen Testing : where () specificity by Stephanie Eckles .

Enhanced ]: not ()

Le sélecteur de base : not () est pris en charge depuis Internet Explorer 9. Mais Selectors Level 4 améliore : not () en l'autorisant pour prendre une liste de sélection, tout comme : is () et : where () .

Les règles suivantes fournissent le même résultat dans les navigateurs pris en charge:

 articl e: pas (h2): pas (h3): pas (h4) {
  marge inférieure: 1,5em;
}

article: pas (h2, h3, h4) {
  marge inférieure: 1,5em;
}

La capacité de : not () d'accepter une liste de sélecteurs est très compatible avec les navigateurs modernes .

Comme nous l'avons vu avec : is () , amélioré : not () peut également contenir une référence au sélecteur de base en tant que descendant en utilisant * . Ce CodePen démontre cette capacité en sélectionnant des liens qui sont et non descendants de nav .

See the Pen [Testing :not() with a descendent selector] (https://codepen.io/smashingmag/pen/BapvQQv ) de Stephanie Eckles .

See the Pen Testing: not () with a descendent selector by Stephanie Eckles .

Bonus : La démo précédente comprend également un exemple de chaînage : not () and : is () pour sélectionner des images qui ne sont pas des frères et sœurs adjacents de h2 ou h3 éléments.

Proposé mais «à risque» - : has ()

La pseudo-classe finale qui est une proposition très excitante mais qui n'a pas de navigateur actuel l'implémentant même dans une manière expérimentale est : has () . En fait, il est répertorié dans le Selector Level 4 Editor's Draft comme «à risque», ce qui signifie qu'il est reconnu pour avoir des difficultés à terminer sa mise en œuvre et qu'il peut être abandonné

S'il était mis en œuvre, : has () serait essentiellement le «parent sélecteur» que de nombreux CSS ont souhaité avoir à disposition. Cela fonctionnerait avec une logique similaire à une combinaison des deux : focus-within et : is () with descendent selectors, où vous recherchez la présence de descendants ] mais le style appliqué serait à l'élément parent.

Etant donné la règle suivante, si la navigation contenait un bouton, alors la navigation aurait diminué le remplissage en haut et en bas:

 nav {
  rembourrage: 0,75rem 0,25rem;

nav: has (bouton) {
  rembourrage supérieur: 0,25rem;
  rembourrage bas: 0,25rem;
}

Encore une fois, ce n'est pas actuellement implémenté dans n'importe quel navigateur, même expérimentalement - mais c'est amusant d'y penser! Robin Rendle a fourni des informations supplémentaires sur ce futur sélecteur sur CSS-Tricks.

Mention honorable du niveau 3: : vide

Une pseudo-classe utile que vous avez peut-être manquée à partir des sélecteurs de niveau 3 est : vide qui correspond à un élément lorsqu'il n'a aucun éléments enfants, y compris les nœuds de texte.

La règle p: vide correspondra

mais pas

Bonjour

.

Une façon d'utiliser : empty consiste à masquer les éléments qui sont peut-être des espaces réservés pour du contenu dynamique rempli de JavaScript. Peut-être avez-vous un div qui recevra les résultats de la recherche, et quand il sera rempli, il aura une bordure et un peu de remplissage. Mais sans aucun résultat, vous ne voulez pas qu'il prenne de la place sur la page. En utilisant : empty vous pouvez le masquer avec:

 .search-results: empty {
  affichage: aucun;
}

Vous pensez peut-être ajouter un message à l'état vide et être tenté de l'ajouter avec un pseudo-élément et un contenu . Le piège ici est que les messages peuvent ne pas être disponibles pour les utilisateurs de technologies d'assistance qui ne sont pas cohérents quant à savoir s'ils peuvent accéder au contenu . En d'autres termes, pour vous assurer qu'un message de type «aucun résultat» est accessible vous voudriez ajouter que comme élément réel comme un paragraphe (un aria-label ne le ferait pas)

Ressources pour apprendre les sélecteurs

CSS a beaucoup plus de sélecteurs incluant des pseudo-classes. Voici quelques autres endroits pour en savoir plus sur ce qui est disponible:

 Smashing Editorial "width =" 35 "height =" 46 "loading =" lazy "decoding =" async (vf, il)




Source link