Sfruttare al meglio le query dei contenitori CSS: lezioni del team di Netflix

Jeremy Weeks
Jeremy Weeks
Stefan Heymanns
Stefan Heymanns

Le query dei contenitori hanno rivoluzionato il modo in cui gli sviluppatori si approcciano al design responsive e il team di Netflix ha sperimentato in prima persona l'impatto profondo che possono avere sulla semplificazione dello sviluppo, sul miglioramento della flessibilità e sul potenziamento delle prestazioni. Questo post illustra i vantaggi principali dell'utilizzo delle query dei contenitori, confrontandoli con i metodi precedenti, in particolare quelli che si basano su JavaScript per il controllo del layout. Sono inclusi esempi di codice per illustrare ogni punto e mostrare come le query dei contenitori possono semplificare la vita degli sviluppatori.

1. Progettazione semplificata dei componenti, "dal basso verso l'alto" rispetto a "dall'alto verso il basso"

Uno dei cambiamenti più significativi che il team di Netflix ha vissuto è stato il passaggio da un approccio di progettazione "top-down" a uno "bottom-up". Prima delle query dei contenitori, i contenitori principali dovevano essere pienamente consapevoli dei requisiti di layout dei contenitori secondari. Con le query del contenitore, questa logica è invertita, consentendo ai componenti figli di controllare il layout in base alle dimensioni del proprio contenitore. In questo modo, il ruolo del componente principale viene semplificato e la logica di layout nel codice viene ridotta.

Esempio: query dei contenitori rispetto a query sui media e JavaScript

Prima (è necessario JavaScript):

/* Layout with media queries */
.card {
    width: 100%;
}

