@container
Nakłada style zależnie od rozmiaru kontenera, a nie całego okna. Komponent dopasowuje się do miejsca, które dostał w układzie.
Przykład
#.slot {
container-type: inline-size;
}
.card {
display: grid;
gap: 10px;
}
@container (width >= 240px) {
.card {
grid-template-columns: 96px 1fr;
align-items: center;
}
}<style>
.layout { display: flex; flex-wrap: wrap; align-items: start; gap: 10px; }
.narrow { flex: 0 0 180px; }
.wide { flex: 1 1 260px; }
.card { padding: 10px; border: 1px solid #27272a; border-radius: 12px; background: #18181b; }
.thumb { height: 60px; border-radius: 8px; background: linear-gradient(135deg, #7c3aed, #0ea5e9); }
.card p { margin: 2px 0 0; color: #a1a1aa; font-size: 13px; }
</style>
<div class="layout">
<div class="slot narrow">
<article class="card"><div class="thumb"></div><div><strong>Flexbox</strong><p>Moduł 7 · 9 lekcji</p></div></article>
</div>
<div class="slot wide">
<article class="card"><div class="thumb"></div><div><strong>Flexbox</strong><p>Moduł 7 · 9 lekcji</p></div></article>
</div>
</div>Obie karty mają ten sam HTML i te same style. Lewa kolumna ma 180 px, więc karta jest pionowa, a prawa ma ponad 240 px i karta układa się poziomo. Na telefonie prawa kolumna spada pod lewą, ale nadal jest dość szeroka na układ poziomy.
Definicja i zastosowanie
#Reguła @container działa jak @media, ale zamiast szerokości okna sprawdza rozmiar wybranego przodka, czyli kontenera. Dzięki temu ta sama karta może być pionowa w wąskiej kolumnie bocznej i pozioma w szerokiej treści głównej. Komponent przenosisz w inne miejsce strony, a on sam dopasowuje się do dostępnej przestrzeni.
Najpierw trzeba wskazać kontener. Właściwość container-type: inline-size każe przeglądarce śledzić jego szerokość, a container-type: size także wysokość. Opcjonalna container-name nadaje mu nazwę, a skrót container: karta / inline-size ustawia nazwę i typ naraz. Zapytanie @container (width >= 400px) trafia do najbliższego przodka, który jest kontenerem, a @container karta (width >= 400px) do najbliższego o tej nazwie.
Reguły z @container działają tylko na potomków kontenera, nigdy na niego samego, bo rozmiar kontenera nie może zależeć od stylów, które od tego rozmiaru zależą. Z tego samego powodu szerokość kontenera przestaje wynikać z treści: element dopasowany do zawartości, np. inline-block albo float, może się skurczyć do zera. Przy container-type: size musisz też sam podać wysokość.
W środku kontenera działają jednostki zapytań: cqi to 1% szerokości kontenera, cqb 1% jego wysokości, a cqmin i cqmax odpowiednio mniejszy i większy z tych wymiarów. Nagłówek z font-size: clamp(1rem, 6cqi, 2rem) rośnie razem z kartą, a nie z oknem.
Składnia
#.rodzic { container-type: inline-size; container-name: <nazwa>; }
@container <nazwa>? (<warunek rozmiaru>) {
selektor { właściwość: wartość; }
}Warianty zapytań
#kontener ma co najmniej 240 px
Gdy kontener ma co najmniej 240 px szerokości, obrazek staje obok tekstu. Przeciągnij prawy dolny róg ramki w lewo, a karta wróci do układu pionowego.kontener węższy niż 200 px
W bardzo wąskim kontenerze znika opis, a tytuł się zmniejsza. Zwęż ramkę poniżej 200 px, przeciągając jej prawy dolny róg, żeby to zobaczyć.najbliższy kontener o nazwie lesson
Zapytanie z nazwą pomija kontenery o innych nazwach i szuka najbliższego przodka o nazwielesson. Przydaje się, gdy kontenery są zagnieżdżone, a Ty chcesz pytać o konkretny, np. o kolumnę strony.1% szerokości kontenera
Jednostka zapytań o kontener. Tytuł ma 7% szerokości kontenera, więc rośnie i maleje razem z ramką, aclamp()trzyma go w rozsądnych granicach. Przeciągnij róg ramki i obserwuj napis.
Warianty zapytań w praktyce
#(width >= 240px)
@container (width >= 240px) {
.card {
grid-template-columns: 72px 1fr;
align-items: center;
}
}(width < 200px)
@container (width < 200px) {
.meta { display: none; }
.title { font-size: 14px; }
}lesson (width >= 240px)
lesson. Przydaje się, gdy kontenery są zagnieżdżone, a Ty chcesz pytać o konkretny, np. o kolumnę strony..demo { container-name: lesson; }
@container lesson (width >= 240px) {
.card {
grid-template-columns: 72px 1fr;
align-items: center;
background: #1e1b4b;
}
}cqi
clamp() trzyma go w rozsądnych granicach. Przeciągnij róg ramki i obserwuj napis..title {
font-size: clamp(14px, 7cqi, 26px);
}Więcej przykładów
#.hero {
container: hero / inline-size;
}
.hero h2 {
font-size: clamp(1.1rem, 7cqi, 2.2rem);
}
@container hero (width < 320px) {
.hero .actions {
flex-direction: column;
}
}<style>
.hero { resize: horizontal; overflow: hidden; width: 100%; min-width: 180px; max-width: 100%; padding: 16px; border: 2px dashed #7c3aed; border-radius: 14px; background: #18181b; }
.hero h2 { margin: 0 0 12px; line-height: 1.15; }
.actions { display: flex; gap: 8px; }
.actions button { padding: 8px 14px; border: 0; border-radius: 8px; background: #7c3aed; color: #fff; font: inherit; }
.actions button + button { background: #3f3f46; }
</style>
<section class="hero">
<h2>Zacznij przygodę z CSS</h2>
<div class="actions"><button type="button">Start</button><button type="button">Program kursu</button></div>
</section>Przeciągnij prawy dolny róg ramki. Nagłówek skaluje się jednostką cqi, a gdy kontener zrobi się węższy niż 320 px, przyciski ustawią się jeden pod drugim.
Obsługa przeglądarek
#Szeroko dostępne · od 2023 roku
Działa we wszystkich nowoczesnych przeglądarkach, także na telefonach. Możesz używać bez obaw.
- Chrome
- Edge
- Firefox
- Safari
Dobre praktyki
#- Kontenerem rób element, którego szerokość wynika z układu: kolumnę siatki, sekcję albo slot na komponent. Samej karty zwykle nie oznaczaj jako kontenera, tylko jej opakowanie.
- Reguła
@containerstylizuje tylko potomków. Jeśli chcesz zmienić wygląd samego kontenera, dodaj w środku element opakowujący i to jemu nadaj style. - Podział ról jest prosty:
@mediado decyzji o całej stronie, np. układu kolumn i nawigacji, a@containerdo komponentów używanych w różnych miejscach.
Powiązane hasła
#- @mediaWłącza style tylko wtedy, gdy urządzenie spełnia warunek: ma odpowiednią szerokość okna, ciemny motyw, mysz albo drukuje stronę.
- JednostkiPrzegląd jednostek długości w CSS: od stałych pikseli, przez em i rem zależne od czcionki, po jednostki okna, kontenera i siatki.
- clamp()Trzyma wartość w przedziale od minimum do maksimum, a pomiędzy pozwala jej płynnie rosnąć. Podstawa płynnej typografii.
- @supportsWłącza style tylko w przeglądarkach, które obsługują daną właściwość, wartość albo selektor. Pozwala bezpiecznie korzystać z nowości.
- grid-template-columnsDefiniuje kolumny siatki: ich liczbę i szerokości.
- container-typeZamienia element w kontener, o którego rozmiar mogą pytać reguły @container. Obejmuje też container-name i skrót container.
Widzisz błąd albo brakuje przykładu? Napisz do nas.