Последние несколько месяцев ознаменовали собой золотую эру для веб-интерфейсов. Появились новые возможности платформы с тесной кроссбраузерной совместимостью, поддерживающие больше веб-функций и возможностей настройки, чем когда-либо.
Вот 20 самых интересных и значимых функций, которые появились недавно или появятся в ближайшее время:
- Запросы контейнеров
- Вопросы стиля
-
:has()селектор - n-й микросинтаксис
-
text-wrap: balance -
initial-letter - Динамические блоки области просмотра
- Цветовые пространства с широким цветовым охватом
-
color-mix() - Гнездование
- Каскадные слои
- Ограниченные стили
- Тригонометрические функции
- Индивидуальные свойства преобразования
- попвер
- позиционирование якоря
- выбрать меню
- Дискретные переходы свойств
- Анимация, управляемая прокруткой
- Просмотр переходов
Новый адаптивный дизайн
Давайте начнём с новых возможностей адаптивного дизайна. Новые функции платформы позволяют создавать логические интерфейсы с компонентами, которые сами определяют свою адаптивную стилизацию, создавать интерфейсы, использующие возможности системы для обеспечения более привычного интерфейса, и вовлекать пользователя в процесс проектирования с помощью запросов на определение пользовательских предпочтений для полной настройки.
Запросы контейнеров
Контейнерные запросы недавно стали стабильно работать во всех современных браузерах. Они позволяют запрашивать размер и стиль родительского элемента, чтобы определить стили, которые должны применяться к его дочерним элементам. Медиа-запросы могут получать доступ к информации только из области просмотра, что означает, что они могут работать только в макрорежиме макета страницы. Контейнерные запросы, с другой стороны, являются более точным инструментом, который может поддерживать любое количество макетов или макетов внутри макетов.
В приведенном ниже примере папки «Входящие» и боковой панели «Избранное» представлены в виде контейнеров. Содержимое их папок изменяет свою сетку и отображает или скрывает метку времени письма в зависимости от доступного пространства. Это один и тот же компонент на странице, просто отображающийся в разных режимах просмотра.
Поскольку у нас используется контейнерный запрос, стили этих компонентов динамические. Если вы изменяете размер страницы и макет, компоненты реагируют на выделенное им пространство. Боковая панель превращается в верхнюю панель с большим пространством, и мы видим, что макет больше похож на основной почтовый ящик. Когда пространства становится меньше, оба элемента отображаются в сжатом формате.
Подробнее о запросах к контейнерам и создании логических компонентов можно узнать в этой статье .
Вопросы стиля
Browser Support
Спецификация запроса контейнера также позволяет запрашивать значения стилей родительского контейнера. В настоящее время это частично реализовано в Chrome 111, где можно использовать пользовательские свойства CSS для применения стилей контейнера.
В следующем примере для оформления фона карточки и значка-индикатора используются характеристики погоды, хранящиеся в значениях пользовательских свойств, такие как дождь, солнце и облачность.
@container style(--sunny: true) {
.weather-card {
background: linear-gradient(-30deg, yellow, orange);
}
.weather-card:after {
content: url(<data-uri-for-demo-brevity>);
background: gold;
}
}

Это только начало для запросов стилей. В будущем у нас появятся логические запросы для определения существования значения пользовательского свойства и уменьшения повторения кода, а в настоящее время обсуждаются запросы диапазона для применения стилей на основе диапазона значений. Это позволит применять стили, показанные здесь, используя процентное значение вероятности дождя или облачности.
Вы можете узнать больше и посмотреть больше примеров в нашей статье в блоге о запросах стилей .
:has()
Говоря о мощных динамических функциях, селектор `:has()` — одна из самых мощных новых возможностей CSS, появившихся в современных браузерах. С помощью :has() вы можете применять стили, проверяя, содержит ли родительский элемент определенные дочерние элементы или находятся ли эти дочерние элементы в определенном состоянии. Это означает, что у нас, по сути, теперь есть селектор родительского элемента.
Основываясь на примере запроса контейнера, вы можете использовать :has() для того, чтобы сделать компоненты еще более динамичными. В нем элемент со звездочкой получает серый фон, а элемент с отмеченным флажком — синий фон.

