Français

Explorez le sélecteur CSS :has(), un élément déterminant pour la sélection parentale. Découvrez les applications pratiques, la compatibilité entre navigateurs et les techniques avancées pour révolutionner votre style CSS.

Maîtriser le sélecteur CSS :has() : Libérer la puissance de la sélection parentale

Pendant des années, les développeurs CSS ont aspiré à un moyen simple et efficace de sélectionner les éléments parents en fonction de leurs enfants. L'attente est terminée ! La pseudo-classe :has() est enfin là, et elle révolutionne la façon dont nous écrivons le CSS. Ce sélecteur puissant vous permet de cibler un élément parent s'il contient un élément enfant spécifique, ouvrant ainsi un monde de possibilités pour un style dynamique et responsive.

Qu'est-ce que le sélecteur :has() ?

La pseudo-classe :has() est une pseudo-classe relationnelle CSS qui accepte une liste de sélecteurs comme argument. Elle sélectionne un élément si l'un des sélecteurs de la liste de sélecteurs correspond à au moins un élément parmi les descendants de l'élément. En termes plus simples, elle vérifie si un élément parent a un enfant spécifique, et si c'est le cas, le parent est sélectionné.

La syntaxe de base est :

parent:has(child) { /* Règles CSS */ }

Cela sélectionne l'élément parent uniquement s'il contient au moins un élément child.

Pourquoi :has() est-il si important ?

Traditionnellement, le CSS a été limité dans sa capacité à sélectionner les éléments parents en fonction de leurs enfants. Cette limitation nécessitait souvent des solutions JavaScript complexes ou des solutions de contournement pour obtenir un style dynamique. Le sélecteur :has() élimine le besoin de ces méthodes encombrantes, permettant un code CSS plus propre, plus maintenable et plus performant.

Voici pourquoi :has() change la donne :

Exemples de base du sélecteur :has()

Commençons par quelques exemples simples pour illustrer la puissance du sélecteur :has().

Exemple 1 : Styliser un div parent en fonction de la présence d'une image

Supposons que vous souhaitiez ajouter une bordure à un élément <div> uniquement s'il contient un élément <img> :

div:has(img) { border: 2px solid blue; }

Cette règle CSS appliquera une bordure bleue à tout <div> qui contient au moins un élément <img>.

Exemple 2 : Styliser un élément de liste en fonction de la présence d'un span

Disons que vous avez une liste d'éléments et que vous souhaitez mettre en évidence l'élément de liste s'il contient un élément <span> avec une classe spécifique :

li:has(span.highlight) { background-color: yellow; }

Cette règle CSS changera la couleur de fond de tout <li> qui contient un <span> avec la classe "highlight" en jaune.

Exemple 3 : Styliser une étiquette de formulaire en fonction de la validité de l'entrée

Vous pouvez utiliser :has() pour styliser une étiquette de formulaire en fonction de si son champ d'entrée associé est valide ou non valide (combiné avec la pseudo-classe :invalid) :

label:has(+ input:invalid) { color: red; font-weight: bold; }

Cela rendra l'étiquette rouge et en gras si le champ d'entrée qui la suit immédiatement est invalide.

Utilisations avancées du sélecteur :has()

Le sélecteur :has() devient encore plus puissant lorsqu'il est combiné avec d'autres sélecteurs et pseudo-classes CSS. Voici quelques cas d'utilisation avancés :

Exemple 4 : Cibler les éléments vides

Vous pouvez utiliser la pseudo-classe :not() conjointement avec :has() pour cibler les éléments qui *n'ont pas* d'enfant spécifique. Par exemple, pour styliser les divs qui *ne* contiennent pas d'images :

