Усі ми чудово знайомі з media queries — способом змінювати певні стилі в залежності від ширини вʼюпорту. Ще з 2001 року ми мали можливість визначати стилі для різних типів медіа, правда, без звичної на сьогодні гнучкості: просто screen чи print.
Але вже з 2002 року розпочалася робота над Media Queries Level 3, і підтримка так званих брейкпоінтів зʼявилася спочатку в Opera 7 2003 року, а трошки згодом її підхопили Safari 3, Firefox 3 та Chrome 1.
Проривом у використанні цього підходу можна вважати статтю Ітана Маркотта Responsive Web Design, що вийшла 2010 року та закріпила термін responsive design як один з головних підходів до побудови інтерфейсів.
Але очевидно, що цей підхід з часом усе більше й більше обмежував розробників. Що, якщо ми маємо одну ширину екрану, але той самий віджет на одних сторінках може займати ширину однієї колонки, а на інших — дві чи три?
Частково, звичайно, це можна вирішити використанням такого собі fluid layout — з використанням тих же flex, коли елементи можна розташувати в адаптивний потік, який сам розташовує їх в залежності ширини.
Але така флюїдність також має певні обмеження, і одна з них — відсутність точного контролю зі сторони розробника.
Ідея container query зародилася ще 2009 року, але тривалий час перебувала лише ідеєю, не в останню чергу через технічні обмеження того часу. Адже це вимагало б постійної перевірки стану контейнерів та їхніх нащадків, що могло також призводити до нескінченних циклів. Тому роботу відклали майже на десятиліття, і лише 2018 року почалися перші цікаві досліди Google з ідеєю "Element Queries".
Це призвело до компромісної ідеї: до специфікації вводиться поняття CSS Containment, яке дозволяє обмежити вплив елемента на layout і тим самим зробити container queries можливими. І вже 2021 року в Chrome Canary зʼявляється перша підтримка
@container.Подальше прийняття відбулося фактично в два етапи: спочатку у червні 2022 року Chrome та Edge 105 впроваджують повну підтримку фічі (з очевидних причин ми якось пропустили цю новину), а згодом до них приєднуються Safari 16 та Firefox 110.
Якщо коротко, то за допомогою container query ми можемо визначати стилі для нащадків контейнера в залежності від його розмірів. Що цікаво, не лише від ширини, а й від висоти. Синтаксис простий, мінімально ми задаємо контейнеру його тип:
.card {
container-type: inline-size;
}А в запиті реагуємо на задані умови:
@container (min-width: 400px) {
.card-content { display: grid; }
}Ба більше, ми можемо іменувати контейнери, і в такий спосіб точніше визначати стилі, наприклад, коли ми працюємо з елементом, який може бути вкладеним в два чи більше контейнерів.
Такий підхід дозволяє робити дійсно ізольовані UI-компоненти, і не переживати через те, що макет десь зламається, адже ми обмежуємось контекстом саме контейнеру, а не усієї сторінки загалом. В такий спосіб забезпечується більша гнучкість UI та збільшується кількість сценаріїв використання компоненту, які ми можемо дійсно передбачити.
Що почитати:
📖 MDN: @container
📖 MDN: container-type
📖 MDN: container-name
Що почитати душнілам:
📖 CSS Containment Module Level 3 (W3C Draft)
@babichdev