Веб-платформа полна инноваций, и CSS и функции веб-интерфейса находятся в авангарде этой захватывающей эволюции. Мы живем в золотую эру веб-интерфейсов, новые функции CSS появляются во всех браузерах с беспрецедентной скоростью, открывая мир возможностей для создания красивых и привлекательных веб-приложений. В этой статье мы подробно рассмотрим текущее состояние CSS, изучив некоторые из самых революционных новых функций, которые меняют подход к созданию веб-приложений, представленных в прямом эфире на Google I/O 2024.
Новые интерактивные возможности
Взаимодействие с веб-сайтом по своей сути представляет собой диалог между вами и вашими пользователями — именно поэтому так важно инвестировать в качественное взаимодействие с пользователями. Мы работаем над действительно масштабными улучшениями, которые открывают возможности, ранее недоступные в веб-среде, для навигации внутри веб-страниц и между ними.
Анимация, управляемая прокруткой
Как следует из названия, API для создания анимаций, управляемых прокруткой, позволяет создавать динамические анимации на основе прокрутки без использования наблюдателей прокрутки или других ресурсоемких скриптов.
Создавайте анимации, управляемые прокруткой.
Подобно тому, как на платформе работают анимации, основанные на времени , теперь вы можете использовать прогресс прокрутки скроллера для запуска, приостановки и обратного воспроизведения анимации. Таким образом, при прокрутке вперед вы будете видеть прогресс анимации, а при прокрутке назад — в обратном направлении. Это позволяет создавать визуальные эффекты, занимающие часть или всю страницу, с элементами, анимирующимися внутри области просмотра (также известный как скроллинг) , для динамического визуального воздействия.
Анимация, управляемая прокруткой, может использоваться для выделения важного контента, сопровождения пользователей в повествовании или просто для придания динамичности вашим веб-страницам.
Визуализация анимации, управляемой прокруткой
Живая демонстрация
@keyframes appear {
from {
opacity: 0;
scale: 0.8;
}
to {
opacity: 1;
scale: 1;
}
}
img {
animation: appear linear;
animation-timeline: view();
animation-range: entry 25% cover 50%;
}
Приведенный выше код определяет простую анимацию, которая появляется в области просмотра путем изменения прозрачности и масштаба изображения. Анимация управляется положением прокрутки. Для создания этого эффекта сначала настройте CSS-анимацию, а затем задайте параметр animation-timeline . В данном случае функция view() со значениями по умолчанию отслеживает изображение относительно области прокрутки (которая в данном случае также является областью просмотра).
Важно учитывать поддержку браузеров и пользовательские предпочтения, особенно в отношении доступности. Поэтому используйте правило @supports , чтобы проверить, поддерживает ли браузер анимацию, управляемую прокруткой, и оберните вашу анимацию, управляемую прокруткой, в запрос пользовательских предпочтений, например, @media (prefers-reduced-motion: no-preference) , чтобы учесть предпочтения пользователей в отношении движения. Выполнив эти проверки, вы будете уверены, что ваши стили будут работать и анимация не создаст проблем для пользователя.
@supports (animation-timeline: view()) {
@media (prefers-reduced-motion: no-preference) {
/* Apply scroll-driven animations here */
}
}
Анимация, управляемая прокруткой, может означать как полноэкранное отображение текста, так и более тонкие анимации, например, сворачивание и появление тени в заголовке веб-приложения при прокрутке.
Визуализация анимации, управляемой прокруткой
Живая демонстрация
@keyframes shrink-name {
from {
font-size: 2em;
}
to {
font-size: 1.5em;
}
}
@keyframes add-shadow {
from {
box-shadow: none;
}
to {
box-shadow: 0 4px 2px -2px gray;
}
}
header {
animation: add-shadow linear both;
}
h2 {
animation: shrink-name linear both;
}
header, h2 {
animation-timeline: scroll();
animation-range: 0 150px;
}
В этой демонстрации используются несколько различных анимаций с ключевыми кадрами — для заголовка, текста, панели навигации и фона — а затем к каждой из них применяется соответствующая анимация, управляемая прокруткой. Хотя у каждой анимации свой стиль, у всех одинаковая временная шкала анимации, ближайший элемент прокрутки и одинаковый диапазон анимации — от верхней части страницы до 150 пикселей.
Преимущества анимации, управляемой прокруткой, с точки зрения производительности
Этот встроенный API снижает нагрузку на код, который вам пришлось бы поддерживать, будь то написанный вами собственный скрипт или включение дополнительной сторонней зависимости. Он также избавляет от необходимости использовать различные наблюдатели прокрутки, что означает довольно существенное повышение производительности. Это связано с тем, что анимации, управляемые прокруткой, работают вне основного потока при анимации свойств, которые можно анимировать в композиторе, таких как преобразования и прозрачность, независимо от того, используете ли вы новый API непосредственно в CSS или используете хуки JavaScript.
Недавно Tokopedia использовала анимацию, управляемую прокруткой, чтобы панель навигации по продукту появлялась по мере прокрутки. Использование этого API принесло серьезные преимущества как в плане управления кодом, так и в плане производительности.
«Нам удалось сократить количество строк кода до 80% по сравнению с использованием традиционных событий прокрутки JavaScript, и мы заметили, что средняя загрузка ЦП во время прокрутки снизилась с 50% до 2%. — Энди Вихалим, старший инженер-программист, Tokopedia»
Будущее эффектов прокрутки
Мы знаем, что эти эффекты будут и дальше делать интернет более привлекательным местом, и мы уже думаем о том, что может произойти дальше. Это включает в себя возможность не только использовать новые временные шкалы анимации, но и использовать точку прокрутки для запуска анимации, так называемые анимации, запускаемые прокруткой.
В будущем в браузерах появятся ещё больше функций прокрутки. Следующая демонстрация показывает сочетание этих будущих функций. Она использует CSS-свойство scroll-start-target для установки начальной даты и времени в полях выбора, а также событие JavaScript scrollsnapchange для обновления даты в заголовке, что позволяет легко синхронизировать данные с событием привязки.
Также можно использовать эту функцию для обновления элемента выбора в реальном времени с помощью события JavaScript scrollsnapchanging .
В настоящее время эти функции доступны только в версии Canary за специальным флагом, однако они открывают возможности, которые ранее были невозможны или очень сложны для реализации на платформе, и демонстрируют перспективы развития интерактивных интерфейсов на основе прокрутки.
Чтобы узнать больше о том, как начать работу с анимацией, управляемой прокруткой, наша команда только что запустила новую серию видеороликов, которую вы можете найти на YouTube-канале Chrome for Developers . Здесь вы узнаете основы анимации, управляемой прокруткой, от Брамуса Ван Дамма, включая то, как работает эта функция, терминологию, различные способы создания эффектов и как комбинировать эффекты для создания насыщенных визуальных эффектов. Это отличная серия видеороликов, которую стоит посмотреть.
Просмотр переходов
Мы только что рассмотрели новую мощную функцию анимации на веб-страницах, но есть еще одна мощная новая функция, называемая переходами между представлениями, которая позволяет анимировать переходы между различными представлениями страниц для создания плавного пользовательского опыта. Переходы между представлениями обеспечивают новый уровень плавности в веб-дизайне, позволяя создавать плавные переходы между различными представлениями на одной странице или даже между разными страницами.
Airbnb — одна из компаний, уже экспериментирующих с интеграцией переходов между экранами в свой пользовательский интерфейс для плавной и удобной навигации по сайту. Это включает в себя боковую панель редактора объявлений, переход непосредственно к редактированию фотографий и добавлению удобств — всё в рамках плавного пользовательского процесса.
Хотя эти эффекты на всю страницу выглядят красиво и плавно, вы также можете создавать микро-взаимодействия, например, как в этом примере, где список обновляется при взаимодействии пользователя. Этого эффекта можно легко добиться с помощью переходов между представлениями.
Быстрый способ включить переходы между представлениями в вашем одностраничном приложении очень прост: достаточно обернуть интерактивный элемент с помощью document.startViewTransition и убедиться, что каждый элемент, подвергающийся переходу, имеет view-transition-name , либо указывается непосредственно в коде, либо динамически с помощью JavaScript при создании узлов DOM.
Демонстрационный визуальный эффект
Живая демонстрация
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.startViewTransition(() => {
btn.closest('.card').remove();
});
})
});
/* Styles for the transition animation */
::view-transition-old(.card):only-child {
animation: fade-out ease-out 0.5s;
}
Просмотреть классы перехода
Названия переходов представления можно использовать для применения пользовательских анимаций к переходам представления, хотя это может быть неудобно при большом количестве переходов. Первое в этом году обновление переходов представления упрощает эту проблему и вводит возможность создания классов переходов представления , которые можно применять к пользовательским анимациям.
Просмотреть типы переходов
Еще одно важное улучшение для переходов между представлениями — поддержка типов переходов между представлениями . Типы переходов между представлениями полезны, когда вам нужен другой тип визуального перехода при анимации перехода между представлениями страницы и другими представлениями.
Например, вам может понадобиться, чтобы анимация перехода с главной страницы на страницу блога отличалась от анимации возврата страницы блога на главную страницу. Или вам может понадобиться, чтобы страницы менялись местами по-разному, как в этом примере, слева направо и наоборот. Раньше это было сложно реализовать. Вы могли добавлять классы в DOM для применения стилей, а затем вам приходилось удалять эти классы. View-transition-types позволяют браузеру удалять старые переходы, вместо того чтобы заставлять вас делать это вручную перед запуском новых, выполняя эту работу за вас.
Вы можете задать типы внутри функции document.startViewTransition , которая теперь принимает объект. update — это функция обратного вызова, которая обновляет DOM, а types — это массив с типами.
document.startViewTransition({
update: myUpdate,
types: ['slide', 'forwards']
})
Переходы между многостраничными окнами
Мощность веб-технологий заключается в их масштабности. Многие приложения представляют собой не просто одну страницу, а целостную структуру, включающую множество страниц. Именно поэтому мы с радостью объявляем о добавлении поддержки переходов между окнами в многостраничных приложениях в Chromium 126.
Этот новый набор функций для работы с разными документами включает веб-интерфейсы, расположенные в пределах одного источника, например, переход с web.dev на web.dev/blog, но не включает навигацию между источниками, например, переход с web.dev на blog.web.dev или на другой домен, такой как google.com.
Одно из ключевых отличий переходов между страницами в пределах одного документа заключается в том, что вам не нужно оборачивать переход в document.startViewTransition() . Вместо этого, включите переход на обе страницы, участвующие в нем, используя правило CSS @view-transition .
@view-transition {
navigation: auto;
}
Для более индивидуального эффекта вы можете подключить JavaScript, используя новые обработчики событий pageswap или pagereveal , которые предоставляют доступ к объекту перехода представления.
С помощью pageswap вы можете внести некоторые последние изменения на исходящей странице непосредственно перед созданием старых снимков, а с помощью pagereveal настроить новую страницу перед началом ее отрисовки после инициализации.
window.addEventListener('pageswap', async (e) => {
// ...
});
window.addEventListener('pagereveal', async (e) => {
// ...
});
В будущем мы планируем расширить возможности перехода между окнами просмотра, в том числе:
- Ограниченные переходы : позволяют ограничить переход поддеревом DOM, обеспечивая интерактивность остальной части страницы и поддерживая одновременный запуск нескольких переходов между представлениями.
- Переходы между окнами, управляемые жестами : используйте жесты перетаскивания или свайпа, чтобы запустить переход между окнами в разных документах и получить более привычный для веб-приложений интерфейс.
- Навигация с использованием CSS : настройте переход между представлениями в разных документах непосредственно в CSS в качестве альтернативы использованию событий
pageswapиpagerevealв JavaScript. Чтобы узнать больше о переходах между представлениями в многостраничных приложениях, в том числе о том, как наиболее эффективно настроить их с помощью предварительной отрисовки, посмотрите следующий доклад Брамуса Ван Дамма:
Компоненты пользовательского интерфейса, поддерживаемые движком: упрощение сложных взаимодействий.
Создание сложных веб-приложений — непростая задача, но CSS и HTML развиваются, чтобы значительно упростить этот процесс. Новые функции и улучшения упрощают создание компонентов пользовательского интерфейса, позволяя сосредоточиться на создании превосходных пользовательских интерфейсов. Это достигается благодаря совместной работе нескольких ключевых организаций по стандартизации и групп сообщества, включая рабочую группу CSS, группу сообщества Open UI и WHATWG (Рабочая группа по технологиям веб-гипертекстовых приложений).
Одна из главных проблем, с которой сталкиваются разработчики, — это, казалось бы, простая просьба: возможность стилизовать выпадающие меню (элемент select). Хотя на первый взгляд это кажется простым, на самом деле это сложная проблема, затрагивающая множество аспектов платформы: от компоновки и рендеринга до прокрутки и взаимодействия, от стилизации пользовательского агента и свойств CSS до изменений в самом HTML.

