
Начну с того, что произвело на меня самое сильное впечатление — с позиционирования относительно якоря, или anchor positioning. Раньше, чтобы подсказка или выпадающее меню корректно появлялись рядом с кнопкой и при этом не вылезали за край экрана, приходилось измерять положение элемента, вычислять доступное пространство, а затем на лету менять сторону появления блока. Теперь браузер делает это сам: элементу присваивается имя якоря, а зависимый блок просто указывает, к какой стороне якоря он крепится, и с какой стороны разворачивается, если места не хватает. Выглядит это примерно так:
.trigger { anchor-name: --menu-button; } .dropdown { position: absolute; position-anchor: --menu-button; top: anchor(bottom); left: anchor(left); position-try-fallbacks: flip-block; }
Здесь нет ни одной строчки скрипта, а логика получилась ровно такой, какой её представляешь в голове, когда рисуешь макет на бумаге. Есть, правда, оговорка: поддержка ещё неравномерная, первым эту возможность реализовал движок на основе Chromium, и на момент написания этого текста разумно закладывать запасной вариант поведения для тех браузеров, которые пока не подтянулись.
Второе, что не может не радовать — это анимации, управляемые прокруткой страницы. Идея простая и в то же время долгожданная: анимация привязывается не ко времени, а к позиции скролла или к тому, насколько элемент виден во вьюпорте. Раньше подобные эффекты — постепенное проявление текста при подъезде к нему, плавный переход изображения из чёрно-белого в цветное, параллакс-смещение блоков — собирались через обработчики событий скролла, которые постоянно дёргали браузер и заметно били по производительности. Теперь всё это описывается декларативно через свойства для временной шкалы анимации, и браузер сам синхронизирует кадры с прокруткой, без единого лишнего пересчёта на стороне JavaScript. Ощущение, что сайт стал живым, но при этом не потерял в отзывчивости — а ведь именно баланс между красотой и производительностью всегда был самым слабым местом подобных эффектов.
Отдельного упоминания заслуживает механизм переходов между состояниями страницы — view transitions. Раньше смена одного экрана одностраничного приложения на другой либо происходила рывком, либо требовала отдельной анимационной библиотеки, которая клонировала DOM, накладывала слои и синхронизировала их появление и исчезновение. Сейчас достаточно обернуть смену состояния в соответствующий вызов, и браузер сам сделает плавный переход, снимая своеобразный снимок «до» и «после» и интерполируя между ними. Что особенно приятно — это работает не только внутри одной страницы, но постепенно приходит и к переходам между полноценными документами, то есть между разными страницами классического многостраничного сайта. Раньше такой эффект ассоциировался исключительно с мобильными приложениями, а теперь превращается в обычный приём веб-разработки.
Нельзя обойти вниманием и псевдокласс :has, который тихо, без лишнего шума, изменил сам подход к написанию селекторов. Долгие годы CSS не умел «смотреть» на потомков и реагировать на их состояние — то есть нельзя было стилизовать родителя в зависимости от того, что происходит внутри него. Теперь это стало возможным, и решения, которые раньше требовали добавления класса через скрипт при каждом взаимодействии пользователя, укладываются в одну строчку условия. Форма, у которой при пустом обязательном поле подсвечивается вся секция целиком, карточка, которая меняет фон, если внутри неё оказалось изображение с ошибкой загрузки — всё это делается чистым CSS, без единого слушателя событий.
К этому же семейству новинок примыкают контейнерные запросы, а точнее их развитие — запросы к стилям контейнера. Раньше адаптивность строилась исключительно вокруг ширины экрана, и компонент не мог реагировать на размеры своего непосредственного родителя, только на размеры окна браузера целиком. Контейнерные запросы это изменили: теперь блок способен подстраиваться под пространство, которое ему реально доступно, независимо от того, находится ли он в узкой боковой панели или на всю ширину страницы. А запросы к стилям контейнера идут ещё дальше и позволяют менять оформление вложенных элементов в зависимости от значения пользовательских переменных, заданных на самом контейнере — по сути, это превращает CSS в маленькую систему тем, которая переключается сама, без строчки JavaScript.
Отдельно хочется отметить попап-функциональность и элемент диалога, которые вместе с новым атрибутом, определяющим, какие действия закрывают всплывающее окно, наконец сняли необходимость городить самодельные модальные окна с ручным управлением фокусом, доступностью для скринридеров и обработкой клавиши выхода. Плюс появившийся вариант всплывающего окна, подчинённого другому — удобно ровно для тех же тултипов, о которых шла речь выше.
Из более скромных, но приятных мелочей упомяну функцию смешивания цветов прямо в таблице стилей, которая избавляет от необходимости заранее просчитывать промежуточные оттенки в графическом редакторе, и свойство, отвечающее за более осмысленный перенос строк в заголовках — оно само распределяет слова так, чтобы последняя строка не повисала одним коротким словом. Мелочь, а сколько раз хотелось именно этого.
Что объединяет все перечисленные новинки? Все они движутся в одну сторону — туда, где браузер берёт на себя работу, которую раньше делал программист руками. Меньше скриптов, меньше собственных пересчётов, меньше кода, который приходится поддерживать. И, пожалуй, это самое приятное впечатление от CSS последнего времени: язык, который многие считали второстепенным, оказался способен взять на себя логику, которая ещё недавно казалась исключительно прерогативой JavaScript.









