CSS следующего поколения: @container

Spread the love

Новое свойство @container дает нам возможность стилизовать элементы в зависимости от размера их родительского контейнера.

Вы можете думать об этом как о медиа-запросе (@media), но вместо того, чтобы полагаться на область просмотра (viewport) для настройки стилей, эти стили теперь могу зависеть от родительский контейнер целевого элемента.

Контейнерные запросы (@container) станут самым большим изменением в веб-стиле со времен CSS3, изменив наше представление о том, что означает «отзывчивый дизайн» (responsive design).

Область просмотра (viewport) и пользовательский агент больше не будут единственными целями, которые нам нужны для создания адаптивного макета и стилей пользовательского интерфейса. С контейнерными запросами элементы смогут нацеливаться на своих родителей и соответствующим образом применять собственные стили. Это означает, что один и тот же элемент, который находится на боковой панели (к примеру), в теле или на базовой панели, может выглядеть совершенно по-разному в зависимости от доступного размера.

@container в действие

В этом примере я использую две карточки в родительском элементе со следующей разметкой:

<div class="card-container">
  <div class="card">
    <figure> ... </figure>
    <div>
      <div class="meta">
        <h2>...</h2>
        <span class="time">...</span>
      </div>
      <div class="notes">
        <p class="desc">...</p>
        <div class="links">...</div>
      </div>
      <button>...</button>
    </div>
  </div>
</div>

Затем я устанавливаю включение (свойство container-type ) для родителя, у которого я буду запрашивать стили контейнера (.card-container). Я также устанавливаю относительный макет сетки для родителя .card-container, поэтому его inline-size будет меняться в зависимости от этой сетки. Вот что я запрашиваю с помощью @container:

.card-container {
  container-type: inline-size;
  width: 100%;
}

Теперь я могу использовать контейнерный запрос для настройки стилей! Это очень похоже на то, как вы устанавливаете стили, используя медиа запросы на основе ширины , используя  max-width для установки стилей, когда элемент меньше определенного размера, и min-width, когда он больше.

/* when the parent container is smaller than 850px, 
remove the .links div and decrease the font size on 
the episode time marker */

@container (max-width: 850px) {
  .links {
    display: none;
  }

  .time {
    font-size: 1.25rem;
  }

  /* ... */
}

/* when the parent container is smaller than 650px, 
decrease the .card element's grid gap to 1rem */

@container (max-width: 650px) {
  .card {
    gap: 1rem;
  }

  /* ... */
}

Контейнерные запросы + медиа-запросы

Одной из лучших функций контейнерных запросов является возможность отделять микро макеты от макро макетов. Вы можете стилизовать отдельные элементы с помощью контейнерных запросов, создавая детализированные микро-макеты, а также стилизовать целые макеты страниц с помощью медиа-запросов, макро макетов. Это создает новый уровень контроля, позволяющий создавать еще более отзывчивые интерфейсы.

Вот еще один пример, демонстрирующий возможности использования медиа-запросов для макро макетов (пример календаря, переходящего с одной панели на несколько панелей) и микро-макета (т. е. макета/размера даты и полей события/сдвига размера) для создания прекрасной коллекции запросов.

Контейнерные запросы + CSS Grid

Один из моих любимых способов увидеть влияние контейнерных запросов — это посмотреть, как они работают в grid. Возьмем следующий пример пользовательского интерфейса для торговли растениями:

На этом сайте вообще не используются медиа-запросы. Вместо этого мы используем контейнерные запросы только вместе с CSS grid для отображения компонента карты покупок в разных представлениях.

В сетке товара макет создается с помощью grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));. Это создает макет, который говорит cards занимать доступное дробное пространство, пока они не достигнут размера 230 пикселей, а затем перетекают в следующую строку. Ознакомьтесь с другими трюками с сеткой на 1linelayouts.com.

Затем у нас есть контейнерный запрос, который настраивает карточки так, чтобы они принимали вертикальный блочный макет, когда они имеют ширину менее 350 пикселей, и переходит к горизонтальному встроенному макету, применяя display: flex (который по умолчанию имеет inline flow).

@container (min-width: 350px) {
  .product-container {
    padding: 0.5rem 0 0;
    display: flex;
  }

  /* ... */
}

Это означает, что каждая карточка имеет собственный адаптивный стиль. Это еще один пример того, как вы можете создать макро-макет с сеткой товаров и микро-макет с карточками товаров. Довольно круто!

Применение

Чтобы использовать @container, сначала необходимо создать родительский элемент, содержащий контейнер. Для этого вам нужно установить в родительском элементе значение contain: layout inline-size. Вы можете использовать inline-size, поскольку в настоящее время мы можем применять контейнерные запросы только к inline. Это предотвратит разрыв вашего макета в блочном направлении.

Настройка contain: layout inline-size создает новый содержащий блок и новый блочный контекст форматирования, позволяя браузеру отделить его от остальной части макета. Теперь мы можем строить запросы!

Ограничения

В настоящее время вы не можете использовать контейнерные запросы на основе высоты, используя только ось блока. Чтобы дочерние элементы сетки работали с @container, вам нужно добавить элемент-оболочку. Несмотря на это, добавление оболочки позволяет получить желаемые эффекты.

Попробуйте

Вы можете поэкспериментировать со свойством @container в Chromium уже сегодня, перейдя по адресу: chrome://flags в Chrome Canary и включив флаг #experimental-container-queries.

Перевод оригинальной статьи: Next Gen CSS: @container

Была ли вам полезна эта статья?
[1 / 5]

Spread the love
Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments