contain — CSS Containment
CSS
contain— свойство, указывающее браузеру, что элемент и его поддерево изолированы от остального документа в части layout, paint или style, что позволяет браузеру оптимизировать рендеринг, ограничивая scope пересчётов.
Зачем нужно
Без containment изменение одного элемента может вызвать layout/paint для всей страницы. contain говорит браузеру: "внутри этого элемента всё изолировано" — и браузер может пропустить проверку влияния на весь документ. Критично для виджетов, карточек, длинных списков.
Где используется
- Компоненты в длинных списках (карточки товаров, строки таблицы)
- Виджеты и independent UI блоки (sidebar, chat, карта)
- Анимированные элементы
content-visibility: autoавтоматически добавляет containment
Основной контент
Значения contain
.card {
contain: layout; /* layout: изменения внутри не влияют на layout снаружи */
contain: paint; /* paint: содержимое не рисуется за пределами элемента */
contain: style; /* style: счётчики CSS не протекают наружу */
contain: size; /* size: размер элемента не зависит от содержимого */
contain: content; /* content = layout + paint (наиболее часто используемое) */
contain: strict; /* strict = layout + paint + size (самое строгое) */
}
Практическое применение
/* Карточки в grid — идеальный кандидат */
.product-card {
contain: content;
/* Браузер знает: изменение внутри карточки не влияет на соседей */
/* Позволяет параллельно обрабатывать несколько карточек */
}
/* Виджет с анимацией */
.animated-widget {
contain: layout paint;
/* paint: анимация не создаёт layer для соседних элементов */
}
/* Фиксированного размера блоки */
.avatar {
width: 48px;
height: 48px;
contain: strict;
/* Браузер может кешировать размер и пропустить relayout */
}
/* Sidebar с независимым контентом */
.sidebar {
contain: layout;
/* Изменения в sidebar не вызывают layout в main content */
}
contain vs will-change
/* contain — говорит: "это изолировано от остального" */
.card { contain: layout; }
/* will-change — говорит: "это скоро изменится" */
.card { will-change: transform; }
/* Разные цели:
contain → оптимизация layout/paint scope
will-change → создание compositor layer, GPU-ускорение */
Измерение эффекта
// Перед/после contain: измеряем Layout Duration в Performance API
performance.mark('layout-start');
// Динамическое добавление элементов в список
for (let i = 0; i < 100; i++) {
const card = createCard(data[i]);
list.appendChild(card);
}
performance.mark('layout-end');
performance.measure('layout', 'layout-start', 'layout-end');
// С contain: layout значительно быстрее
CSS Containment Level 2 — container queries
/* container: создаёт containment context для container queries */
.card-wrapper {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 300px) {
.card-image { display: block; }
}
Частые ошибки
contain: strictна элементе с неизвестным размером — height: 0 (size containment)contain: paintна элементе сoverflow: visibleпотомками — они обрезаются- Применение к inline элементам — containment требует block/inline-block/flex/grid
- Использование
containвместоcontent-visibility: autoдля off-screen элементов
Связанные темы
- _MOC Производительность
- content-visibility -- lazy rendering
- will-change -- подсказка браузеру
- Как браузер рендерит страницу