Case study :has()

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

È noto che in CSS non esiste un modo per selezionare direttamente un elemento principale in base ai suoi elementi secondari. Questa è da molti anni una delle richieste principali degli sviluppatori. Il selettore:has(), ora supportato da tutti i principali browser, risolve questo problema. Prima di :has(), spesso si mettevano in catena selettori lunghi o si aggiungevano classi per gli hook di stile. Ora puoi applicare uno stile in base alla relazione di un elemento con i suoi discendenti. Scopri di più sul selettore :has() in CSS Wrapped 2023 e 5 snippet CSS che ogni sviluppatore frontend dovrebbe conoscere.

Sebbene questo selettore sembri piccolo, può consentire un numero enorme di casi d'uso. Questo articolo mostra alcuni casi d'uso che le aziende di e-commerce hanno sbloccato con il selettore :has().

:has() fa parte di Elementi di base di nuovo disponibili.

Supporto dei browser

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

Origine

Dai un'occhiata alla serie completa di cui fa parte questo articolo, che illustra in che modo le aziende di e-commerce hanno migliorato il proprio sito web utilizzando nuove funzionalità CSS e UI.

Bazar criteri

Con il selettore :has(), siamo riusciti a eliminare la convalida basata su JavaScript della selezione dell'utente e a sostituirla con una soluzione CSS che funziona perfettamente per noi con la stessa esperienza di prima. - Aman Soni, Tech Lead, Policybazaar

Il team di investimento di Policybazaar ha applicato abilmente il selettore :has() per fornire un'indicazione visiva chiara agli utenti che confrontano i piani. L'immagine seguente mostra due tipi di piani nell'interfaccia utente di confronto (giallo e blu). Ogni piano può essere confrontato solo con il proprio tipo. Se utilizzi :has(), quando un utente seleziona un tipo di piano, l'altro tipo di piano non può essere selezionato.

Implementazione di :has() per applicare uno stile all'elemento principale e ai relativi elementi secondari al fine di creare una funzionalità di selezione vincolata alla categoria.

Codice

:has() ti consente di applicare stili agli elementi principali e ai relativi elementi secondari. Il seguente codice verifica se un contenitore principale ha una classe .disabled-group impostata. In questo caso, la scheda non è selezionabile e il pulsante "Aggiungi" non reagisce ai clic impostando pointer-events su 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);
}

Il team dedicato alla salute di Policybazaar ha implementato un caso d'uso leggermente diverso. Hanno un quiz in linea per l'utente e usano :has() per selezionare lo stato della casella di controllo della domanda e vedere se la domanda ha ricevuto una risposta. In questo caso, viene applicata un'animazione per passare alla domanda successiva.

health.policybazaar.com/

Codice

Nell'esempio di confronto dei piani, :has() è stato utilizzato per verificare la presenza di una classe. Puoi anche controllare lo stato di un elemento di input, ad esempio una casella di controllo, utilizzando :has(input:checked). Nell'immagine che mostra il quiz, ogni domanda nel banner viola è una casella di controllo. Policybazaar controlla se la domanda ha ricevuto risposta utilizzando :has(input:checked) e, in caso affermativo, attiva un'animazione utilizzando animation: quesSlideOut 0.3s 0.3s linear forwards per passare alla domanda successiva. Scopri come funziona nel codice seguente.

.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 ha utilizzato :has() per creare un'immagine in overlay se la miniatura del prodotto contiene un video. Se la miniatura del prodotto contiene una classe .playIcon, viene aggiunto un overlay CSS. In questo caso, il selettore :has() viene utilizzato insieme al selettore di nidificazione & all'interno della classe .thumbnailWrapper generale che si applica a tutte le miniature. In questo modo, il CSS è più modulare e leggibile.

Screenshot della pagina di Tokopedia prima e dopo l'utilizzo del selettore has.
Prima e dopo l'utilizzo di :has().

Codice

Il seguente codice utilizza i selettori e i combinatori CSS (& e >) e il nidificazione con :has() per applicare uno stile alla miniatura. Per i browser che non supportano la funzionalità, viene utilizzata come alternativa la regola della classe CSS aggiuntiva standard. La regola @supports selector(:has(*)) viene utilizzata anche per verificare il supporto del browser. Di conseguenza, l'esperienza complessiva è la stessa nelle varie versioni del browser.

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;
    }
  }
`;

Aspetti da considerare quando si utilizza :has()

Combina :has() con altri selettori per creare una condizione più complessa. Dai un'occhiata ad alcuni esempi in has() sul selettore della famiglia.

Risorse:

Consulta gli altri articoli di questa serie per scoprire in che modo le aziende di e-commerce hanno tratto vantaggio dall'utilizzo di nuove funzionalità CSS e UI, come animazioni basate sullo scorrimento, transizioni di visualizzazione, popover e query dei contenitori.