Однако этот API не ограничивается выбором родительского элемента. Вы также можете стилизовать любые дочерние элементы внутри родительского. Например, заголовок будет выделен жирным шрифтом, если элемент содержит элемент «звездочка». Это достигается с помощью .item:has(.star) .title . Использование селектора :has() ` дает доступ к родительским элементам, дочерним элементам и даже элементам-соседям, что делает этот API действительно гибким, и каждый день появляются новые варианты его использования.
Узнайте больше и ознакомьтесь с другими примерами, прочитайте эту статью в блоге, посвященную функции :has() .
n-й из синтаксиса
Browser Support
Веб-платформа теперь имеет более продвинутый выбор n-го дочернего элемента. Расширенный синтаксис n-го дочернего элемента предоставляет новое ключевое слово ("of"), которое позволяет использовать существующий микросинтаксис An+B с более конкретным подмножеством для поиска.
Если вы используете обычный nth-child, например :nth-child(2) для специального класса, браузер выберет элемент, к которому применен класс special, и который также является вторым дочерним элементом. Это отличается от :nth-child(2 of .special) , который сначала предварительно отфильтрует все элементы .special , а затем выберет второй из этого списка.
Подробнее об этой функции можно узнать в нашей статье о синтаксисе nth-of .
text-wrap: balance
Селекторы и запросы стилей — не единственные места, где мы можем встраивать логику в наши стили; типографика — ещё одно такое место. Начиная с Chrome 114, вы можете использовать балансировку переноса текста для заголовков, используя свойство text-wrap со значением balance .
Для балансировки текста браузер фактически выполняет бинарный поиск наименьшей ширины, которая не приводит к появлению дополнительных строк, останавливаясь на одном пикселе CSS (а не на пикселе отображения). Для дальнейшего минимизирования шагов в бинарном поиске браузер начинает с 80% от средней ширины строки.
Подробнее об этом читайте в этой статье .
initial-letter
Ещё одно полезное улучшение веб-типографики — свойство initial-letter . Это свойство CSS позволяет лучше контролировать стиль буквиц с отступом.
С помощью свойства initial-letter в псевдоэлементе ` :first-letter можно указать: размер буквы в зависимости от количества строк, которые она занимает; смещение блока, или «удержание», то есть место, где будет располагаться буква.
Подробнее об использовании intial-letter можно узнать здесь .
Динамические блоки области просмотра
Browser Support
Одна из распространенных проблем, с которой сегодня сталкиваются веб-разработчики, — это точное и согласованное масштабирование во всю область просмотра, особенно на мобильных устройствах. Разработчику нужно, чтобы 100vh (100% высоты области просмотра) означало «быть такой же высоты, как и область просмотра», но единица vh не учитывает такие факторы, как сворачивание панелей навигации на мобильных устройствах, поэтому иногда получается слишком длинный элемент, что приводит к прокрутке.

Для решения этой проблемы мы ввели новые единицы измерения на веб-платформе, включая: - Малую высоту и ширину области просмотра (или svh и svw ), которые представляют наименьший активный размер области просмотра. - Большую высоту и ширину области просмотра ( lvh и lvw ), которые представляют наибольший размер. - Динамическую высоту и ширину области просмотра ( dvh и dvw ).
Значение динамических единиц области просмотра изменяется в зависимости от того, видны ли дополнительные динамические панели инструментов браузера, такие как адресная строка вверху или панель вкладок внизу, и когда они невидимы.

Для получения более подробной информации об этих новых модулях ознакомьтесь с разделом «Большие, малые и динамические модули области просмотра» .
Цветовые пространства с широким цветовым охватом
Еще одним важным нововведением веб-платформы являются цветовые пространства с широким цветовым охватом. До появления цветовых пространств с широким цветовым охватом на веб-платформе можно было сделать фотографию с яркими цветами, которые отображались на современных устройствах, но нельзя было подобрать цвет кнопки, текста или фона, соответствующий этим ярким значениям.
Попробуйте сами!
Но теперь на веб-платформе доступен целый ряд новых цветовых пространств, включая REC2020, P3, XYZ, LAB, OKLAB, LCH и OKLCH. Познакомьтесь с новыми цветовыми пространствами для веб-платформы и многим другим в руководстве по цветопередаче HD .

