Le CSS ne permet pas de sélectionner directement un élément parent en fonction de ses enfants. C'est une fonctionnalité très demandée par les développeurs depuis de nombreuses années. Le sélecteur :has()
, désormais compatible avec tous les principaux navigateurs, résout ce problème. Avant :has()
, vous deviez souvent enchaîner de longs sélecteurs ou ajouter des classes pour appliquer un style aux hooks. Vous pouvez désormais appliquer un style en fonction de la relation d'un élément avec ses descendants. Pour en savoir plus sur le sélecteur :has()
, consultez CSS Wrapped 2023 et Cinq extraits CSS que tous les développeurs de l'interface doivent connaître.
Bien que ce sélecteur semble petit, il peut permettre un grand nombre de cas d'utilisation.
Cet article présente quelques cas d'utilisation que les entreprises d'e-commerce ont débloqués avec le sélecteur :has()
.
:has()
fait partie de Baseline Newly Available.
Découvrez la série complète dont cet article fait partie, qui explique comment les entreprises d'e-commerce ont amélioré leur site Web à l'aide de nouvelles fonctionnalités CSS et d'UI.
Policybazaar
Avec le sélecteur
:has()
, nous avons pu éliminer la validation basée sur JavaScript de la sélection de l'utilisateur et la remplacer par une solution CSS qui fonctionne parfaitement pour nous avec la même expérience qu'auparavant.—Aman Soni, Tech Lead, Policybazaar
L'équipe Investment de Policybazaar a intelligemment appliqué le sélecteur :has()
pour fournir une indication visuelle claire aux utilisateurs qui comparent des forfaits. L'image suivante montre deux types de forfaits dans l'UI de comparaison (jaune et bleu). Chaque forfait ne peut être comparé qu'à son propre type. Lorsque vous utilisez :has()
, un utilisateur ne peut pas sélectionner un autre type de forfait lorsqu'il a déjà sélectionné un type de forfait.
Code
:has()
vous permet de styliser les éléments parent et leurs enfants. Le code suivant vérifie si une classe .disabled-group
est définie pour un conteneur parent.
Si c'est le cas, la fiche est grisée et le bouton "Ajouter" ne peut pas réagir aux clics en définissant pointer-events
sur none
.
.plan-group-container:has(.disabled-group) {
opacity: 0.5;
filter: grayscale(100%);
}
.plan-group-container:has(.disabled-section) .button {
pointer-events: none;
border-color: #B5B5B5;
color: var(--text-primary-38-color);
background: var(--input-border-color);
}
L'équipe santé de Policybazaar a implémenté un cas d'utilisation légèrement différent. Il propose un quiz intégré à l'utilisateur et utilise :has()
pour vérifier l'état de la case à cocher de la question et voir si la réponse a été donnée. Si c'est le cas, une animation est appliquée pour passer à la question suivante.
Code
Dans l'exemple de comparaison de plans, :has()
a été utilisé pour vérifier la présence d'une classe. Vous pouvez également vérifier l'état d'un élément d'entrée, tel qu'une case à cocher, à l'aide de :has(input:checked)
. Dans le visuel du quiz, chaque question de la bannière violette est une case à cocher. Policybazaar vérifie si la réponse à la question a été trouvée à l'aide de :has(input:checked)
et, le cas échéant, déclenche une animation à l'aide de animation: quesSlideOut 0.3s 0.3s linear forwards
pour faire glisser le curseur vers la question suivante. Découvrez comment cela fonctionne dans le code suivant.
.segment_banner__wrap__questions {
position: relative;
animation: quesSlideIn 0.3s linear forwards;
}
.segment_banner__wrap__questions:has(input:checked) {
animation: quesSlideOut 0.3s 0.3s linear forwards;
}
@keyframes quesSlideIn {
from {
transform: translateX(50px);
opacity: 0;
}
to {
transform: translateX(0px);
opacity: 1;
}
}
@keyframes quesSlideOut {
from {
transform: translateX(0px);
opacity: 1;
}
to {
transform: translateX(-50px);
opacity: 0;
}
}
Tokopedia
Tokopedia a utilisé :has()
pour créer une image superposée si la miniature du produit contient une vidéo. Si la miniature du produit contient une classe .playIcon
, une superposition CSS est ajoutée. Ici, le sélecteur :has() est utilisé avec le sélecteur d'imbrication &
dans la classe .thumbnailWrapper
globale qui s'applique à toutes les miniatures. Cela crée un code CSS plus modulaire et lisible.
Code
Le code suivant utilise les sélecteurs et combinators CSS (&
et >
) et l'imbrication avec :has()
pour styliser la vignette.
Pour les navigateurs non compatibles, la règle de classe CSS supplémentaire standard est utilisée comme solution de secours. La règle @supports selector(:has(*))
permet également de vérifier la compatibilité des navigateurs.
Par conséquent, l'expérience globale est la même sur toutes les versions de navigateur.
export const thumbnailWrapper = css`
padding: 0;
margin-right: 7px;
border: none;
outline: none;
background: transparent;
> div {
width: 64px;
height: 64px;
overflow: hidden;
cursor: pointer;
border-color: ;
position: relative;
border: 2px solid ${NN0};
border-radius: 8px;
transition: border-color 0.25s;
&.active {
border-color: ${GN500};
}
@supports selector(:has(*)) {
&:has(.playIcon) {
&::after {
content: '';
display: block;
background: rgba(0, 0, 0, 0.2);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}
}
& > .playIcon {
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
text-align: center;
z-index: 1;
}
}
`;
Éléments à prendre en compte lors de l'utilisation de :has()
Combinez :has()
avec d'autres sélecteurs pour créer une condition plus complexe. Consultez quelques exemples dans has() le sélecteur de famille.
Ressources :
- Version CSS 2023
- :has(): sélecteur de famille
- Démonstrations :has()
- Voulez-vous signaler un bug ou demander une nouvelle fonctionnalité ? Votre avis nous intéresse !
Consultez les autres articles de cette série qui expliquent comment les entreprises d'e-commerce ont tiré parti des nouvelles fonctionnalités CSS et d'UI telles que les animations basées sur le défilement, les transitions de vue, les popovers et les requêtes de conteneur.