На протяжении многих лет разработка интерфейсов во фронтенде была неразрывно связана со сборочными инструментами. Чтобы использовать вложенные селекторы, рассчитывать цвета или верстать сетки, инженеры подключали препроцессоры Sass или Less, настраивали PostCSS и усложняли конфигурацию сборщиков.
Однако веб-платформа совершила большой скачок. Благодаря инициативе Baseline ключевые возможности языка стилей получили статус широкой доступности (Widely Available) во всех независимых браузерных движках — Blink, Gecko и WebKit. Сегодня браузеры из коробки выполняют то, для чего раньше требовались внешние npm-пакеты.
Отказ от сборки стилей ускоряет разработку, упрощает CI/CD и позволяет отдавать чистый CSS напрямую через протоколы HTTP/2 и HTTP/3.
Нативная вложенность, родительский селектор и палитры без Sass
Главным поводом использовать препроцессоры была вложенность селекторов. Спецификация CSS Nesting позволяет браузерам нативно разбирать иерархические правила через амперсанд & и прямые вложенные теги.
Вместе с псевдоклассом :has() («родительский селектор») и функцией color-mix() необходимость в Sass отпадает даже при верстке интерактивных компонентов:
/* Базовый компонент карточки с нативной вложенностью и динамическим цветом */
.product-card {
--theme-color: #3b82f6;
padding: 1.5rem;
border-radius: 12px;
background-color: #ffffff;
border: 1px solid color-mix(in oklch, var(--theme-color) 25%, #e2e8f0);
transition: border-color 0.2s ease, box-shadow 0.2s ease;
/* Нативная вложенность селекторов */
& .card-title {
font-size: 1.25rem;
font-weight: 600;
color: #1e293b;
}
/* Реакция на наведение курсора без дублирования родителя */
&:hover {
border-color: var(--theme-color);
box-shadow: 0 4px 12px color-mix(in srgb, var(--theme-color) 15%, transparent);
}
/* Стилизация родительской карточки при активном чекбоксе */
&:has(input[type="checkbox"]:checked) {
border-color: #10b981;
background-color: color-mix(in srgb, #10b981 5%, #ffffff);
}
}
Функция color-mix() производит расчет оттенков прямо в браузере в перцептивно точных пространствах цвета (oklch), заменяя вспомогательные JS-скрипты и функции вроде lighten() и darken().
Изоляция стилей через @scope и адаптивность контейнеров
Второй пласт утилит, от которых можно отказаться, — это инструменты изоляции стилей и скрипты отслеживания ресайза ResizeObserver.
Директива @scope изолирует каскад стилей внутри DOM-узла с возможностью задать нижнюю границу (donut scope), а контейнерные запросы @container адаптируют блок под ширину прямого предка:
/* Ограничение области видимости компонента галереи */
@scope (.media-gallery) to (.media-content) {
/* Стили действуют только внутри галереи, не протекая во внутренний контент */
.gallery-item {
aspect-ratio: 16 / 9;
border-radius: 8px;
overflow: hidden;
}
}
/* Контейнерная адаптивность карточки независимо от размера экрана */
.card-container {
container-type: inline-size;
}
@container (min-width: 450px) {
.product-card {
display: grid;
grid-template-columns: 120px 1fr;
gap: 1rem;
}
}
Дополнительные возможности современной платформы
Помимо вложенности и контейнерных запросов, стандарт закрывает еще ряд исторических потребностей верстки:
- Subgrid (
grid-template-rows: subgrid): выравнивает элементы внутри разных карточек по общей базовой сетке родителя. - Scroll-driven animations (
animation-timeline: scroll()): плавные анимации прогресса скролла без JS-кода и без событийwindow.onscroll. - Единицы
dvhиsvh: устраняют скачки верстки на смартфонах при скрытии адресной строки браузера. - Директива
@starting-style: обеспечивает плавную анимацию появления элементов при первой вставке в DOM. - Слои каскада (
@layer): разделяют приоритеты стилей (сброс, компоненты, утилиты) без битвы за!important.
Нативный CSS полностью берет на себя стили, адаптивность и анимации. Шаг сборки в продакшене оправдан только для минификации кода и объединения нескольких файлов в единый бандл для оптимизации сети.
Использование современных стандартов CSS делает кодовую базу чище и повышает отзывчивость интерфейса за счет работы в потоке композитора браузера.