И вы сразу можете увидеть в инструментах разработчика, как расширился цветовой диапазон: белая линия обозначает, где заканчивается диапазон sRGB и начинается более широкий цветовой охват.

Доступно гораздо больше инструментов для работы с цветом! Не пропустите и все замечательные улучшения градиентов. Адам Аргил даже создал совершенно новый инструмент, который поможет вам опробовать новый инструмент для выбора цвета и построения градиентов в веб-среде — попробуйте его на gradient.style .
color-mix()
Расширение цветового пространства обеспечивается функцией color-mix() . Эта функция позволяет смешивать два цветовых значения для создания новых значений на основе каналов смешиваемых цветов. Цветовое пространство, в котором происходит смешивание, влияет на результат. Работа в более перцептивном цветовом пространстве, таком как oklch, приведет к другому диапазону цветов, чем, например, srgb.
color-mix(in srgb, blue, white);
color-mix(in srgb-linear, blue, white);
color-mix(in lch, blue, white);
color-mix(in oklch, blue, white);
color-mix(in lab, blue, white);
color-mix(in oklab, blue, white);
color-mix(in xyz, blue, white);

Функция color-mix() предоставляет давно запрашиваемую возможность: сохранение непрозрачных значений цвета при одновременном добавлении к ним некоторой прозрачности. Теперь вы можете использовать переменные цвета вашего бренда, создавая вариации этих цветов с разной степенью непрозрачности. Для этого нужно смешать цвет с прозрачным элементом. Если смешать ваш фирменный синий цвет с 10% прозрачного элемента, вы получите фирменный цвет с 90% непрозрачностью. Вы можете увидеть, как это позволяет быстро создавать цветовые системы.
Сегодня вы можете увидеть это в действии в инструментах разработчика Chrome: в панели стилей появится очень симпатичная иконка в виде диаграммы Венна для предварительного просмотра.

Больше примеров и подробностей вы найдете в нашей статье в блоге о color-mix или можете попробовать этот пример использования color-mix().
Основы CSS
Создание новых возможностей, которые явно принесут пользу пользователям, — это лишь одна часть задачи, но многие функции, появляющиеся в Chrome, направлены на улучшение опыта разработчиков и создание более надежной и организованной архитектуры CSS. К таким функциям относятся вложенность CSS, каскадные слои, стили с областью видимости, тригонометрические функции и отдельные свойства преобразования.
Гнездование
Вложенность CSS, функция, полюбившаяся разработчикам Sass и являвшаяся одним из самых востребованных запросов CSS-разработчиков на протяжении многих лет, наконец-то появилась на веб-платформе. Вложенность позволяет разработчикам писать код в более лаконичном, сгруппированном формате, что уменьшает избыточность.
.card {}
.card:hover {}
/* can be done with nesting like */
.card {
&:hover {
}
}
Вы также можете вкладывать медиа-запросы друг в друга, что также означает возможность вложения запросов контейнера . В следующем примере карточка меняет свою ориентацию с портретной на альбомную, если в её контейнере достаточно ширины:
.card {
display: grid;
gap: 1rem;
@container (width >= 480px) {
display: flex;
}
}
Адаптация макета к flex происходит, когда контейнер имеет более (или равное) 480px свободного пространства внутри строки. Браузер просто применит новый стиль отображения, когда будут выполнены условия.
Для получения дополнительной информации и примеров ознакомьтесь с нашей статьей о вложенности CSS .
Каскадные слои
Ещё одна проблема, с которой сталкиваются разработчики, — это обеспечение единообразия в приоритете одних стилей над другими, и одним из способов решения этой проблемы является улучшение контроля над каскадностью CSS-стилей.
Каскадные слои решают эту проблему, предоставляя пользователям возможность контролировать, какие слои имеют более высокий приоритет, чем другие, что означает более точный контроль над тем, когда применяются ваши стили.


