Niedawno Chris Coyier napisał posta na blogu, zadając sobie pytanie:
Skoro zapytania w kontenerach są obsługiwane przez wszystkie wyszukiwarki, dlaczego coraz więcej programistów z nich nie korzysta?
Post Chrisa podaje kilka potencjalnych przyczyn (np. brak świadomości, stare nawyki umierają bezpowrotnie), ale jest też konkretna przyczyna, która szczególnie się wyróżnia.
Niektórzy deweloperzy chcą teraz korzystać z zapytań dotyczących kontenerów, ale uważają, że nie jest to możliwe, ponieważ nadal muszą obsługiwać starsze przeglądarki.
Jak można się domyślić na podstawie tytułu, sądzimy, że większość programistów ma teraz możliwość korzystania z zapytań dotyczących kontenerów w środowisku produkcyjnym, nawet jeśli trzeba obsługiwać starsze przeglądarki. W tym poście omawiamy zalecane przez nas podejście.
Pragmatyczne podejście
Jeśli chcesz używać w kodzie zapytań dotyczących kontenerów, ale chcesz, aby wyglądały one tak samo we wszystkich przeglądarkach, możesz zaimplementować kreacje zastępcze w językach JavaScript, które nie obsługują zapytań dotyczących kontenerów.
Kolejne pytanie brzmi: na ile wszechstronne powinna być kreacja zastępcza?
Tak jak w przypadku każdej kreacji zastępczej, wyzwaniem jest zachowanie równowagi między użytecznością a wydajnością. W przypadku funkcji CSS obsługa pełnego interfejsu API często nie jest dostępna (zobacz, dlaczego nie używać polyfill). Jednak może to być całkiem sporo, jeśli określisz podstawowy zestaw funkcji, z których powinna korzystać większość deweloperów, a następnie zoptymalizować reklamy zastępcze tylko pod kątem tych funkcji.
Jaki jest „podstawowy zestaw funkcji”, w przypadku zapytań dotyczących kontenerów. Aby odpowiedzieć na to pytanie, zastanów się, jak większość programistów tworzy obecnie elastyczne witryny z zapytaniami o multimedia.
Prawie wszystkie nowoczesne systemy projektowania i biblioteki komponentów zostały ustandaryzowane pod kątem urządzeń mobilnych i są zaimplementowane za pomocą zestawu zdefiniowanych wstępnie punktów przerwania (takich jak SM
, MD
, LG
, XL
). Komponenty są domyślnie zoptymalizowane pod kątem wyświetlania ich na małych ekranach. Style są na siebie warunkowo nakładane, aby obsługiwać stały zestaw o większych szerokościach ekranu. Przykłady znajdziesz w dokumentacji Bootstrap i Tailwind.
To podejście jest tak samo trafne w przypadku systemów projektowania opartych na kontenerach, jak w przypadku systemów uwzględniających widoczny obszar. W większości przypadków dla projektantów istotne jest nie to, jak duży jest ekran, tylko ilość miejsca dostępnego dla komponentu w kontekście, w którym jest umieszczony. Inaczej mówiąc, zamiast punktów przerwania względem całego widocznego obszaru (i dotyczy całej strony) będą one stosowane do określonych obszarów treści, takich jak paski boczne, okna modalne lub treść posta.
Jeśli poradzisz sobie z ograniczeniami wynikającymi z podejścia przede wszystkim na urządzenia mobilne i opartego na punktach przerwania (co obecnie robi większość deweloperów), to wdrożenie dla tego podejścia kreacji zastępczej opartej na kontenerach jest znacznie łatwiejsze niż wdrażanie pełnej obsługi funkcji zapytań dotyczących poszczególnych kontenerów.
W następnej sekcji wyjaśniamy, jak to wszystko działa, wraz ze szczegółowym przewodnikiem, który wyjaśnia, jak wdrożyć je w istniejącej witrynie.
Jak to działa
Krok 1. Zaktualizuj style komponentu, aby używały reguł @container
zamiast @media
W pierwszym kroku określ wszystkie komponenty witryny, które Twoim zdaniem skorzystałyby na dostosowaniu rozmiaru według kontenerów, a nie na podstawie widocznego obszaru.
Warto zacząć od jednego lub dwóch komponentów, by zobaczyć, jak działa ta strategia, ale jeśli chcesz przekształcić wszystkie komponenty w styl oparty na kontenerach, również możesz to zrobić. Największą zaletą tej strategii jest to, że w razie potrzeby można ją stosować stopniowo.
Po wybraniu komponentów, które chcesz zaktualizować, musisz zmienić w nich każdą regułę @media
CSS do reguły @container
.
Oto przykład, jak to może wyglądać w komponencie .photo-gallery
, który domyślnie składa się z pojedynczej kolumny, a następnie za pomocą reguł @media
aktualizuje swój układ tak, aby w punktach przerwania MD i XL (odpowiednio) znalazły się dwie i trzy kolumny:
.photo-gallery {
display: grid;
grid-template-columns: 1fr;
}
/* Styles for the `MD` breakpoint */
@media (min-width: 800px) {
.photo-gallery {
grid-template-columns: 1fr 1fr;
}
}
/* Styles for the `XL` breakpoint */
@media (min-width: 1200px) {
.photo-gallery {
grid-template-columns: 1fr 1fr 1fr;
}
}
Aby zaktualizować komponent .photo-gallery
tak, aby korzystał z reguł @container
, najpierw zastąp ciąg znaków @media
ciągiem @container
w CSS. Gramatyka obu tych reguł jest na tyle podobna, że w wielu przypadkach to może być wszystko, co trzeba zmienić.
W zależności od projektu witryny może być też konieczna aktualizacja warunku rozmiaru, zwłaszcza jeśli reguły @media
w witrynie zakładają, ile miejsca będzie dostępne dla konkretnych komponentów na różnych rozmiarach widocznego obszaru.
Jeśli na przykład style CSS .photo-gallery
w punktach przerwania MD
i XL
w poprzednim przykładzie zakładają, że w tych punktach przerwania będzie wyświetlany pasek boczny o szerokości 200 pikseli, wtedy warunki rozmiaru w regułach @container
powinny być o około 200 pikseli mniej, przy założeniu, że „kontener” dla komponentu .photo-gallery
nie będzie zawierał paska bocznego.
Aby można było przekonwertować reguły CSS .photo-gallery
z reguł @media
na reguły @container
, pełny zestaw zmian będzie wyglądał tak:
/* Before, using the original breakpoint sizes: */
@media (min-width: 800px) { /* ... */ }
@media (min-width: 1200px) { /* ... */ }
/* After, with the breakpoint sizes reduced by 200px: */
@container (min-width: 600px) { /* ... */ }
@container (min-width: 1000px) { /* ... */ }
Pamiętaj, że nie musisz zmieniać żadnego stylu w obrębie bloku deklaracji, ponieważ odzwierciedlają one jak wygląd komponentu, a nie to, kiedy powinny zostać zastosowane określone style.
Po zmianie stylów komponentów z reguł @media
na reguły @container
kolejnym krokiem jest skonfigurowanie elementów kontenera.
Krok 2. Dodaj elementy kontenerów do kodu HTML
W poprzednim kroku zdefiniowano style komponentów oparte na rozmiarze elementu kontenera. Następnym krokiem jest określenie, które elementy na stronie powinny być tymi elementami kontenera, których rozmiar będą dotyczyć reguł @container
.
Możesz zadeklarować dowolny element jako element kontenera w CSS, ustawiając jego właściwość container-type
na size
lub inline-size
. Jeśli reguły kontenera opierają się na szerokości, zazwyczaj należy użyć inline-size
.
Weźmy na przykład witrynę o podstawowej strukturze HTML:
<body>
<div class="sidebar">...</div>
<div class="content">...</div>
</body>
Aby ustawić elementy .sidebar
i .content
w tej witrynie jako kontenery, dodaj tę regułę do CSS:
.content, .sidebar {
container-type: inline-size;
}
W przeglądarkach, które obsługują zapytania dotyczące kontenerów, wystarczy Ci kod CSS, aby style komponentu zdefiniowane w poprzednim kroku utworzyć względem głównego obszaru treści lub paska bocznego, w zależności od tego, w jakim elemencie się znajdują.
Jednak w przypadku przeglądarek, które nie obsługują zapytań dotyczących kontenerów, konieczne jest wykonanie dodatkowych czynności.
Musisz dodać kod, który wykrywa zmianę rozmiaru elementów kontenera, a następnie aktualizuje DOM na podstawie tych zmian w sposób, który będzie możliwy do powiązania z CSS.
Na szczęście wymagany kod jest minimalny i można go całkowicie wyodrębnić jako wspólny komponent, którego można używać w dowolnej witrynie i w dowolnym obszarze treści.
Ten kod definiuje element <responsive-container>
wielokrotnego użytku, który automatycznie wykrywa zmiany rozmiaru i dodaje klasy punktów przerwania, na podstawie których CSS może określić styl:
// A mapping of default breakpoint class names and min-width sizes.
// Redefine these (or add more) as needed based on your site's design.
const defaultBreakpoints = {SM: 400, MD: 600 LG: 800, XL: 1000};
// A resize observer that monitors size changes to all <responsive-container>
// elements and calls their `updateBreakpoints()` method with the updated size.
const ro = new ResizeObserver((entries) => {
entries.forEach((e) => e.target.updateBreakpoints(e.contentRect));
});
class ResponsiveContainer extends HTMLElement {
connectedCallback() {
const bps = this.getAttribute('breakpoints');
this.breakpoints = bps ? JSON.parse(bps) : defaultBreakpoints;
this.name = this.getAttribute('name') || '';
ro.observe(this);
}
disconnectedCallback() {
ro.unobserve(this);
}
updateBreakpoints(contentRect) {
for (const bp of Object.keys(this.breakpoints)) {
const minWidth = this.breakpoints[bp];
const className = this.name ? `${this.name}-${bp}` : bp;
this.classList.toggle(className, contentRect.width >= minWidth);
}
}
}
self.customElements.define('responsive-container', ResponsiveContainer);
Kod ten tworzy mechanizm ResizeObserver, który automatycznie nasłuchuje zmian rozmiaru wszystkich elementów <responsive-container>
w DOM. Jeśli zmiana rozmiaru pasuje do jednego ze zdefiniowanych rozmiarów punktu przerwania, do elementu jest dodawana klasa o tej nazwie (i usuwana, jeśli warunek nie będzie już spełniony).
Jeśli na przykład width
elementu <responsive-container>
ma długość od 600 do 800 pikseli (w zależności od domyślnych wartości punktów przerwania ustawionych w kodzie), zostaną dodane klasy SM
i MD
w ten sposób:
<responsive-container class="SM MD">...</responsive-container>
Te klasy pozwalają zdefiniować style kreacji zastępczych dla przeglądarek, które nie obsługują zapytań dotyczących kontenerów (patrz krok 3: dodawanie stylów zastępczych do CSS).
Jeśli chcesz zaktualizować poprzedni kod HTML i używać tego elementu kontenera, zmień elementy paska bocznego i treści głównej <div>
na elementy <responsive-container>
:
<body>
<responsive-container class="sidebar">...</responsive-container>
<responsive-container class="content">...</responsive-container>
</body>
W większości przypadków wystarczy po prostu użyć elementu <responsive-container>
bez żadnych dostosowań, ale jeśli chcesz go dostosować, dostępne są te opcje:
- Niestandardowe rozmiary punktów przerwania: ten kod używa zestawu domyślnych nazw klas punktów przerwania i rozmiarów minimalnej szerokości, ale możesz zmienić te wartości domyślne. Możesz też zastąpić te wartości dla poszczególnych elementów za pomocą atrybutu
breakpoints
. - Nazwane kontenery: ten kod obsługuje również nazwane kontenery, przekazując atrybut
name
. Jest to przydatne, jeśli musisz zagnieździć elementy kontenera. Więcej informacji znajdziesz w sekcji o ograniczeniach.
Oto przykład, w którym ustawiono obie te opcje konfiguracji:
<responsive-container
name='sidebar'
breakpoints='{"bp4":400,"bp5":500,"bp6":600,"bp7":700,"bp8":800,"bp9":900,"bp10":1000}'>
</responsive-container>
Podczas grupowania tego kodu pamiętaj, aby używać wykrywania funkcji i dynamicznego pliku import()
do ładowania kodu tylko wtedy, gdy przeglądarka nie obsługuje zapytań dotyczących kontenera.
if (!CSS.supports('container-type: inline-size')) {
import('./path/to/responsive-container.js');
}
Krok 3. Dodaj style zastępcze do CSS
Ostatnim krokiem w tej strategii jest dodanie stylów zastępczych dla przeglądarek, które nie rozpoznają stylów zdefiniowanych w regułach @container
. Aby to zrobić, skopiuj te reguły za pomocą klas punktów przerwania ustawionych w elementach <responsive-container>
.
Kontynuując poprzedni przykład .photo-gallery
, style zastępcze w 2 regułach @container
mogą wyglądać tak:
/* Container query styles for the `MD` breakpoint. */
@container (min-width: 600px) {
.photo-gallery {
grid-template-columns: 1fr 1fr;
}
}
/* Fallback styles for the `MD` breakpoint. */
@supports not (container-type: inline-size) {
:where(responsive-container.MD) .photo-gallery {
grid-template-columns: 1fr 1fr;
}
}
/* Container query styles for the `XL` breakpoint. */
@container (min-width: 1000px) {
.photo-gallery {
grid-template-columns: 1fr 1fr 1fr;
}
}
/* Fallback styles for the `XL` breakpoint. */
@supports not (container-type: inline-size) {
:where(responsive-container.XL) .photo-gallery {
grid-template-columns: 1fr 1fr 1fr;
}
}
W tym kodzie każda reguła @container
zawiera równoważną regułę warunkową odpowiadającą elementowi <responsive-container>
, jeśli istnieje odpowiednia klasa punktu przerwania.
Część selektora pasującego do elementu <responsive-container>
jest umieszczona w funkcjonalnym selektorze pseudoklasy :where(), aby specyficzność selektora kreacji zastępczej odpowiadała specyfice pierwotnego selektora w regule @container
.
Każda reguła zastępcza jest też zawarta w deklaracji @supports
. Chociaż nie jest to niezbędne do działania kreacji zastępczej, oznacza to, że przeglądarka całkowicie ignoruje te reguły, jeśli obsługuje zapytania dotyczące kontenerów, co może ogólnie zwiększyć skuteczność dopasowywania stylów. Pozwala to też narzędziom do tworzenia lub sieci CDN usuwać te deklaracje, jeśli wiedzą, że przeglądarka obsługuje zapytania dotyczące kontenera i nie potrzebuje tych stylów zastępczych.
Główną wadą tej strategii kreacji zastępczych jest konieczność dwukrotnego powtórzenia deklaracji stylu, co jest uciążliwe i podatne na błędy. Jeśli jednak korzystasz z preprocesora CSS, możesz to wyodrębnić i stworzyć połączenie, które wygeneruje zarówno regułę @container
, jak i kod zastępczy. Oto przykład z użyciem Sass:
@use 'sass:map';
$breakpoints: (
'SM': 400px,
'MD': 600px,
'LG': 800px,
'XL': 1000px,
);
@mixin breakpoint($breakpoint) {
@container (min-width: #{map.get($breakpoints, $breakpoint)}) {
@content();
}
@supports not (container-type: inline-size) {
:where(responsive-container.#{$breakpoint}) & {
@content();
}
}
}
Następnie, gdy uzyskasz tę składankę, możesz zmienić oryginalne style komponentu .photo-gallery
w podobny sposób, co całkowicie eliminuje duplikaty:
.photo-gallery {
display: grid;
grid-template-columns: 1fr;
@include breakpoint('MD') {
grid-template-columns: 1fr 1fr;
}
@include breakpoint('XL') {
grid-template-columns: 1fr 1fr 1fr;
}
}
To wszystko.
Podsumowanie
Podsumujmy. Jak zaktualizować kod, by używać teraz zapytań dotyczących kontenerów z kreacją zastępczą w różnych przeglądarkach.
- Komponenty tożsamości, którym chcesz określić styl w odniesieniu do ich kontenera, i zaktualizuj reguły
@media
w ich CSS, tak aby używały reguł@container
. Dodatkowo (jeśli jeszcze tego nie robisz) ujednolicić zestaw nazw punktów przerwania, aby dopasować je do warunków rozmiaru określonych w regułach kontenera. - Dodaj kod JavaScriptu, który jest podstawą niestandardowego elementu
<responsive-container>
, a potem dodaj element<responsive-container>
do wszystkich obszarów treści na stronie, do których chcesz położenie komponentów. - Aby zapewnić obsługę starszych przeglądarek, dodaj do CSS style zastępcze zgodne z klasami punktów przerwania, które są automatycznie dodawane do elementów
<responsive-container>
w kodzie HTML. Najlepiej jest korzystać z kombinacji przedprocesora CSS, by uniknąć konieczności dwukrotnego zapisywania tych samych stylów.
Największym atutem tej strategii jest jednorazowa konfiguracja, ale dodanie do niej nowych komponentów i definiowanie dla nich stylów zależnych od kontenera nie wymaga żadnego dodatkowego wysiłku.
Zobacz, jak to działa
Chyba najlepszym sposobem na zrozumienie, jak te wszystkie etapy współgrają ze sobą, jest prezentacja w praktyce.
Ta wersja demonstracyjna to zaktualizowana wersja witryny utworzonej w 2019 r. (przed pojawieniem się zapytań dotyczących kontenerów), która pokazuje, dlaczego zapytania dotyczące kontenerów są niezbędne do tworzenia rzeczywiście elastycznych bibliotek komponentów.
Ponieważ styl na tej stronie jest już zdefiniowany dla wielu „elastycznych komponentów”, była doskonałym kandydatem do przetestowania tej strategii w prostej witrynie. Jak się okazało, aktualizacja była dość prosta i nie wymagała niemal żadnych zmian w oryginalnych stylach witryny.
Możesz zapoznać się z pełnym demonstracyjnym kodem źródłowym w GitHubie. Aby dowiedzieć się, jak są zdefiniowane style zastępcze, zajrzyj do komponentu CSS komponentu demonstracyjnego. Jeśli chcesz przetestować tylko działanie kreacji zastępczych, możesz skorzystać z wersji demonstracyjnej tylko w przypadku kreacji zastępczych, która obejmuje tylko ten wariant – nawet w przeglądarkach, które obsługują zapytania dotyczące kontenerów.
Ograniczenia i możliwe usprawnienia
Jak wspomnieliśmy na początku tego posta, opisana tu strategia sprawdza się w większości przypadków użycia, które są ważne dla deweloperów podczas sięgania po zapytania dotyczące kontenerów.
Istnieją jednak bardziej zaawansowane przypadki użycia, których ta strategia celowo nie obsługuje:
Jednostki zapytań dotyczących kontenerów
Specyfikacja zapytań dotyczących kontenera określa liczbę nowych jednostek, które są zgodne z rozmiarem kontenera. W niektórych przypadkach większość projektów elastycznych jest potencjalnie przydatna, ale można to zrobić przy użyciu istniejących środków, takich jak użycie procentów czy układów siatki czy elastycznego.
Jeśli jednak musisz korzystać z jednostek zapytań w kontenerach, możesz je łatwo obsługiwać, korzystając z właściwości niestandardowych. Dokładniej rzecz ujmując, definiując niestandardową właściwość dla każdej jednostki używanej w elemencie kontenera:
responsive-container {
--cqw: 1cqw;
--cqh: 1cqh;
}
Jeśli zechcesz uzyskać dostęp do jednostek zapytań kontenera, używaj tych właściwości zamiast samej jednostki:
.photo-gallery {
font-size: calc(10 * var(--cqw));
}
Następnie, aby zapewnić obsługę starszych przeglądarek, ustaw wartości tych właściwości niestandardowych w elemencie kontenera w wywołaniu zwrotnym ResizeObserver
.
class ResponsiveContainer extends HTMLElement {
// ...
updateBreakpoints(contentRect) {
this.style.setProperty('--cqw', `${contentRect.width / 100}px`);
this.style.setProperty('--cqh', `${contentRect.height / 100}px`);
// ...
}
}
Pozwala to uzyskać certyfikat tych wartości, od JavaScriptu po CSS, i wtedy masz pełne możliwości CSS (np. calc()
, min()
, max()
, clamp()
) do manipulowania nimi zgodnie z potrzebami.
Właściwości logiczne i obsługa trybu zapisu
Możesz zauważyć, że w deklaracjach @container
w niektórych przykładach kodu CSS występuje użycie atrybutu inline-size
zamiast width
. Być może zauważysz też nowe jednostki cqi
i cqb
(odpowiednio w przypadku rozmiarów wbudowanych i blokowych). Te nowe funkcje odzwierciedlają przejście CSS na właściwości i wartości logiczne, a nie fizyczne lub kierunkowe.
Niestety interfejsy API takie jak Resize Observer nadal zgłaszają wartości w tabelach width
i height
, więc jeśli Twoje projekty wymagają elastyczności właściwości logicznych, musisz to sprawdzić samodzielnie.
Mimo że można uzyskać tryb pisania za pomocą polecenia takiego jak getComputedStyle()
przekazywanego w elemencie kontenera, jest to płatne, a nieprawidłowo nie jest w stanie wykryć, czy zmienił się tryb pisania.
Z tego względu najlepszym rozwiązaniem jest akceptacja właściwości trybu pisania w elemencie <responsive-container>
, którą właściciel witryny może ustawić (i aktualizować) zgodnie z potrzebami. Aby to zrobić, wykonaj czynności opisane w poprzedniej sekcji, ale w razie potrzeby zamień komponenty width
i height
.
Kontenery zagnieżdżone
Właściwość container-name
pozwala nadać kontenerowi nazwę, do której można się później odwoływać w regule @container
. Kontenery z nazwą są przydatne, jeśli masz kontenery zagnieżdżone w kontenerach i potrzebujesz określonych reguł, aby pasowały tylko do określonych kontenerów (a nie tylko do najbliższego kontenera nadrzędnego).
Opisana tutaj strategia zastępcza korzysta z kombinatora podrzędnego, aby określić styl elementów pasujących do określonych klas punktów przerwania. Ten błąd może wystąpić w przypadku zagnieżdżonych kontenerów, ponieważ do danego komponentu może pasować dowolna liczba klas punktów przerwania z wielu elementów nadrzędnych elementów kontenera.
Na przykład tutaj są 2 elementy <responsive-container>
opakowujące komponent .photo-gallery
, ale kontener zewnętrzny jest większy niż kontener wewnętrzny, więc zostały w nim dodane różne klasy punktów przerwania.
<responsive-container class="SM MD LG">
...
<responsive-container class="SM">
...
<div class="photo-gallery">...</div class="photo-gallery">
</responsive-container>
</responsive-container>
W tym przykładzie klasa MD
i LG
w kontenerze zewnętrznym miałaby wpływ na reguły stylu pasujące do komponentu .photo-gallery
. Nie pasuje to do zachowania zapytań dotyczących kontenera (ponieważ pasują one tylko do kontenera z najbliższym elementem nadrzędnym).
Aby rozwiązać ten problem:
- Aby uniknąć konfliktów, pamiętaj, aby zawsze nazywały się wszystkie kontenery, które zagnieżdżasz, a potem klasy punktów przerwania mają przed sobą odpowiednią nazwę kontenera.
- W selektorach zastępczych zamiast kombinatora podrzędnego użyj kombinatora podrzędnego (co jest nieco bardziej restrykcyjne).
W sekcji zagnieżdżonych kontenerów w witrynie demonstracyjnej znajduje się przykład tego, jak to działa za pomocą nazwanych kontenerów oraz kombinacja sass używana w kodzie do generowania stylów zastępczych dla nazwanych i nienazwanych reguł @container
.
Co z przeglądarkami, które nie obsługują :where()
, elementów niestandardowych ani zmiany rozmiaru obserwatora?
Choć te interfejsy API mogą wydawać się stosunkowo nowe, wszystkie są obsługiwane we wszystkich przeglądarkach od ponad 3 lat i weszły w skład powszechnie dostępnego punktu odniesienia.
Jeśli więc nie masz danych, które wskazują, że znaczna część użytkowników Twojej witryny korzysta z przeglądarek, które nie obsługują żadnej z tych funkcji, nie ma powodu, by nie używać ich bez ograniczeń.
Nawet wtedy najgorsze, co może się zdarzyć w tym przypadku, to użycie kreacji zastępczej nie będzie działać w przypadku niewielkiego odsetka użytkowników. Oznacza to, że zobaczą oni widok domyślny, a nie widok zoptymalizowany pod kątem rozmiaru kontenera.
Funkcjonalność witryny powinna nadal działać. To jest najważniejsze.
Dlaczego nie wystarczy użyć kodu polyfill zapytań kontenera?
Funkcje CSS są często trudne do wypełnienia i zwykle wymagają ponownego zaimplementowania całego parsera CSS przeglądarki i kaskady logiki w JavaScript. W związku z tym autorzy kodu polyfill CSS muszą dokonywać wielu kompromisów, które niemal zawsze wiążą się z wieloma ograniczeniami funkcji i znacznym ograniczeniem wydajności.
Z tego względu zasadniczo odradzamy stosowanie w środowisku produkcyjnym kodu polyfill CSS, w tym tagu container-query-polyfill z Laboratorium Google Chrome, który nie jest już obsługiwany (i służył głównie do celów demonstracyjnych).
Opisana tutaj strategia zastępcza ma mniejsze ograniczenia, wymaga znacznie mniej kodu i będzie znacznie skuteczniejsza niż jakikolwiek inny kod polyfill zapytań kontenera.
Czy trzeba stosować kreacje zastępcze w starszych przeglądarkach?
Jeśli obawiasz się o którekolwiek z opisanych tu ograniczeń, prawdopodobnie warto zastanowić się, czy w ogóle trzeba wdrożyć opcję zastępczą. W końcu najłatwiejszym sposobem uniknięcia tych ograniczeń jest używanie danej funkcji bez żadnych wartości zastępczych. Szczerze mówiąc, w wielu przypadkach może to być całkowicie uzasadniony wybór.
Według strony caniuse.com zapytania dotyczące kontenerów są obsługiwane przez 90% użytkowników internetu z całego świata. Dla wielu osób czytających tego posta ta liczba jest prawdopodobnie znacznie większa niż w przypadku tych użytkowników. Pamiętaj, że większość użytkowników będzie widzieć w interfejsie Twoją wersję zapytań o kontenery. Dla 10% użytkowników, którzy nie mają dostępu do tych treści, nie oznacza to, że nie będą mieli żadnych negatywnych skutków. Gdy będziesz wdrażać tę strategię, w najgorszym razie zobaczą oni wersję domyślną lub „mobilne”. układ dla niektórych komponentów, co nie oznacza końca świata.
Podczas kompromisów lepiej jest optymalizować kampanie pod kątem większości użytkowników – zamiast utożsamiać się z modelem o najniższym wspólnym mianowniku, który zapewnia wszystkim użytkownikom spójne, ale mniej trafne wrażenia.
Zanim więc uznasz, że nie można używać zapytań dotyczących kontenerów ze względu na brak obsługi przeglądarek, poświęćmy czas na zastanowienie się, jak będą one wyglądać po ich wdrożeniu. Rekompensata może być opłacalna, nawet bez żadnych rozwiązań alternatywnych.
Plany na przyszłość
Mamy nadzieję, że ten post przekonał Cię, że można używać zapytań dotyczących kontenerów w środowisku produkcyjnym i że nie trzeba będzie czekać latami, aż wszystkie nieobsługujące przeglądarki znikną.
Opisana tu strategia wymaga pewnego nakładu pracy, ale powinna być na tyle prosta i prosta, że większość użytkowników może ją wdrożyć w swoich witrynach. Mimo to istnieje niewątpliwość, aby jeszcze bardziej ułatwić jego wdrożenie. Jednym z przykładów jest połączenie wielu odległych części w jeden komponent zoptymalizowany pod kątem określonej platformy lub stosu, który zajmuje się całą pracą nad klejem. Jeśli stworzysz taki element, daj nam znać, a my pomożemy Ci go wypromować.
Poza zapytaniami dotyczącymi kontenerów jest mnóstwo niesamowitych funkcji CSS i interfejsu, które obecnie współdziałają ze wszystkimi głównymi wyszukiwarkami. Zastanówmy się teraz, jak możemy teraz wykorzystać te funkcje, aby nasi użytkownicy mogli z nich korzystać.
Aktualizacja (25 lipca 2024 r.): pierwsza aktualizacja wskazówek w „Kroku 1”. sugerowano, że zapytania o media i kontenery mogą używać warunków tego samego rozmiaru. Często jest to prawdą, ale nie zawsze (jak słusznie wskazujemy niektóre powody). Zaktualizowane wytyczne zawierają teraz wyjaśnienie i przykładowe przypadki, w których konieczna może być zmiana warunków dotyczących rozmiaru.
Aktualizacja (2 lipca 2024 r.): początkowo wszystkie przykłady kodu CSS używały Sass (aby zachować spójność z ostateczną rekomendacją). Na podstawie opinii czytelników postanowiliśmy zaktualizować kilka pierwszych arkuszy CSS do zwykłego kodu CSS, a platforma Sass jest używana tylko w przykładach kodu, które wymagają stosowania składanek.