Études de cas :has()

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

Le CSS n'a jamais permis de sélectionner directement un élément parent en fonction de ses enfants. Il s'agit d'une demande récurrente des 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 les hooks de style. 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 :has() sélecteur dans CSS Wrapped 2023 et 5 extraits CSS que tout développeur frontend devrait connaître.

Bien que ce sélecteur semble petit, il peut activer 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().

Consultez la série complète dont cet article fait partie. Elle explique comment les entreprises d'e-commerce ont amélioré leur site Web à l'aide de nouvelles fonctionnalités CSS et d'interface utilisateur.

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 de manière transparente pour nous avec la même expérience qu'auparavant.—Aman Soni, responsable technique, Policybazaar

L'équipe d'investissement de Policybazaar a appliqué le sélecteur :has() de manière astucieuse pour fournir une indication visuelle claire aux utilisateurs qui comparent des 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'avec son propre type. En utilisant :has(), lorsqu'un utilisateur sélectionne un type de forfait, l'autre type de forfait ne peut pas être sélectionné.

Implémentation de :has() pour appliquer un style à l'élément parent et à ses enfants afin de créer une fonctionnalité de sélection liée à une catégorie.

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 réagit pas 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 de santé de Policybazaar a implémenté un cas d'utilisation légèrement différent. Elle propose un quiz en ligne à l'utilisateur et utilise :has() pour vérifier l'état de la case à cocher de la question afin de voir si l'utilisateur a répondu. Si c'est le cas, une animation est appliquée pour passer à la question suivante.

health.policybazaar.com/

Code

Dans l'exemple de comparaison de forfaits, :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 l'image montrant le quiz, chaque question de la bannière violette est une case à cocher. Policybazaar vérifie si l'utilisateur a répondu à la question à l'aide de :has(input:checked). Si c'est le cas, une animation est déclenchée à l'aide de animation: quesSlideOut 0.3s 0.3s linear forwards pour passer à 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 de superposition 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 globale .thumbnailWrapper, qui s'applique à toutes les miniatures. Cela crée un CSS plus modulaire et plus lisible.

Capture d'écran de la page Tokopedia avant et après l'utilisation du sélecteur "has".
Avant et après l'utilisation de :has().

Code

Le code suivant utilise les sélecteurs et les combinateurs CSS (& et >) ainsi que l'imbrication avec :has() pour appliquer un style à la miniature. 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(*)) est également utilisée pour vérifier la compatibilité du navigateur. Par conséquent, l'expérience globale est la même dans toutes les versions du 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;
    }
  }
`;

Points à 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() the family selector.

Ressources :

Découvrez les autres articles de cette série qui expliquent comment les entreprises d'e-commerce ont bénéficié de l'utilisation de nouvelles fonctionnalités CSS et d'interface utilisateur telles que les animations pilotées par le défilement, les transitions de vue, les pop-ups et les requêtes de conteneur.