Case study :has()

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

Notoriamente CSS non disponeva di un modo per selezionare direttamente un elemento principale in base ai propri elementi secondari. Questa è una delle più richieste dagli sviluppatori da molti anni. Il selettore :has(), ora supportato da tutti i principali browser, risolve il problema. Prima del giorno :has(), spesso concatenavi selettori lunghi o aggiungevi classi per applicare uno stile agli hook. Ora puoi definire lo 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 di 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 Baseline Newly Available.

Supporto dei browser

  • 105
  • 105
  • 121
  • 15,4

Origine

Consulta la serie completa di cui fa parte questo articolo, che illustra come le aziende di e-commerce hanno migliorato il loro sito web utilizzando le nuove funzionalità CSS e dell'interfaccia utente.

Bazar delle norme

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 funzioni senza soluzione di continuità per noi, ma con la stessa esperienza di prima: Aman Soni, Tech Lead, Policybazaar

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

Implementazione di :has() per definire lo stile dell'elemento principale e dei relativi figli per creare una funzionalità di selezione associata alla categoria.

Codice

:has() ti consente di accedere allo stile degli elementi principali e dei relativi figli. Il codice seguente consente di verificare se per un contenitore principale è impostata una classe .disabled-group. In questo caso, la scheda è visualizzata in grigio 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 health di Policybazaar ha implementato un caso d'uso leggermente diverso. Ha un quiz incorporato per l'utente e usa :has() per selezionare lo stato della casella di controllo della domanda e vedere se la domanda ha ricevuto una risposta. In tal caso, viene applicata un'animazione per passare alla domanda successiva.

health.policybazaar.com/

Codice

Nell'esempio di confronto dei piani, è stato utilizzato :has() 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 è stata data una risposta alla domanda utilizzando :has(input:checked) e, in caso affermativo, attiva un'animazione utilizzando animation: quesSlideOut 0.3s 0.3s linear forwards per scorrere alla domanda successiva. Scopri come funziona nel codice che segue.

.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 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 codice CSS sarà più modulare e leggibile.

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

Codice

Il seguente codice utilizza i selettori CSS e i combinatori (& e >) e la nidificazione con :has() per definire lo stile della miniatura. Per i browser non supportati, viene utilizzata la normale regola della classe CSS aggiuntiva come riserva. La regola @supports selector(:has(*)) viene utilizzata anche per verificare il supporto del browser. Pertanto, l'esperienza complessiva è la stessa in tutte le 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() il selettore della famiglia.

Risorse:

Esplora gli altri articoli di questa serie che spiegano i vantaggi per le aziende di e-commerce dall'utilizzo di nuove funzionalità CSS e UI, come animazioni con scorrimento, transizioni di visualizzazione, query relative a popover e container.