Выпадающий список состоит из множества элементов и включает в себя множество состояний, которые необходимо учитывать, например:
- Назначение клавиш (для входа/выхода из взаимодействия)
- Чтобы закрыть окно, нажмите на него.
- Активное управление всплывающими окнами (закрытие других всплывающих окон при открытии одного)
- управление фокусом вкладки
- Визуализация значения выбранного параметра
- стиль взаимодействия стрелок
- Управление состоянием (открытие/закрытие)
В настоящее время управлять всем этим состоянием самостоятельно довольно сложно, но и платформа не облегчает задачу. Чтобы это исправить, мы разобрали эти части и выпускаем несколько базовых функций, которые позволят не только стилизовать выпадающие списки, но и многое другое.
API всплывающих окон
Сначала мы добавили глобальный атрибут под названием popover , и я рад сообщить, что несколько недель назад он стал доступен в базовой версии.
Всплывающие окна скрываются с помощью display: none , пока не будут открыты с помощью вызывающего объекта, такого как кнопка, или с помощью JavaScript. Чтобы создать простое всплывающее окно, установите атрибут `popover` для элемента и свяжите его ID с кнопкой с помощью popovertarget . Теперь кнопка является вызывающим объектом.
Демонстрационный визуальный эффект
Живая демонстрация
<button popovertarget="my-popover">Open Popover</button>
<div id="my-popover" popover>
<p>I am a popover with more information.</p>
</div>
Благодаря включенному атрибуту popover, браузер обрабатывает многие ключевые действия без дополнительного написания скриптов, в том числе:
- Перемещение на верхний слой. : Отдельный слой над остальной частью страницы, чтобы вам не приходилось возиться с
z-index. - Функция автоматического закрытия всплывающего окна : щелчок за пределами области всплывающего окна закроет его и вернет фокус.
- Управление фокусом вкладок по умолчанию: при открытии всплывающего окна следующая вкладка останавливается внутри этого всплывающего окна.
- Встроенные сочетания клавиш. : Нажатие клавиши
escили двойное переключение закроет всплывающее окно и вернет фокус. - Привязки компонентов по умолчанию : Браузер семантически связывает всплывающее окно с его триггером.

