Études de cas :has()

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

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 enchaîniez souvent des sélecteurs longs ou ajoutiez des classes pour les crochets 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 sélecteur :has(), consultez CSS Wrapped 2023 et 5 extraits CSS que tout développeur front-end doit 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 la section Nouvelle version de référence disponible.

Navigateurs pris en charge

  • Chrome: 105
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

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.

Implémentation de :has() pour styliser 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 de styliser les éléments parent et leurs enfants. Le code suivant vérifie si un conteneur parent a une classe .disabled-group définie. 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 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 afin de voir si elle a été répondue. 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 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 question a été répondue à l'aide de :has(input:checked). Si c'est le cas, il déclenche une animation à 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 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.

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 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é avec le navigateur. Par conséquent, l'expérience globale est la même entre 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;
    }
  }
`;

É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 :

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.