Подробнее о том, как использовать каскадные слои, вы можете узнать в этой статье .
CSS с областью видимости
CSS-стили с областью видимости позволяют разработчикам указывать границы, в пределах которых применяются конкретные стили, по сути, создавая собственные пространства имен в CSS. Раньше разработчики полагались на сторонние скрипты для переименования классов или на специальные соглашения об именовании для предотвращения конфликтов стилей, но скоро вы сможете использовать @scope .
Здесь мы ограничиваем область видимости элемента .title элементом .card . Это предотвратит конфликт элемента `.title` с другими элементами .title на странице, такими как заголовок записи в блоге или другой заголовок.
@scope (.card) {
.title {
font-weight: bold;
}
}
В этой демонстрации в реальном времени вы можете увидеть @scope с ограничениями области видимости вместе с @layer :

Подробнее об @scope можно узнать в спецификации `css-cascade-6` .
Тригонометрические функции
Ещё одним нововведением в CSS является добавление тригонометрических функций к существующим математическим функциям CSS. Эти функции теперь стабильно работают во всех современных браузерах и позволяют создавать более органичные макеты на веб-платформе. Отличный пример — это радиальное меню, которое теперь можно проектировать и анимировать с помощью функций sin() и cos() .
В приведенной ниже демонстрации точки вращаются вокруг центральной точки. Вместо вращения каждой точки вокруг своего центра и последующего перемещения ее наружу, каждая точка перемещается по осям X и Y. Расстояния по осям X и Y определяются с учетом cos() и sin() --angle соответственно.
Более подробную информацию по этой теме вы найдете в нашей статье о тригонометрических функциях .
Индивидуальные свойства преобразования
Эргономика для разработчиков продолжает улучшаться благодаря функциям индивидуального преобразования. С момента нашей последней конференции I/O, функция индивидуального преобразования стала стабильно работать во всех современных браузерах.
Раньше для масштабирования, вращения и перемещения элементов пользовательского интерфейса приходилось использовать функцию transform. Это требовало множества повторений и было особенно неудобно при применении нескольких преобразований в разные моменты анимации.
.target {
transform: translateX(50%) rotate(30deg) scale(1.2);
}
.target:hover {
transform: translateX(50%) rotate(30deg) scale(2); /* Only scale changed here, yet you have to repeat all other parts */
}
Теперь вы можете добавить все эти детали в свои CSS-анимации, разделив типы преобразований и применяя их по отдельности.
.target {
translate: 50% 0;
rotate: 30deg;
scale: 1.2;
}
.target:hover {
scale: 2;
}
Благодаря этому изменения в перемещении, вращении или масштабировании могут происходить одновременно с разной скоростью и в разное время в течение анимации.
Более подробную информацию об отдельных функциях преобразования можно найти в этой статье .
Настраиваемые компоненты
Чтобы убедиться, что мы удовлетворяем некоторые ключевые потребности разработчиков через веб-платформу, мы сотрудничаем с сообществом OpenUI и определили три решения для начала:
- Встроенная функция всплывающих окон с обработчиками событий, декларативная структура DOM и доступные значения по умолчанию.
- CSS API для связывания двух элементов друг с другом с целью обеспечения позиционирования с помощью привязки (якорного позиционирования).
- Компонент выпадающего меню с возможностью настройки стиля содержимого, доступного в выпадающем списке.
Поповер
API всплывающих окон предоставляет элементам некоторые встроенные функции поддержки браузеров, такие как:
- Поддержка верхнего слоя, поэтому вам не нужно управлять
z-index. При открытии всплывающего окна или диалогового окна вы перемещаете этот элемент на специальный слой поверх страницы. - Функция
autoзакрытия всплывающих окон обеспечивает автоматическое закрытие при щелчке вне элемента, удаляя всплывающее окно из дерева специальных возможностей и корректно управляя фокусом. - Доступность по умолчанию для соединительной ткани целевого элемента всплывающего окна и самого всплывающего окна.
Всё это означает, что для создания всего этого функционала и отслеживания всех этих состояний требуется написать меньше кода на JavaScript.

