Connu, il manquait un moyen de sélectionner directement un élément parent en fonction de ses enfants. Depuis de nombreuses années, c'est l'une des principales demandes des développeurs. Le sélecteur :has()
, désormais compatible avec les principaux navigateurs, résout ce problème. Avant :has()
, vous enchaîniez souvent des sélecteurs longs ou ajoutiez des classes pour les hooks de style. Vous pouvez désormais styliser en fonction de la relation d'un élément avec ses descendants. Pour en savoir plus sur le sélecteur :has()
, consultez l'article CSS Encapsulé 2023 et les 5 extraits CSS que les développeurs frontend devraient connaître.
Bien que ce sélecteur semble petit, il peut permettre de nombreux cas d'utilisation.
Cet article présente certains cas d'utilisation que les entreprises d'e-commerce ont débloqués à l'aide du sélecteur :has()
.
:has()
fait partie de la version Baseline Newly Available.
Consultez la série complète dont fait partie cet article, qui explique comment les entreprises d'e-commerce ont amélioré leur site Web à l'aide de nouvelles fonctionnalités CSS et 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, avec la même expérience qu'auparavant. Aman Soni, responsable technique, Policybazaar
L'équipe d'investissement de Policybazaar a utilisé intelligemment le sélecteur :has()
pour fournir une indication visuelle claire aux utilisateurs qui comparent les forfaits. L'image suivante montre deux types de forfaits dans l'interface utilisateur de comparaison (jaune et bleu). Chaque forfait ne peut être comparé qu'à son propre type. Si vous utilisez :has()
, lorsqu'un utilisateur sélectionne un type de forfait, l'autre type ne peut pas être sélectionné.
Code
:has()
vous permet d'appliquer un style aux éléments parents 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 mis en œuvre un cas d'utilisation légèrement différent. Ils disposent d'un questionnaire intégré pour l'utilisateur et utilisent :has()
pour vérifier l'état de la case à cocher de la question et voir si une réponse a été apportée. Si c'est le cas, une animation est appliquée pour passer à la question suivante.
Code
Dans l'exemple de comparaison des 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, comme une case à cocher, à l'aide de :has(input:checked)
. Dans le visuel montrant le quiz, chaque question dans la bannière violette est une case à cocher. Policybazaar vérifie si une réponse a été apportée à la question à l'aide de :has(input:checked)
et, si c'est le cas, déclenche une animation en utilisant animation: quesSlideOut 0.3s 0.3s linear forwards
pour faire glisser la question vers la question suivante. Pour en savoir plus, consultez 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 en superposition si la miniature du produit contient une vidéo. Si la vignette 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 vignettes. Cela permet de créer un code CSS plus modulaire et plus lisible.
Code
Le code suivant utilise les combinateurs et sélecteurs 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 en remplacement. La règle @supports selector(:has(*))
permet également de vérifier la compatibilité des navigateurs.
Par conséquent, l'expérience est globalement la même pour 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 lorsque vous utilisez :has()
Combinez :has()
avec d'autres sélecteurs pour créer une condition plus complexe. Découvrez quelques exemples dans has() le sélecteur de famille.
Ressources :
- CSS encapsulé(e) 2023
- :has(): sélecteur de famille
- Démonstrations :has()
- Souhaitez-vous signaler un bug ou demander une nouvelle fonctionnalité ? Votre avis nous intéresse !
Découvrez les autres articles de cette série qui expliquent comment les entreprises d'e-commerce ont tiré parti des nouvelles fonctionnalités CSS et UI, telles que les animations basées sur le défilement, les transitions d'affichage, les fenêtres pop-up et les requêtes de conteneur.