Études de cas :has()

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

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.

Navigateurs pris en charge

  • 105
  • 105
  • 121
  • 15,4

Source

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é.

Implémenter :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 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.

health.policybazaar.com/

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.

Capture d'écran de la page de 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 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 :

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.