Структура DOM для всплывающих окон является декларативной и может быть описана достаточно просто, указав элементу всплывающего окна id и атрибут ` popover . Затем этот идентификатор синхронизируется с элементом, который будет открывать всплывающее окно, например, с кнопкой с атрибутом popovertarget .
<div id="event-popup" popover>
<!-- Popover content goes in here -–>
</div>
<button popovertarget="event-popup">Create New Event</button>
popover — это сокращение от popover=auto . Элемент с popover=auto принудительно закрывает другие всплывающие окна при открытии, получает фокус при открытии и может быть легко закрыт. Напротив, элементы popover=manual не принудительно закрывают никакие другие типы элементов, не получают фокус немедленно и не закрываются легко. Они закрываются с помощью переключателя или другого действия закрытия.
Самую актуальную документацию по всплывающим окнам в настоящее время можно найти на MDN .
Позиционирование якоря
Всплывающие подсказки также часто используются в таких элементах, как диалоговые окна и всплывающие подсказки, которые обычно должны быть привязаны к определенным элементам. Рассмотрим этот пример события. Когда вы щелкаете по событию в календаре, рядом с ним появляется диалоговое окно. Элемент календаря является якорем, а всплывающее окно — это диалоговое окно, отображающее подробную информацию о событии.
Вы можете создать центрированную всплывающую подсказку с помощью функции anchor() , используя ширину, заданную якорем, для позиционирования подсказки на уровне 50% от координаты якоря по оси X. Затем используйте существующие значения позиционирования для применения остальных стилей размещения.
Но что произойдет, если всплывающее окно не поместится в область просмотра из-за выбранного вами положения?

Для решения этой проблемы API позиционирования якорей включает резервные позиции, которые можно настроить. В следующем примере создается резервная позиция под названием "сверху-снизу". Браузер сначала попытается расположить всплывающую подсказку вверху, и если она не поместится в область просмотра, он расположит ее под якорным элементом, внизу.
.center-tooltip {
position-fallback: --top-then-bottom;
translate: -50% 0;
}
@position-fallback --top-then-bottom {
@try {
bottom: calc(anchor(top) + 0.5rem);
left: anchor(center);
}
@try {
top: calc(anchor(bottom) + 0.5rem);
left: anchor(center);
}
}
Подробнее о позиционировании опорных точек читайте в этой статье блога .
<selectmenu>
Благодаря возможности позиционирования всплывающих окон и ссылок вы можете создавать полностью настраиваемые выпадающие меню. Группа сообщества OpenUI изучает фундаментальную структуру этих меню и ищет способы обеспечить возможность настройки любого содержимого внутри них. Рассмотрим эти наглядные примеры:

Чтобы создать пример selectmenu слева, где цветные точки соответствуют цвету, отображаемому в событии календаря, можно написать его следующим образом:
<selectmenu>
<button slot="button" behavior="button">
<span>Select event type</span>
<span behavior="selected-value" slot="selected-value"></span>
<span><img src="icon.svg"/></span>
</button>
<option value="meeting">
<figure class="royalblue"></figure>
<p>Meeting</p>
</option>
<option value="break">
<figure class="gold"></figure>
<p>Lunch/Break</p>
</option>
...
</selectmenu>
Дискретные переходы свойств
Для того чтобы всплывающие окна плавно появлялись и исчезали, веб-технологиям необходим способ анимации отдельных свойств. Это свойства, которые раньше обычно не поддавались анимации, например, анимация перехода на верхний слой и обратно, а также анимация перехода на экран с display: none обратно.
В рамках работы по обеспечению плавных переходов для всплывающих окон, выпадающих меню и даже существующих элементов, таких как диалоговые окна или пользовательские компоненты, браузеры внедряют новые механизмы для поддержки этих анимаций.
В приведенном ниже примере всплывающие окна анимируются при появлении и исчезновении с помощью :popover-open для открытого состояния, @starting-style для состояния перед открытием и применяют значение `transform` непосредственно к элементу в состоянии после закрытия (после открытия). Чтобы все это работало с `display`, необходимо добавить это в свойство transition , следующим образом:
.settings-popover {
&:popover-open {
/* 0. before-change */
@starting-style {
transform: translateY(20px);
opacity: 0;
}
/* 1. open (changed) state */
transform: translateY(0);
opacity: 1;
}
/* 2. After-change state */
transform: translateY(-50px);
opacity: 0;
/* enumarate transitioning properties, including display */
transition: transform 0.5s, opacity 0.5s, display 0.5s allow-discrete;
}
Взаимодействия
Это подводит нас к интерактивным функциям, последней остановке в этом обзоре возможностей веб-интерфейса.
Мы уже говорили об анимации отдельных свойств, но в Chrome также появляются действительно интересные API, связанные с анимацией при прокрутке и переходами между представлениями.
Анимация, управляемая прокруткой
Анимация, управляемая прокруткой, позволяет контролировать воспроизведение анимации в зависимости от положения элемента в контейнере прокрутки. Это означает, что при прокрутке вверх или вниз анимация будет перемещаться вперед или назад. Кроме того, с помощью анимации, управляемой прокруткой, вы также можете управлять анимацией в зависимости от положения элемента внутри его контейнера прокрутки. Это позволяет создавать интересные эффекты, такие как параллаксное фоновое изображение, индикаторы выполнения прокрутки и изображения, которые появляются по мере приближения к экрану.
Этот API поддерживает набор классов JavaScript и свойств CSS, позволяющих легко создавать декларативные анимации, управляемые прокруткой.
Для управления CSS-анимацией при прокрутке используйте новые свойства scroll-timeline , view-timeline и animation-timeline . Для управления JavaScript Web Animations API передайте экземпляр ScrollTimeline или ViewTimeline в качестве параметра timeline в Element.animate()
Эти новые API работают совместно с существующими API веб-анимаций и CSS-анимаций, а это значит, что они используют преимущества этих API. В частности, это включает возможность запуска анимаций вне основного потока. Да, вы правильно прочитали: теперь вы можете создавать плавные анимации, управляемые прокруткой, в основном потоке, всего лишь добавив несколько строк кода. Что тут может не понравиться?!
Подробное руководство по созданию анимаций, управляемых прокруткой, вы найдете в этой статье .
Просмотр переходов
API View Transition позволяет легко изменять DOM за один шаг, создавая при этом анимированный переход между двумя состояниями. Это могут быть простые эффекты затухания между представлениями, но вы также можете управлять тем, как должны происходить переходы между отдельными частями страницы.
Переходы между представлениями можно использовать в качестве прогрессивного улучшения: возьмите свой код, который обновляет DOM любым методом, и оберните его в API переходов между представлениями с резервным вариантом для браузеров, которые не поддерживают эту функцию.
function spaNavigate(data) {
// Fallback for browsers that don't support this API:
if (!document.startViewTransition) {
updateTheDOMSomehow(data);
return;
}
// With a transition:
document.startViewTransition(() => updateTheDOMSomehow(data));
}
Внешний вид перехода контролируется с помощью CSS.
@keyframes slide-from-right {
from { opacity: 0; transform: translateX(75px); }
}
@keyframes slide-to-left {
to { opacity: 0; transform: translateX(-75px); }
}
::view-transition-old(root) {
animation: 350ms both slide-to-left ease;
}
::view-transition-new(root) {
animation: 350ms both slide-from-right ease;
}
Как показано в этой замечательной демонстрации Макси Феррейры , другие интерактивные элементы страницы, такие как воспроизводимое видео, продолжают работать во время выполнения перехода между представлениями.
В настоящее время функция перехода между окнами работает с одностраничными приложениями (SPA) в Chrome 111. Поддержка многостраничных приложений находится в разработке. Для получения более подробной информации ознакомьтесь с нашим подробным руководством по переходу между окнами.
Заключение
Следите за всеми последними новинками в CSS и HTML прямо здесь, на developer.chrome.com , и смотрите видеоролики I/O, чтобы увидеть больше примеров веб-приложений.