Возможно, вы даже используете этот API всплывающих окон уже сегодня, не подозревая об этом. GitHub реализовал всплывающие окна в меню «Новое» на главной странице и в обзоре запросов на слияние. Они постепенно улучшали эту функцию, используя полифил для всплывающих окон , разработанный Oddbird при значительной поддержке Кейта Циркеля из GitHub, для поддержки старых браузеров.
«Благодаря переходу на всплывающие окна нам удалось исключить из кода буквально тысячи строк. Всплывающие окна помогают нам, избавляя от необходимости бороться с заветными значениями z-index... Наличие правильной структуры дерева доступности, установленной с помощью декларативного поведения кнопок и встроенных механизмов фокусировки, значительно упрощает внедрение шаблонов в нашей системе дизайна. — Кейт Циркель, инженер-программист, GitHub»
Анимация эффектов входа и выхода
При использовании всплывающих окон вам, вероятно, захочется добавить интерактивность. За последний год появились четыре новые функции интерактивности для поддержки анимации всплывающих окон. К ним относятся:
Возможность анимировать display и content-visibility на временной шкале ключевых кадров.
Свойство transition-behavior с ключевым словом allow-discrete позволяет разрешать переходы дискретных свойств, таких как display .
Правило @starting-style для анимации эффектов появления из display: none в `top-layer` .
Свойство overlay используется для управления поведением верхнего слоя во время анимации.
Эти свойства работают для любого элемента, который вы анимируете в верхнем слое, будь то всплывающее окно или диалоговое окно. В целом, для диалогового окна с фоном это выглядит так:
Демонстрационный визуальный эффект
Живая демонстрация
dialog, ::backdrop{
opacity: 0;
transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}
[open], [open]::backdrop {
opacity: 1;
}
@starting-style {
[open], [open]::backdrop {
opacity: 0;
}
}
Сначала настройте @starting-style , чтобы браузер знал, какие стили использовать для анимации этого элемента в DOM. Это делается как для диалогового окна, так и для фона. Затем стилизуйте состояние открытия для обоих элементов. Для диалогового окна используется атрибут ` open , а для всплывающего окна — псевдоэлемент ` ::popover-open . Наконец, анимируйте свойства opacity , display и overlay , используя ключевое слово allow-discrete , чтобы включить режим анимации, в котором дискретные свойства могут переходить друг в друга.
Позиционирование якоря
Popover — это только начало. Очень интересное обновление — поддержка позиционирования привязки теперь доступна в Chrome 125.
Используя позиционирование с помощью привязки, всего несколькими строками кода браузер может обработать логику привязки позиционированного элемента к одному или нескольким элементам-привязкам. В следующем примере простая всплывающая подсказка привязана к каждой кнопке, расположенной внизу по центру.
Демонстрационный визуальный эффект
Живая демонстрация
Настройте позиционирование с помощью привязки элемента в CSS, используя свойство anchor-name для элемента, к которому привязывается элемент (в данном случае, кнопка), и свойство position-anchor для элемента, к которому применяется позиционирование (в данном случае, всплывающая подсказка). Затем примените абсолютное или фиксированное позиционирование относительно привязки с помощью функции anchor() . Следующий код позиционирует верхнюю часть всплывающей подсказки относительно нижней части кнопки.
.anchor {
anchor-name: --my-anchor;
}
.positioned {
position: absolute;
position-anchor: --my-anchor;
}
В качестве альтернативы, можно использовать имя привязки непосредственно в функции привязки, минуя свойство position-anchor . Это может быть полезно при привязке к нескольким элементам.
.anchor {
anchor-name: --my-anchor;
}
.positioned {
position: absolute;
top: anchor(--my-anchor bottom);
}
Наконец, используйте новое ключевое слово anchor-center для свойств justify и align , чтобы центрировать позиционированный элемент относительно его привязки.
.anchor {
anchor-name: --my-anchor;
}
.positioned {
position: absolute;
top: anchor(--my-anchor bottom);
justify-self: anchor-center;
}
Хотя использование позиционирования с помощью привязки (якоря) очень удобно с всплывающими окнами (popover), всплывающее окно определенно не является обязательным условием для его использования. Позиционирование с помощью привязки можно использовать с любыми двумя (или более) элементами для создания визуальной связи. На самом деле, следующий пример, вдохновленный статьей Романа Комарова , показывает, как стиль подчеркивания привязывается к элементам списка при наведении курсора или нажатии клавиши Tab.
Демонстрационный визуальный эффект
Живая демонстрация
В этом примере используется функция `anchor` для установки положения ссылки с помощью физических свойств ` left , right и bottom . При наведении курсора на одну из ссылок целевая ссылка изменяется, и браузер перемещает её для применения позиционирования, одновременно анимируя изменение цвета для создания интересного эффекта.
ul::before {
content: "";
position: absolute;
left: anchor(var(--target) left);
right: anchor(var(--target) right);
bottom: anchor(var(--target) bottom);
...
}
li:nth-child(1) { --anchor: --item-1 }
ul:has(:nth-child(1) a:is(:hover, :focus-visible)) {
--target: --item-1;
--color: red;
}
позиционирование inset-area
В дополнение к стандартному абсолютному позиционированию по направлению, которое вы, вероятно, использовали ранее, появился новый механизм компоновки, являющийся частью API позиционирования якорей, называемый «вставка» (inset area). Вставка упрощает размещение позиционированных элементов относительно соответствующих якорей и работает на сетке из 9 ячеек с якорным элементом в центре. Например, inset-area: top размещает позиционированный элемент вверху, а inset-area: bottom внизу.
Упрощенная версия первого примера с якорем выглядит так, используя inset-area :
.anchor {
anchor-name: --my-anchor;
}
.positioned {
position: absolute;
position-anchor: --my-anchor;
inset-area: bottom;
}
Вы можете комбинировать эти позиционные значения с ключевыми словами `span`, чтобы начать с центральной позиции и либо растянуть элемент влево, вправо, либо охватить все столбцы или строки. Вы также можете использовать логические свойства. Чтобы упростить визуализацию и понимание этого механизма компоновки, воспользуйтесь этим инструментом в Chrome 125+:
Поскольку эти элементы привязаны к определенному месту, позиционированный элемент динамически перемещается по странице вслед за перемещением его привязки. В данном случае у нас есть элементы-карточки, оформленные с помощью контейнерных запросов, которые изменяют свой размер в зависимости от своего внутреннего размера (чего нельзя сделать с медиа-запросами), и привязанное меню будет смещаться вместе с новым макетом по мере изменения пользовательского интерфейса карточки.
Демонстрационный визуальный эффект
Живая демонстрация
Динамическое позиционирование точек привязки с position-try-options
Создание меню и подменю значительно упрощается благодаря сочетанию всплывающих окон и позиционирования с помощью привязки. Кроме того, когда ваш элемент, привязанный к краю области просмотра, достигает края, вы можете позволить браузеру самостоятельно изменить его положение. Это можно сделать несколькими способами. Первый — создать собственные правила позиционирования. В данном случае подменю изначально располагается справа от кнопки «витрина». Но вы можете создать блок @position-try на случай, если справа от меню недостаточно места, присвоив ему пользовательский идентификатор ` --bottom . Затем вы связываете этот блок @position-try с привязкой, используя position-try-options .
Теперь браузер будет переключаться между этими закрепленными состояниями, сначала пытаясь занять правильное положение, а затем перемещаясь вниз. И это можно сделать с помощью плавного перехода.
Демонстрационный визуальный эффект
Живая демонстрация
#submenu {
position-anchor: --submenu;
top: anchor(top);
left: anchor(right);
margin-left: var(--padding);
position-try-options: --bottom;
transition: top 0.25s, left 0.25s;
width: max-content;
}
@position-try --bottom {
top: anchor(left);
left: anchor(bottom);
margin-left: var(--padding);
}
Помимо явной логики позиционирования, браузер предоставляет несколько ключевых слов для выполнения базовых действий, таких как изменение направления ссылки в блоке или в строке.
position-try-options: flip-block, flip-inline;
Для простого переключения между элементами воспользуйтесь значениями ключевых слов `flip` и вовсе откажитесь от написания определения position-try . Таким образом, теперь у вас есть полностью функциональный адаптивный элемент с позиционированием, использующий местоположение, всего лишь с помощью нескольких строк CSS.
Демонстрационный визуальный эффект
Живая демонстрация
.tooltip {
inset-area: top;
position-try-options: flip-block;
}
Узнайте больше об использовании позиционирования с помощью якорей .
Будущее многоуровневого пользовательского интерфейса
Мы видим повсюду элементы, связанные между собой, и набор функций, показанный в этом посте, — это отличное начало для раскрытия творческого потенциала и лучшего контроля над элементами с привязкой к якорю и многоуровневыми интерфейсами. Но это только начало. Например, в настоящее время popover работают только с кнопками в качестве вызывающего элемента или с JavaScript. Для чего-то вроде предварительного просмотра в стиле Википедии, шаблона, распространенного на всех веб-платформах, необходимо иметь возможность взаимодействовать с всплывающим окном и запускать его по ссылке, а также при проявлении пользователем интереса, не обязательно кликая по ссылке, например, при наведении курсора или фокусировке на вкладке.
В качестве следующего шага в развитии API всплывающих окон мы работаем над interesttarget , чтобы решить эти задачи и упростить воспроизведение подобных ситуаций с помощью соответствующих механизмов обеспечения доступности. Это сложная проблема доступности, требующая решения множества открытых вопросов относительно идеального поведения, но решение и стандартизация этой функциональности на уровне платформы должны улучшить пользовательский опыт для всех.
<a interesttarget="my-tooltip">Hover/Focus to show the tooltip</a>
<span popover=hint id="my-toolip">This is the tooltip</span>
Кроме того, благодаря работе двух сторонних разработчиков, Кейта Циркеля и Люка Уорлоу, в Canary доступен для тестирования еще один перспективный универсальный вызывающий механизм ( invoketarget ). invoketarget поддерживает декларативный подход к разработке, который popovertarget обеспечивает для всплывающих окон, нормализованный для всех интерактивных элементов, включая <dialog> , <details> , <video> , <input type="file"> и многое другое.
<button invoketarget="my-dialog">
Open Dialog
</button>
<dialog id="my-dialog">
Hello world!
</dialog>
Мы знаем, что существуют сценарии использования, которые пока не охвачены этим API. Например, стилизация стрелки, соединяющей привязанный элемент с его якорем, особенно при изменении положения привязанного элемента, а также возможность «скользить» элементу и оставаться в области видимости, вместо того чтобы привязываться к другому заданному положению, когда он достигает своего ограничивающего прямоугольника. Поэтому, хотя мы рады появлению этого мощного API, мы также с нетерпением ждем возможности еще больше расширить его возможности в будущем.
Стилизуемый выбор
Используя popover и anchor , команда добилась прогресса в создании настраиваемого выпадающего списка. Хорошая новость в том, что прогресс значителен. Плохая новость в том, что этот API пока находится в экспериментальном состоянии. Тем не менее, я рад поделиться некоторыми демонстрациями и обновлениями о нашем прогрессе и, надеюсь, получить ваши отзывы. Во-первых, есть прогресс в том, как включить новый, настраиваемый интерфейс выпадающего списка. В настоящее время это делается с помощью свойства appearance в CSS, установленного на appearance: base-select . После установки appearance вы включите новый, настраиваемый интерфейс выпадающего списка.
select {
appearance: base-select;
}
Помимо appearance: base-select , появилось несколько новых HTML-обновлений. К ним относятся возможность заключать параметры в ` datalist для персонализации и возможность добавлять произвольный неинтерактивный контент, например изображения, в параметры. Также появится новый элемент ` <selectedoption> `, который будет отображать содержимое параметров в себе, и вы сможете настроить его под свои нужды. Этот элемент действительно очень удобен.
Демонстрационный визуальный эффект

Живая демонстрация
<select>
<button type=popover>
<selectedoption></selectedoption>
</button>
<datalist>
<option value="" hidden>
<p>Select a country</p>
</option>
<option value="andorra">
<img src="Flag_of_Andorra.svg" />
<p>Andorra</p>
</option>
<option value="bolivia">
<img src="Flag_of_Bolivia.svg" />
<p>Bolivia</p>
</option>
...
</datalist>
</select>
Следующий код демонстрирует настройку <selectedoption> в пользовательском интерфейсе Gmail, где визуальный значок представляет тип ответа, выбранный для экономии места. Вы можете использовать базовые стили отображения внутри selectedoption , чтобы различать стиль варианта ответа и стиль предварительного просмотра. В данном случае текст, отображаемый в варианте ответа, может быть визуально скрыт в selectedoption .
Демонстрационный визуальный эффект

Живая демонстрация
selectedoption .text {
display: none;
}
Одним из главных преимуществ повторного использования элемента <select> для этого API является обратная совместимость. В этом выпадающем списке стран вы можете увидеть настраиваемый пользовательский интерфейс с изображениями флагов в параметрах для более удобного восприятия контента пользователем. Поскольку неподдерживаемые браузеры будут игнорировать строки, которые они не понимают, такие как пользовательская кнопка, список данных, выбранный параметр и изображения в параметрах, резервный вариант будет аналогичен текущему пользовательскому интерфейсу выпадающего списка по умолчанию.

Благодаря настраиваемым выпадающим спискам возможности безграничны. Мне особенно нравится этот селектор стран в стиле Airbnb, потому что он имеет продуманный стиль для адаптивного дизайна. Это и многое другое можно сделать с помощью грядущего стилизуемого выпадающего списка, что делает его крайне необходимым дополнением к веб-платформе.
Демонстрационный визуальный эффект
Живая демонстрация
Эксклюзивный аккордеон
Решение проблем со стилем элементов (и всех сопутствующих аспектов) — не единственный компонент пользовательского интерфейса, на котором сосредоточилась команда Chrome. Первое дополнительное обновление компонента — это возможность создавать эксклюзивные аккордеоны, в которых одновременно можно открыть только один элемент.
Browser Support
Для этого необходимо присвоить одно и то же имя нескольким элементам сведений, создав таким образом связанную группу сведений, подобно группе переключателей.
<details name="learn-css" open>
<summary>Welcome to Learn CSS!</summary>
</details>
<details name="learn-css">
<summary>Box Model</summary>
<p>...</p>
</details>
<details name="learn-css">
<summary>Selectors</summary>
<p>...</p>
</details>
:user-valid и :user-invalid
Еще одно улучшение компонентов пользовательского интерфейса — псевдоклассы :user-valid и :user-invalid . Стабильно работающие во всех браузерах, эти псевдоклассы ведут себя аналогично псевдоклассам :valid :user-valid :invalid :user-invalid но соответствуют элементу управления формы только после того, как пользователь существенно взаимодействовал с полем ввода. Это означает, что для определения того, было ли взаимодействие с значением формы выполнено или оно стало «измененным», требуется значительно меньше кода, что может быть очень полезно для предоставления обратной связи пользователю и значительно сокращает объем скриптов, необходимых для этого раньше.
Демонстрационный видеоролик
Живая демонстрация
input:user-valid,
select:user-valid,
textarea:user-valid {
--state-color: green;
--bg: linear-gradient(...);
}
input:user-invalid,
select:user-invalid,
textarea:user-invalid {
--state-color: red;
--bg: linear-gradient(...);
}
Узнайте больше об использовании псевдоэлементов проверки форм user-* .
field-sizing: content
Еще одно полезное обновление компонента, появившееся недавно, — это field-sizing: content , которое можно применять к элементам управления форм, таким как поля ввода и текстовые поля. Это позволяет увеличивать (или уменьшать) размер поля ввода в зависимости от его содержимого. field-sizing: content может быть особенно полезен для текстовых полей, поскольку вы больше не ограничены фиксированными размерами, из-за которых вам может потребоваться прокрутить вверх, чтобы увидеть то, что вы написали в начале запроса в слишком маленьком поле ввода.
Демонстрационный видеоролик
Живая демонстрация
textarea, select, input {
field-sizing: content;
}
Узнайте больше о расчете размеров поля .
<hr> в <select>
Возможность включения элемента <hr> , или горизонтальной линии, в выпадающих списках — еще одна небольшая, но полезная функция компонента. Хотя она не имеет большого семантического применения, она помогает хорошо разделять контент внутри выпадающего списка, особенно тот контент, который вы, возможно, не захотите группировать с помощью optgroup, например, значение-заполнитель.
Выберите скриншот

Выберите демонстрацию в реальном времени
<select name="majors" id="major-select">
<option value="">Select a major</option>
<hr>
<optgroup label="School of Fine Arts">
<option value="arthist">
Art History
</option>
<option value="finearts">
Fine Arts
</option>
...
</select>
Узнайте больше об использовании отдела кадров в отдельных разделах.
Улучшение качества жизни
Мы постоянно работаем над улучшением, и это касается не только взаимодействия и компонентов. За последний год было внесено множество других улучшений, повышающих удобство использования.
Вложенность с опережающим планированием
Встроенная функция CSS-вложенности появилась во всех браузерах в прошлом году, и с тех пор её улучшили, добавив поддержку опережающего просмотра (lookahead), что означает, что символ & перед именами элементов больше не является обязательным. Это делает вложенность гораздо более эргономичной и похожей на то, к чему я привык раньше.
Одна из моих любимых особенностей вложенности CSS заключается в том, что она позволяет визуально блокировать компоненты, а внутри этих компонентов включать состояния и модификаторы, такие как запросы контейнера и медиа-запросы. Раньше я обычно группировал все эти запросы внизу файла для большей специфичности. Теперь же их можно написать так, чтобы это имело смысл, прямо рядом с остальным кодом.
.card {
/* card base styles */
h2 {
/* child element style */
}
&.highlight {
/* modifier style */
}
&:hover, &:focus {
/* state styles */
}
@container (width >= 300px) {
/* container query styles */
}
}
Выравнивание содержимого для блочной компоновки
Ещё одно действительно приятное изменение — возможность использовать механизмы центрирования, такие как align-content в блочной компоновке. Это означает, что теперь вы можете, например, центрировать элементы по вертикали внутри div без необходимости применять flex- или grid-макет и без побочных эффектов, таких как предотвращение схлопывания полей, которые могут быть нежелательны при использовании этих алгоритмов компоновки.
Browser Support
Скриншот

Живая демонстрация
div {
align-content: center;
}
Обтекание текста: сбалансированно и красиво
Говоря о верстке, стоит отметить, что верстка текста значительно улучшилась благодаря добавлению параметров text-wrap: balance и pretty . text-wrap: balance используется для создания более равномерного блока текста, а text-wrap: pretty фокусируется на уменьшении количества одиночных символов в последней строке текста.
Демонстрационный видеоролик
Живая демонстрация
balance и pretty на заголовке и абзаце, перемещая ползунок. Попробуйте перевести демонстрацию на другой язык! h1 {
text-wrap: balance;
}
Узнайте больше о переносе текста: баланс .
Международные обновления типографики
В прошлом году были внесены значительные улучшения в типографическую разметку текстов на японском, китайском и корейском языках , например, функция word-break: auto-phrase , которая переносит строку по естественной границе фразы.
Browser Support

word-break: normal и word-break: auto-phrase А также text-spacing-trim , который применяет кернинг между знаками препинания для улучшения читаемости китайского, японского и корейского шрифтов, обеспечивая более приятный визуальный результат.

Относительный цветовой синтаксис
В мире цветовых тем мы стали свидетелями значительного обновления синтаксиса относительных цветов.
В этом примере цвета используют тему оформления на основе Oklch. По мере изменения значения оттенка с помощью ползунка, вся тема меняется. Этого можно добиться с помощью синтаксиса относительных цветов. Фон использует основной цвет, основанный на оттенке, и регулирует каналы яркости, насыщенности и оттенка для изменения своего значения. --i — это индекс соседнего элемента в списке для градации значений, показывающий, как можно комбинировать ступенчатое изменение с пользовательскими свойствами и синтаксисом относительных цветов для создания тем.
Демонстрационный видеоролик
Живая демонстрация
balance и pretty на заголовке и абзаце, перемещая ползунок. Попробуйте перевести демонстрацию на другой язык! :root {
--hue: 230;
--primary: oklch(70% .2 var(--hue));
}
li {
--_bg: oklch(from var(--primary)
calc(l - (var(--i) * .05))
calc(c - (var(--i) * .01))
calc(h - (var(--i) + 5)));
}
функция light-dark()
Благодаря функции light-dark() , настройка тем оформления стала намного более динамичной и упрощенной.
Функция light-dark() — это эргономичное улучшение, упрощающее настройку цветовых тем, позволяющее более лаконично записывать стили тем, как это наглядно продемонстрировано на этой визуальной диаграмме Адама Аргила. Раньше для настройки параметров темы требовались два разных блока кода (тема по умолчанию и запрос пользовательских настроек). Теперь же, используя функцию light-dark() , вы можете записать эти параметры стиля как для светлой, так и для темной темы в одной строке CSS.
light-dark() . Подробнее см. в демонстрации . html {
color-scheme: light dark;
}
button {
background-color: light-dark(lightblue, darkblue);
}
Если пользователь выбрал светлую тему, кнопка будет иметь светло-голубой фон. Если пользователь выбрал темную тему, кнопка будет иметь темно-голубой фон.
:has() селектор
And I would be remiss to talk about modern UI without mentioning one of the most impactful interop highlights from the past year, which has to be the :has() selector, landing across browsers in December of last year. This API is a game-changer for writing logical styles.
The :has() selector enables you to check if a child element has specific children, or if those children are in a specific state, and essentially can function as a parent selector as well.
has() being used to style comparison blocks on Tokopedia . :has() has already shown to be particularly useful for many companies , including PolicyBazaar, who use :has() to style blocks based on their interior content, such as in the compare section, where the style adjusts if there is a plan to compare in the block, or if its empty.
“With the :has() selector, we were able to eliminate JavaScript based validation of the user's selection and replace it with a CSS solution which is working seamlessly for us with the same experience as before.–Aman Soni, Tech Lead, PolicyBazaar”
Запросы контейнеров
Another key addition to the web that is now newly available and growing in usage is container queries, which enable the ability to query an element parent's intrinsic size to apply styles: a much more fine-toothed comb than media queries, which only query the viewport size.
Angular recently launched a beautiful new documentation site on angular.dev using container queries to style the header blocks based on their available space on the page. So even if the layout changes, and goes from a multicolumn sidebar layout to a single-column layout, the header blocks can self-adjust.
Without container queries, doing something like this was quite hard to achieve, and damaging for performance, requiring resize observers and element observers. Now, it's trivial to style an element based on its parent size.
Демонстрационный видеоролик
Живая демонстрация
@property
And finally very soon, we are excited to see @property land in Baseline. This is a key feature for providing semantic meaning to CSS custom properties (also known as CSS variables), and enables a slew of new interaction features. @property also enables contextual meaning, typechecking, defaults, and fallback values in CSS. Opening the doors for even more robust features like range style queries. This is a feature that was never possible before, and now provides so much depth to the language of CSS.
Демонстрационный видеоролик
Живая демонстрация
@property --card-bg {
syntax: "<color>";
inherits: false;
initial-value: #c0bae8;
}
Заключение
With all of these new powerful UI capabilities landing across browsers, the possibilities are endless. Novel interactive experiences with scroll-driven animations and view transitions make the web more fluid and interactive in ways we've never seen before. And next level UI components make it easier than ever to build robust, beautifully customized components without ripping out the entire native experience. And finally, quality of life improvements in architecture, layout, typography, and responsive design not only solve the little big things, but also give developers the tools they need to build complex interfaces that work on a variety of devices, form factors, and user needs.
These new features you should be able to remove third-party scripting for performance-heavy features like scrollytelling and tethering elements to each other with anchor positioning, build fluid page transitions, finally style dropdowns, and improve the overall structure of your code natively.
It's never been a better time to be a web developer. There hasn't been so much energy and excitement since the announcement of CSS3. Features we've needed but have only dreamed of actually landing in the past, are finally becoming a reality and a part of the platform. And it's because of your voice that we're able to prioritize and finally bring these capabilities to life. We're working on making it easier to do the hard, tedious stuff natively so you can spend more time building the things that matter–like the core features and design details that set your brand apart.
To learn more about these new features as they land, follow along at developer.chrome.com and web.dev, where our team shares the latest news in web technologies. Try out scroll driven animations, view transitions, anchor positioning, or even the stylable select, and let us know what you think. We're here to listen and we're here to help.