Wykorzystanie potencjału zapytań do kontenera CSS: wnioski z doświadczenia zespołu Netflix

Jeremy Weeks
Jeremy Weeks
Stefan Heymanns
Stefan Heymanns

Zapytania dotyczące kontenera zrewolucjonizowały sposób, w jaki deweloperzy podchodzą do elastycznego projektowania. Zespół Netflixa na własnej skórze przekonał się, jak duży wpływ mogą one mieć na usprawnienie procesu tworzenia, zwiększenie elastyczności i poprawę wydajności. W tym poście omawiamy główne zalety korzystania z zapytań kontenera, porównując je ze starszymi metodami, zwłaszcza tymi, które do kontrolowania układu korzystają z JavaScriptu. Zawiera on przykłady kodu ilustrujące poszczególne punkty, pokazując, jak zapytania dotyczące kontenerów mogą znacznie ułatwić Ci życie jako deweloperowi.

1. Uproszczony projekt komponentów: „od dołu do góry” i „od góry do dołu”

Jednym z największych zmian, jakie wprowadził zespół Netflixa, było przejście od podejścia projektowego „od góry do dołu” do podejścia „od dołu do góry”. Przed wprowadzeniem zapytań dotyczących kontenerów kontenery nadrzędne musiały być w pełni świadome wymagań dotyczących układu swoich podrzędnych. W przypadku zapytań dotyczących kontenera ta logika jest odwrócona, co pozwala komponentom podrzędnym kontrolować układ na podstawie rozmiaru ich kontenera. Upraszcza to rolę elementu nadrzędnego i zmniejsza ilość logiki układu w kodzie.

Przykład: zapytania dotyczące kontenera a zapytania dotyczące multimediów i JavaScript

Wcześniej (wymagane 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();

Po:

/* 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%;
    }
}

Ten przykład pokazuje, że kontener nadrzędny nie musi już zarządzać układem podrzędnym. Reguła @container pozwala elementowi .card reagować na rozmiar kontenera, w którym się znajduje, upraszczając logikę układu i całkowicie eliminując potrzebę korzystania z języka JavaScript.

2. Odpowiedzialność bez skomplikowanych zapytań o media

Zespół Netflixa odkrył, jak zapytania dotyczące kontenera upraszczają responsywność, zwłaszcza w przypadku projektowania pod kątem urządzeń mobilnych. Zamiast pisać złożone zapytania o multimedia, możesz tworzyć komponenty wielokrotnego użytku, które dostosowują się do rozmiaru kontenera, umożliwiając dynamiczne układy na różnych rozmiarach ekranu i urządzeniach. Jest to szczególnie przydatne w przypadku aplikacji takich jak Netflix, w których przypadku dominuje ruch mobilny.

Przykład: szybkość działania komponentu w przypadku zapytań dotyczących kontenera

Przed:

/* 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%;
    }
}

Po:

/* 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;
    }
}

Zamiast polegać na zapytaniach dotyczących multimediów na podstawie widocznego obszaru, .sidebar reaguje teraz na rozmiar kontenera, co pozwala mu łatwiej dostosowywać się do dynamicznych układów bez konieczności znajomości rozmiaru widocznego obszaru lub nadrzędnego kontenera.

3. Zmniejszona zależność od kodu JavaScript w przypadku zarządzania układem

Przed pojawieniem się zapytań w kontenerach wiele zespołów, w tym Netflix, musiało polegać na kodzie JavaScript na potrzeby układów dynamicznych. Zapytanie o rozmiar okna uruchamiałoby zmiany układu, zwiększając złożoność i potencjał wystąpienia błędów. Zapytania o kontenery eliminują tę potrzebę, ponieważ pozwalają CSS zarządzać elastycznością układu na podstawie rozmiaru kontenera.

Przykład: usuwanie logiki układu opartej na JavaScript

Przed:

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();

Po:

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

.card {
    width: 100%;
}

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

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

Takie podejście nie tylko zmniejsza ilość potrzebnego kodu JavaScript, ale też poprawia wydajność, ponieważ nie trzeba wykonywać obliczeń w czasie działania.

4. Mniej kodu, mniej błędów

Zespół Netflixa odkrył, że używanie zapytań kontenerowych prowadzi do mniejszej liczby linii kodu i mniejszej liczby błędów związanych z układem. Dzięki przeniesieniu logiki układu z JavaScriptu do CSS i wyeliminowaniu potrzeby stosowania skomplikowanych zapytań o media deweloperzy mogą pisać kod, który jest łatwiejszy do utrzymania.

Przykład: ograniczanie kodu układu

Zespół Netflixa zauważył, że po wdrożeniu zapytań kontenerowych znacznie zmniejszyła się ilość kodu CSS – w przypadku niektórych komponentów nawet o 30%. Jednocześnie zespół był w stanie uprościć wiele złożonych i czasem podatnych na konflikty zapytań dotyczących multimediów, usuwając logikę kontrolującą komponenty podrzędne i osiągając wyższy stopień rozdzielenia zadań. Takie ograniczenie nie tylko przyspiesza rozwój, ale też minimalizuje potencjalne punkty awarii, co prowadzi do mniejszej liczby błędów.

Przed:

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

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

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

Po

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

.card {
    width: 100%;
}

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

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

5. Ulepszone środowisko programistów

bq. „To ułatwiło mi życie”

Jednym z najmniej docenianych zalet zapytań w kontenerach jest prawdopodobnie lepsze środowisko programistyczne. Dzięki temu, że CSS działa w bardziej intuicyjny sposób, skupiając się na komponentach, deweloperzy mogą skupić się na tworzeniu wielokrotnie użytecznych, elastycznych komponentów bez obaw o to, jak będą się one zachowywać w każdym możliwym scenariuszu układu.

Jak powiedział jeden z członków zespołu Netflix, „właśnie tak CSS powinno działać od samego początku”.

6. Zastępcza wersja wczytywania zawartości

Chociaż zapytania dotyczące kontenerów są teraz dostępne we wszystkich głównych przeglądarkach, nadal istnieją obawy dotyczące starszych wersji przeglądarek, które są nadal używane. Użycie rozwiązania zastępczego jest bardzo ważne. Zespół Netflixa używa tego polyfilla JavaScript stworzonego przez członków społeczności internetowej. Implementacja jest prosta dzięki funkcji wykrywania:

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

Podsumowanie

Zapytania o kontenery to ogromny krok naprzód w CSS, który ułatwia deweloperom tworzenie elastycznych, responsywnych komponentów, które można stosować wielokrotnie w różnych częściach witryny. Dzięki zmniejszeniu zależności od JavaScriptu w przypadku układu, wyeliminowaniu złożonych zapytań do multimediów i przyspieszeniu procesu tworzenia zapewniają znaczne korzyści pod względem wydajności i łatwości konserwacji. Obecnie większość przypadków użycia dotyczy stron Tudum w Netflix, ale planujemy też stosować zapytania dotyczące kontenera w innych częściach Netflix. Zespół Netflixa uważa zapytania dotyczące kontenera za narzędzie najwyższej klasy w swojej skrzynce narzędzi. Ich wykorzystanie będzie się zwiększać, ponieważ coraz więcej programistów docenia ich elastyczność i moc. Zapytania dotyczące kontenera to prostsze i czystsze rozwiązanie, które można wykorzystać do dostosowania istniejących komponentów lub zaprojektowania zupełnie nowych.

Jeśli jeszcze tego nie robisz, wypróbuj zapytania dotyczące kontenera. Prawdopodobnie zauważysz, że upraszcza to Twoją pracę w nieoczekiwany sposób.