Каждый релиз браузера Chromium — это заметное событие для фронтенд-сообщества. Но если минорные версии часто ограничиваются устранением мелких регрессий и внутренними оптимизациями компилятора V8, то вышедший Chrome 156 приносит сразу несколько долгожданных стандартов, которые кардинально упрощают жизнь верстальщикам и дизайнерам интерфейсов.
Главная звезда релиза — официальная имплементация математической функции random() из черновика спецификации CSS Values and Units Module Level 5. То, ради чего десятилетиями приходилось генерировать inline-стили на JavaScript или компилировать тысячи строк вспомогательного кода через SCSS-генераторы, теперь работает на уровне движка Blink прямо в таблицах стилей!
Давай подробно разберем все ключевые новшества Chrome 156, посмотрим на синтаксис и выясним, как они изменят наш подход к современной веб-верстке.
Нативная функция random() в CSS: живой хаос без JS
До сегодняшнего дня добавление легкого «живого несовершенства» в веб-интерфейс было настоящей головной болью. Представь типичную дизайнерскую задачу: ты верстаешь россыпь стикеров на интерактивной доске, частицы конфетти или сетку карточек в блоге, и хочешь, чтобы каждая карточка была слегка повернута на случайный угол от -4 до +4 градусов, а цвет фона слегка варьировался.
Раньше приходилось либо писать JavaScript-скрипт, который обходил DOM и навешивал inline-переменные:
card.style.setProperty('--angle', Math.random() * 8 - 4 + 'deg'),
либо генерировать через Sass-циклы тридцать классов-модификаторов .card--1, .card--2 с зашитыми значениями. Скрипт засорял разметку, ломал серверный рендеринг (SSR) и приводил к раздражающим скачкам при гидратации клиента. А SCSS-подход раздувал итоговый файл стилей на десятки килобайт.
В Chrome 156 функция random() решает эту задачу элегантно и декларативно:
/* Базовый синтаксис: случайное значение в заданном диапазоне */
.sticker {
/* Случайный угол от -4deg до 4deg с шагом дискретизации 0.5deg */
transform: rotate(random(-4deg, 4deg, by 0.5deg));
/* Случайная длительность анимации покачивания */
animation-duration: random(2s, 5s);
/* Случайный оттенок в современном цветовом пространстве Oklch */
background-color: oklch(0.85 0.12 random(0, 360));
}
/* Эффект праздничного конфетти на чистом CSS */
.confetti-particle {
left: random(0vw, 100vw, by 5vw);
animation-duration: random(1.5s, 4s);
background-color: hsl(random(0, 360), 85%, 60%);
}
Как устроена модель кэширования: защита от вечных перерисовок
Первый логичный вопрос любого вдумчивого инженера: «Если в стилях написано random(), не начнет ли браузер судорожно дергать генератор псевдослучайных чисел на каждый кадр анимации или при наведении мыши (hover)? Не приведет ли это к бесконечному циклу Repaint/Reflow?».
Разработчики спецификации W3C и инженеры движка Blink предусмотрели эту опасность:
- Вычисление на фазе Style Cascade: случайное значение генерируется один раз в момент применения каскада стилей к конкретному элементу DOM.
- Привязка к идентификаторам (Seed Keys): движок поддерживает специальный первый аргумент — идентификатор сида. Если передать кастомное имя или атрибут элемента, значение намертво фиксируется за данным ключом:
/* Использование пользовательского идентификатора для детерминированной случайности */
.gallery-card {
--seed: attr(data-id type(<custom-ident>));
width: random(--seed, 280px, 340px);
transform: rotate(random(--seed, -3deg, 3deg));
}
Даже если пользователь многократно скроллит страницу, меняет размеры окна или вызывает пересчет соседних блоков, карточка с data-id="card-42" сохранит ровно тот угол и ширину, которые были вычислены при ее первом появлении.
Прогрессивное улучшение (Progressive Enhancement)
Поскольку Chrome 156 — первый браузер с нативной поддержкой random(), а движки WebKit (Safari) и Gecko (Firefox) еще работают над внедрением, в продакшене обязательно используй директиву @supports:
.sticker {
transform: rotate(0deg); /* Базовое безопасное значение по умолчанию */
}
@supports (transform: rotate(random(0deg, 10deg))) {
.sticker {
transform: rotate(random(-4deg, 4deg, by 0.5deg));
}
}
Псевдокласс :navigation-source: контекстные переходы
Второе фундаментальное нововведение релиза — псевдокласс :navigation-source.

До сих пор веб-страница была слепа к тому, каким образом пользователь на нее попал. Перешел ли он по прямой ссылке из поисковой выдачи? Нажал ли кнопку «Назад» в панели инструментов браузера? Отправил ли форму методом POST? Или просто нажал комбинацию Ctrl+R для перезагрузки?
Теперь контекст навигации доступен непосредственно в селекторах CSS, открывая фантастические возможности для плавных переходов:
/* Анимации навигации в связке с View Transitions */
@media (prefers-reduced-motion: no-preference) {
/* Пользователь вернулся назад через историю (BFCache / Back-Forward) */
:root:navigation-source(traverse) .page-container {
animation: slideInFromLeft 0.35s ease-out;
}
/* Обычный переход вперед по ссылке (Push navigation) */
:root:navigation-source(push) .page-container {
animation: slideInFromRight 0.35s ease-out;
}
/* Страницу принудительно обновили клавишей F5 или через reload */
:root:navigation-source(reload) .status-toast {
display: block;
animation: fadeInOut 3s forwards;
}
}
Селектор поддерживает значения push, replace, reload и traverse. Это позволяет избавиться от хрупких JavaScript-перехватчиков истории браузера и настраивать направление выезда экранов исключительно средствами стилей.
О том, как эволюционирует веб-платформа и средства плавной прокрутки, мы также рассказывали в обзоре кастомизации скролла в Chrome 154 и новшеств Chrome 155.
Оптимизация кинетической прокрутки в scroll-snap
Свойство scroll-snap-type стало стандартом для галерей и полноэкранных секций. Но на сенсорных экранах мобильных устройств при быстром и резком смахивании пальцем (инерционный кинетический скролл) пользователи регулярно сталкивались с неприятной проблемой: контейнер пролетал мимо целевого элемента, судорожно отскакивал назад или застревал ровно посередине между двумя слайдами.
В Chrome 156 математика инерционной прокрутки была переписана:
.story-carousel {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
/* Жесткая фиксация в Chrome 156: запрет пролета нескольких слайдов за один свайп */
scroll-snap-stop: always;
}
.story-card {
flex: 0 0 100vw;
scroll-snap-align: center;
}
Браузер теперь непрерывно рассчитывает вектор торможения и аккуратно «магнитит» ближайший слайд даже при самом резком движении руки, делая веб-карусели неотличимыми по отзывчивости от нативных экранов iOS и Android.
Что еще появилось в Chrome DevTools?
- Инспектор диапазонов Scroll-driven Animations: во вкладке Elements появилась интерактивная шкала времени. Перетаскивая ползунок виртуального скролла, можно в миллиметрах видеть, как интерполируются свойства при достижении меток
entry 0%,cover 50%иexit 100%. - Подсветка мертвого кода стилей в реальном времени: панель Styles теперь динамически маркирует серым цветом те селекторы, которые формально совпали с элементом, но были полностью перекрыты более специфичными правилами или не оказали никакого визуального эффекта на рендеринг.
Chrome 156 доказывает: современный CSS становится все более самостоятельным, мощным и умным языком программирования интерфейсов.