@media (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@media (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}
// JavaScript to detect parent container size
const container = document.querySelector('.container');
const card = document.querySelector('.card');

function adjustLayout() {
    if (window.innerWidth >= 900) {
        card.style.width = '33.33%';
    } else if (window.innerWidth >= 600) {
        card.style.width = '50%';
    } else {
        card.style.width = '100%';
    }
}

window.addEventListener('resize', adjustLayout);
adjustLayout();

Dopo:

/* Container Query */
.container {
    container-type: inline-size;
}

.card {
    width: 100%;
}

@container (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@container (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}

Questo esempio mostra come il contenitore principale non debba più gestire il layout secondario. La regola @container consente a .card di reagire alle dimensioni del contenitore immediato, semplificando la logica di layout e eliminando del tutto la necessità di JavaScript.

2. Adattabilità senza query sui media complesse

Il team di Netflix ha scoperto in che modo le query dei contenitori semplificano la reattività, soprattutto per il design mobile-first. Anziché scrivere query supporti complesse, puoi creare componenti riutilizzabili che si adattano in base alle dimensioni del contenitore, consentendo layout dinamici su vari dispositivi e dimensioni dello schermo. Questo è particolarmente utile per app come Netflix, in cui il traffico mobile è predominante.

Esempio: adattabilità dei componenti con query dei contenitori

Prima:

/* Desktop versus Mobile
this only works if.sidebar is directly contained by a viewport-width element */
.sidebar {
    width: 300px;
}

@media (max-width: 768px) {
    .sidebar {
        width: 100%;
    }
}

Dopo:

/* Responsive sidebar based on container,
.sidebar can be placed in any element of any width */
.container {
    container-type: inline-size;
}

.sidebar {
    width: 100%;
}

@container (min-width: 768px) {
    .sidebar {
        width: 300px;
    }
}

Anziché dipendere dalle query sui media basate sull'area visibile, ora .sidebar risponde alle dimensioni del contenitore, il che consente di adattarsi in modo più naturale ai layout dinamici senza dover conoscere le dimensioni dell'area visibile o del contenitore principale.

3. Diminuzione della dipendenza da JavaScript per la gestione del layout

Prima delle query sui contenitori, molti team, tra cui Netflix, dovevano fare affidamento su JavaScript per i layout dinamici. Se esegui una query sulle dimensioni della finestra, JavaScript attiverebbe modifiche al layout, aumentando la complessità e la potenziale presenza di bug. Le query contenitore eliminano questa necessità consentendo al CSS di gestire la adattabilità del layout in base alle dimensioni del contenitore.

Esempio: rimozione della logica di layout basata su JavaScript

Prima:

const cardContainer = document.querySelector('.card-container');
const cards = cardContainer.children;

function adjustLayout() {
    if (cardContainer.offsetWidth > 900) {
        cards.forEach(card => card.style.width = '33.33%');
    } else if (cardContainer.offsetWidth > 600) {
        cards.forEach(card => card.style.width = '50%');
    } else {
        cards.forEach(card => card.style.width = '100%');
    }
}

window.addEventListener('resize', adjustLayout);
adjustLayout();

Dopo:

.card-container {
    container-type: inline-size;
}

.card {
    width: 100%;
}

@container (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@container (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}

Questo approccio non solo riduce la quantità di JavaScript necessaria, ma migliora anche le prestazioni evitando i calcoli di runtime.

4. Meno codice, meno bug

Il team di Netflix ha scoperto che l'utilizzo delle query dei contenitori ha comportato un minor numero di righe di codice e di bug relativi al layout. Spostando la logica di layout da JavaScript a CSS e eliminando la necessità di query supporti complesse, gli sviluppatori possono scrivere codice più manutenibile.

Esempio: ridurre il codice di layout

Il team di Netflix ha notato una significativa riduzione del codice CSS, fino al 30% per alcuni componenti, dopo aver adottato le query del contenitore. Allo stesso tempo, il team è stato in grado di semplificare molte query sui media complesse e talvolta soggette a conflitti eliminando la logica che controllava i componenti secondari, ottenendo un grado più elevato di separazione degli aspetti. Questa riduzione non solo accelera lo sviluppo, ma riduce al minimo i potenziali punti di errore, con una conseguente riduzione dei bug.

Prima:

/* Before with complex media queries */
.card {
    width: 100%;
}

@media (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@media (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}

Dopo

.container {
    container-type: inline-size;
}

.card {
    width: 100%;
}

@container (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@container (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}

5. Esperienza di sviluppo migliorata

bq. "Questo mi ha semplificato la vita cento volte"

Forse uno dei vantaggi più sottovalutati delle query sui contenitori è l'esperienza di sviluppo migliorata. Se il CSS si comporta in modo più intuitivo e incentrato sui componenti, gli sviluppatori possono concentrarsi sulla creazione di componenti flessibili e riutilizzabili senza preoccuparsi di come si comporteranno in ogni possibile scenario di layout.

Come ha detto uno dei membri del team di Netflix, "È così che il CSS avrebbe dovuto funzionare fin dall'inizio".

6. Riserva di polyfill

Sebbene le query dei contenitori siano ora disponibili in tutti i principali browser, ci sono dubbi sulle versioni precedenti dei browser ancora in uso. Un piano di riserva è molto importante. Il team di Netflix utilizza questo polyfill JavaScript creato dai collaboratori della community web. L'implementazione è semplice con il rilevamento delle funzionalità:

if (! CSS.supports("container-type:size")) {
  /*use polyfill from
  https://www.npmjs.com/package/container-query-polyfill */
 }

Conclusione

Le query dei contenitori rappresentano un enorme passo avanti nel CSS, in quanto consentono agli sviluppatori di creare componenti flessibili e adattabili che possono essere riutilizzati in diverse parti di un sito. Riducendo la dipendenza da JavaScript per il layout, eliminando query sui media complesse e accelerando lo sviluppo, offrono vantaggi significativi sia in termini di prestazioni che di manutenibilità. Attualmente, la maggior parte dei casi d'uso si trova sulle pagine di Tudum di Netflix, con potenziali piani per utilizzare le query dei contenitori in altre parti di Netflix. Il team di Netflix considera le query dei contenitori uno strumento di prima classe nella cassetta degli attrezzi dello sviluppatore e il loro utilizzo aumenterà man mano che un numero maggiore di sviluppatori ne adotterà la flessibilità e la potenza. Che si tratti di eseguire il retrofit di componenti esistenti o di progettarne di nuovi, le query dei contenitori offrono un percorso più semplice e chiaro per il design adattabile.

Se non l'hai ancora fatto, prova le query dei contenitori: probabilmente scoprirai che semplificano il tuo flusso di lavoro in modi inaspettati.