div:not(:has(img)) { background-color: #f0f0f0; }

Cela appliquera un arrière-plan gris clair à tout <div> qui ne contient pas d'élément <img>.

Exemple 5 : Création de mises en page complexes

Le sélecteur :has() peut être utilisé pour créer des mises en page dynamiques basées sur le contenu d'un conteneur. Par exemple, vous pouvez modifier la mise en page d'une grille en fonction de la présence d'un type spécifique d'élément dans une cellule de grille.

.grid-container { display: grid; grid-template-columns: repeat(3, 1fr); } .grid-item:has(img) { grid-column: span 2; }

Cela fera en sorte qu'un élément de grille s'étende sur deux colonnes s'il contient une image.

Exemple 6 : Style de formulaire dynamique

Vous pouvez utiliser :has() pour styliser dynamiquement les éléments de formulaire en fonction de leur état (par exemple, s'ils sont ciblés, remplis ou valides).

.form-group:has(input:focus) { box-shadow: 0 0 5px rgba(0, 0, 255, 0.5); } .form-group:has(input:valid) { border-color: green; } .form-group:has(input:invalid) { border-color: red; }

Cela ajoutera une ombre de boîte bleue lorsque l'entrée est ciblée, une bordure verte si l'entrée est valide et une bordure rouge si l'entrée est invalide.

Exemple 7 : Styliser en fonction du nombre d'enfants

Bien que :has() ne compte pas directement le nombre d'enfants, vous pouvez le combiner avec d'autres sélecteurs et propriétés CSS pour obtenir des effets similaires. Par exemple, vous pouvez utiliser :only-child pour styliser un parent s'il n'a qu'un seul enfant d'un type spécifique.

div:has(> p:only-child) { background-color: lightgreen; }

Cela stylisera un <div> avec un arrière-plan vert clair uniquement s'il contient un seul élément <p> comme enfant direct.

Compatibilité entre navigateurs et solutions de repli

Fin 2023, le sélecteur :has() bénéficie d'une excellente prise en charge dans les navigateurs modernes, notamment Chrome, Firefox, Safari et Edge. Cependant, il est essentiel de vérifier la compatibilité sur Can I use avant de le déployer en production, surtout si vous devez prendre en charge les anciens navigateurs.

Voici une ventilation des considérations de compatibilité :

Fournir des solutions de repli

Si vous devez prendre en charge les anciens navigateurs, vous devrez fournir des solutions de repli. Voici quelques stratégies :

Voici un exemple d'utilisation d'une requête de fonctionnalité :

.parent { /* Style de base pour tous les navigateurs */ border: 1px solid black; } @supports selector(:has(img)) { .parent:has(img) { /* Style amélioré pour les navigateurs qui prennent en charge :has() */ border: 3px solid blue; } }

Ce code appliquera une bordure noire à l'élément .parent dans tous les navigateurs. Dans les navigateurs qui prennent en charge :has(), il appliquera une bordure bleue si l'élément .parent contient une image.

Considérations de performance

Bien que :has() offre des avantages significatifs, il est essentiel de tenir compte de son impact potentiel sur les performances, en particulier lorsqu'il est utilisé de manière extensive ou avec des sélecteurs complexes. Les navigateurs doivent évaluer le sélecteur pour chaque élément de la page, ce qui peut devenir coûteux en termes de calcul.

Voici quelques conseils pour optimiser les performances de :has() :

Erreurs courantes à éviter

Lorsque vous travaillez avec le sélecteur :has(), il est facile de faire des erreurs qui peuvent entraîner des résultats inattendus. Voici quelques pièges courants à éviter :

Meilleures pratiques pour l'utilisation de :has()

Pour maximiser les avantages du sélecteur :has() et éviter les problèmes potentiels, suivez ces meilleures pratiques :

Exemples concrets et cas d'utilisation

Explorons quelques exemples concrets de la façon dont le sélecteur :has() peut être utilisé pour résoudre des problèmes de conception courants.

Exemple 8 : Création de menus de navigation responsives

Vous pouvez utiliser :has() pour créer des menus de navigation responsives qui s'adaptent à différentes tailles d'écran en fonction de la présence d'éléments de menu spécifiques.

Imaginez un scénario où vous souhaitez afficher un menu de navigation différent selon que l'utilisateur est connecté ou non. S'il est connecté, vous pouvez afficher les actions de profil et de déconnexion, sinon vous pouvez afficher la connexion/l'inscription.

nav:has(.user-profile) { /* Styles pour les utilisateurs connectés */ } nav:not(:has(.user-profile)) { /* Styles pour les utilisateurs déconnectés */ }

Exemple 9 : Styliser les composants de carte

Le sélecteur :has() peut être utilisé pour styliser les composants de carte en fonction de leur contenu. Par exemple, vous pouvez ajouter une ombre à une carte uniquement si elle contient une image.

.card:has(img) { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); }

Exemple 10 : Implémenter des thèmes dynamiques

Vous pouvez utiliser :has() pour implémenter des thèmes dynamiques en fonction des préférences de l'utilisateur ou des paramètres du système. Par exemple, vous pouvez modifier la couleur d'arrière-plan de la page selon que l'utilisateur a activé ou non le mode sombre.

body:has(.dark-mode) { background-color: #333; color: #fff; }

Ces exemples illustrent la polyvalence du sélecteur :has() et sa capacité à résoudre un large éventail de problèmes de conception.

L'avenir du CSS : Quelle est la prochaine étape ?

L'introduction du sélecteur :has() marque une étape importante dans l'évolution du CSS. Il permet aux développeurs de créer des feuilles de style plus dynamiques, responsives et maintenables avec moins de dépendance à JavaScript. Alors que la prise en charge du navigateur pour :has() continue de croître, nous pouvons nous attendre à voir des utilisations encore plus innovantes et créatives de ce sélecteur puissant.

Pour l'avenir, le groupe de travail CSS explore d'autres fonctionnalités et améliorations intéressantes qui élargiront encore les capacités du CSS. Ceux-ci inclus:

En se tenant au courant des derniers développements CSS et en adoptant de nouvelles fonctionnalités comme :has(), les développeurs peuvent libérer tout le potentiel du CSS et créer des expériences Web vraiment exceptionnelles.

Conclusion

Le sélecteur :has() est un ajout puissant à la boîte à outils CSS, permettant la sélection parentale et ouvrant de nouvelles possibilités pour un style dynamique et responsive. Bien qu'il soit essentiel de tenir compte de la compatibilité du navigateur et des implications sur les performances, les avantages de l'utilisation de :has() pour un code CSS plus propre, plus maintenable et plus performant sont indéniables. Adoptez ce sélecteur qui change la donne et révolutionnez votre style CSS dès aujourd'hui !

N'oubliez pas de tenir compte de l'accessibilité et de fournir des mécanismes de repli pour les anciens navigateurs. En suivant les meilleures pratiques décrites dans ce guide, vous pouvez exploiter tout le potentiel du sélecteur :has() et créer des expériences Web vraiment exceptionnelles pour les utilisateurs du monde entier.