Возможности веб-стиля сегодняшнего и завтрашнего дня, представленные на Google IO 2022, а также некоторые дополнительные возможности.
2022 год станет одним из величайших годов CSS, как с точки зрения функций, так и совместных выпусков функций браузера, с совместной целью реализовать 14 функций!
Обзор
Этот пост представляет собой статью в форме доклада, прозвучавшего на Google IO 2022. Он не предназначен для того, чтобы быть подробным руководством по каждой функции, а скорее представляет собой введение и краткий обзор, призванный пробудить ваш интерес, предоставляя широту, а не глубину. Если ваш интерес заинтересовался, проверьте в конце раздела ссылки на ресурсы для получения дополнительной информации.
Оглавление
Используйте список ниже, чтобы перейти к интересующим темам:
Совместимость с браузером
Основная причина, по которой так много функций CSS планируется выпустить совместно, связана с усилиями Interop 2022 . Прежде чем изучать усилия Interop, важно взглянуть на усилия Compat 2021 .
Совместимость 2021
Цели на 2021 год, основанные на отзывах разработчиков через опросы, заключались в стабилизации текущих функций, улучшении набора тестов и повышении проходных баллов браузеров по пяти функциям:
-
sticky
позиционирование - изменение
aspect-ratio
-
flex
макет -
grid
-
transform
позиционирование и анимацию
Результаты тестов были повышены по всем направлениям, что продемонстрировало повышенную стабильность и надежность. Поздравляем команды здесь!
Взаимодействие 2022
В этом году браузеры встретились, чтобы обсудить функции и приоритеты, над которыми они намеревались работать, объединив свои усилия. Они планировали предоставить разработчикам следующие веб-функции:
-
@layer
- Цветовые пространства и функции
- Сдерживание
-
<dialog>
- Совместимость форм
- Прокрутка
- Подсетка
- Типография
- Единицы видового экрана
- Веб-совместимость
Это захватывающий и амбициозный список, и мне не терпится увидеть его раскрытие.
Новинка 2022 года
Неудивительно, что на состояние CSS 2022 существенно влияет работа Interop 2022.
Каскадные слои
До появления @layer
обнаруженный порядок загруженных таблиц стилей был очень важен, поскольку стили, загруженные последними, могли перезаписать ранее загруженные стили. Это привело к тщательно управляемым таблицам стилей ввода, в которые разработчикам приходилось сначала загружать менее важные стили, а затем более важные. Существуют целые методологии, помогающие разработчикам управлять этой важностью, такие как ITCSS .
С помощью @layer
входной файл может заранее определить слои и их порядок. Затем, когда стили загружаются, загружаются или определяются, их можно поместить в слой, что позволяет сохранить важность переопределения стиля, но без тщательно управляемой оркестрации загрузки.
Видео показывает, как определенные каскадные слои обеспечивают более свободный и свободный процесс разработки и загрузки, сохраняя при этом каскад по мере необходимости.
Chrome DevTools помогает визуализировать, какие стили из каких слоев берутся:
Ресурсы
- Спецификация CSS Cascade 5
- Объяснение каскадных слоев
- Каскадные слои в MDN
- Уна Кравец : каскадные слои
- Ахмад Шадид : Привет, каскадные слои CSS.
Подсетка
До появления subgrid
сетка внутри другой сетки не могла выравниваться по родительским ячейкам или линиям сетки. Каждый макет сетки был уникальным. Многие дизайнеры размещают единую сетку по всему дизайну и постоянно выравнивают элементы внутри нее, что невозможно сделать с помощью CSS.
После subgrid
дочерний элемент сетки может принять столбцы или строки своих родителей как свои собственные и выровнять себя или дочерние элементы по ним!
В следующей демонстрации элемент body создает классическую сетку из трех столбцов: средний столбец называется main
, а левый и правый столбцы называют свои строки fullbleed
. Затем каждый элемент тела, <nav>
и <main>
, принимает именованные строки из тела, устанавливая grid-template-columns: subgrid
.
body {
display: grid;
grid-template-columns:
[fullbleed-start]
auto [main-start] min(90%, 60ch) [main-end] auto
[fullbleed-end]
;
}
body > * {
display: grid;
grid-template-columns: subgrid;
}
Наконец, дочерние элементы <nav>
или <main>
могут выравниваться или изменять свой размер, используя fullbleed
и main
столбцы и строки.
.main-content {
grid-column: main;
}
.fullbleed {
grid-column: fullbleed;
}
Devtools может помочь вам увидеть линии и подсетки (на данный момент только Firefox). На следующем изображении родительская сетка и подсетки наложены друг на друга. Теперь это напоминает то, как дизайнеры думали о планировке.
На панели элементов инструментов разработчика вы можете увидеть, какие элементы являются сетками и подсетками, что очень полезно для отладки или проверки макета.
Ресурсы
Контейнерные запросы
До появления @container
элементы веб-страницы могли реагировать только на размер всей области просмотра. Это отлично подходит для макромакетов, но для микромакетов, где их внешний контейнер не является всей областью просмотра, макет невозможно соответствующим образом настроить.
После @container
элементы могут реагировать на размер или стиль родительского контейнера! Единственное предостережение: контейнеры должны объявлять себя возможными целями запроса, а это небольшое требование, дающее большую выгоду.
/* establish a container */
.day {
container-type: inline-size;
container-name: calendar-day;
}
Благодаря этим стилям столбцы Mon, Tues, Wed, Thurs и Fri в следующем видео могут быть запрошены элементами событий.
Вот CSS для запроса размера контейнера calendar-day
, а затем настройки макета и размеров шрифта:
@container calendar-day (max-width: 200px) {
.date {
display: block;
}
.date-num {
font-size: 2.5rem;
display: block;
}
}
Вот еще один пример: один компонент книги адаптируется к доступному пространству в столбце, в который он перетаскивается:
Уна права в оценке ситуации как нового реагирования . При использовании @container
можно принять множество интересных и значимых дизайнерских решений.
Ресурсы
- Спецификация контейнерных запросов
- Объяснение контейнерных запросов
- Контейнерные запросы в MDN
- Новый адаптивный подход на web.dev
- Демо-версия календаря от Una
- Потрясающая коллекция контейнерных запросов
- Как мы создали Designcember на web.dev
- Ахмад Шадид : Привет CSS-запросам-контейнерам
accent-color
До появления accent-color
, когда вам нужна была форма с цветами, соответствующими бренду, вы могли столкнуться со сложными библиотеками или решениями CSS, которыми со временем становилось трудно управлять. Хотя они предоставили вам все возможности и, надеюсь, включили в себя доступность, выбор между использованием встроенных компонентов или принятием собственных становится утомительным, чтобы продолжать выбирать.
После accent-color
одна строка CSS добавляет цвет бренда к встроенным компонентам. Помимо оттенка, браузер разумно выбирает подходящие контрастные цвета для вспомогательных частей компонента и адаптируется к цветовым схемам системы (светлым или темным).
/* tint everything */
:root {
accent-color: hotpink;
}
/* tint one element */
progress {
accent-color: indigo;
}
Чтобы узнать больше об accent-color
, прочтите мою публикацию на web.dev , где я рассматриваю многие другие аспекты этого полезного свойства CSS.
Ресурсы
- спецификация акцентного цвета
- цвет-акцент на MDN
- цвет акцента на web.dev
- Bramus : Оттенок элементов управления пользовательского интерфейса с помощью CSS-цвета акцента
Уровень цвета 4 и 5
В последние десятилетия в Интернете доминировал sRGB, но в расширяющемся цифровом мире дисплеев высокой четкости и мобильных устройств, предварительно оснащенных экранами OLED или QLED, sRGB недостаточно. Кроме того, ожидаются динамические страницы, которые адаптируются к предпочтениям пользователя, а управление цветом вызывает растущую озабоченность дизайнеров, систем проектирования и разработчиков кода.
Но не в 2022 году — CSS имеет ряд новых цветовых функций и пространств: — Цвета, которые соответствуют цветовым возможностям HD-дисплеев. - Цветовые пространства, соответствующие замыслу, например единообразие восприятия. - Цветовые пространства для градиентов, которые радикально меняют результаты интерполяции. - Функции цвета, которые помогут вам смешивать и контрастировать, а также выбирать, в каком пространстве вы будете работать.
До появления всех этих цветовых функций системам дизайна необходимо было заранее рассчитывать правильные контрастные цвета и обеспечивать достаточно яркие палитры, в то время как препроцессоры или JavaScript выполняли тяжелую работу.
После всех этих функций цвета браузер и CSS могут выполнять всю работу динамично и точно в срок. Вместо отправки пользователям многих КБ CSS и JavaScript для включения цветов тем и визуализации данных, CSS может выполнять оркестрацию и вычисления. CSS также лучше приспособлен для проверки поддержки перед использованием или корректной обработки резервных вариантов.
@media (dynamic-range: high) {
.neon-pink {
--neon-glow: color(display-p3 1 0 1);
}
}
@supports (color: lab(0% 0 0)) {
.neon-pink {
--neon-glow: lab(150% 160 0);
}
}
hwb()
HWB означает оттенок, белизну и черноту. Он представляет собой удобный для человека способ выражения цвета, поскольку это всего лишь оттенок и количество белого или черного цвета, которые можно осветлить или затемнить. Художники, смешивающие цвета с белым или черным, возможно, оценят это дополнение цветового синтаксиса.
Использование этой цветовой функции приводит к получению цветов из цветового пространства sRGB, такого же, как HSL и RGB. Что касается новизны 2022 года, это не придаёт вам новых красок, но может облегчить некоторые задачи любителям синтаксиса и ментальной модели.
Ресурсы
Цветовые пространства
Представление цветов осуществляется с помощью цветового пространства. Каждое цветовое пространство предлагает различные функции и компромиссы для работы с цветом. Некоторые могут объединить все яркие цвета вместе; некоторые могут сначала выстроить их в ряд, исходя из их легкости.
В 2022 году CSS предложит 10 новых цветовых пространств, каждое из которых обладает уникальными функциями, которые помогут дизайнерам и разработчикам отображать, выбирать и смешивать цвета. Раньше sRGB был единственным вариантом работы с цветом, но теперь CSS открывает новый потенциал и новое цветовое пространство по умолчанию — LCH.
color-mix()
До появления color-mix()
разработчикам и дизайнерам требовались препроцессоры, такие как Sass, для смешивания цветов до того, как их увидит браузер. Большинство функций смешивания цветов также не предоставляли возможности указать, в каком цветовом пространстве выполнять смешивание, что иногда приводило к запутанным результатам.
После color-mix()
разработчики и дизайнеры могут смешивать цвета в браузере вместе со всеми другими стилями, не запуская процессы сборки и не включая JavaScript. Кроме того, они могут указать, в каком цветовом пространстве выполнять смешивание, или использовать цветовое пространство смешивания по умолчанию LCH.
Часто цвет бренда используется в качестве основы и на его основе создаются варианты, например, более светлые или темные цвета для стилей при наведении. Вот как это выглядит с помощью color-mix()
:
.color-mix-example {
--brand: #0af;
--darker: color-mix(var(--brand) 25%, black);
--lighter: color-mix(var(--brand) 25%, white);
}
и если вы хотите смешать эти цвета в другом цветовом пространстве, например srgb, измените его:
.color-mix-example {
--brand: #0af;
--darker: color-mix(in srgb, var(--brand) 25%, black);
--lighter: color-mix(in srgb, var(--brand) 25%, white);
}
Ниже следует демонстрация тем с использованием color-mix()
. Попробуйте изменить цвет бренда и посмотрите обновление темы:
Наслаждайтесь смешиванием цветов в различных цветовых пространствах в своих таблицах стилей в 2022 году!
Ресурсы
- спецификация color-mix()
- color-mix() на MDN
- Тематическая демонстрация
- Еще одна тематическая демонстрация
- Фабио Джолито : Создайте цветовую тему с помощью новых функций CSS.
color-contrast()
До появления color-contrast()
авторам таблиц стилей необходимо было заранее знать доступные цвета. Часто палитра отображает черный или белый текст на образце цвета, чтобы указать пользователю цветовой системы, какой цвет текста потребуется для правильного контраста с этим образцом.
После color-contrast()
авторы таблиц стилей могут полностью переложить задачу на браузер. Вы можете не только использовать браузер для автоматического выбора черного или белого цвета, но и предоставить ему список цветов, подходящих для системы дизайна, и заставить его выбрать первый, соответствующий желаемому коэффициенту контрастности.
Вот скриншот демонстрационного набора цветовой палитры HWB , где цвета текста автоматически выбираются браузером на основе образца цвета:
Основы синтаксиса выглядят следующим образом: в функцию передается серый цвет, и браузер определяет, какой контраст больше: черный или белый:
color: color-contrast(gray);
Функцию также можно настроить с помощью списка цветов, из которого она выберет наиболее контрастный цвет:
color: color-contrast(gray vs indigo, rebeccapurple, hotpink);
Наконец, если предпочтительно не выбирать из списка самый контрастный цвет, можно указать целевой коэффициент контрастности и выбрать первый цвет, который его пройдет:
color: color-contrast(
var(--bg-blue-1)
vs
var(--text-lightest), var(--text-light), var(--text-subdued)
to AA /* 4.5 could also be passed */
);
Эту функцию можно использовать не только для цвета текста, хотя, по моим оценкам, это будет ее основной вариант использования. Подумайте, насколько проще будет создавать доступные и разборчивые интерфейсы, если выбор правильных контрастных цветов будет встроен в сам язык CSS.
Ресурсы
Относительный синтаксис цвета
До появления синтаксиса относительного цвета для расчета цвета и внесения корректировок цветовые каналы необходимо было индивидуально поместить в пользовательские свойства. Это ограничение также сделало HSL основной цветовой функцией для управления цветами, поскольку оттенок, насыщенность или яркость можно было легко настроить с помощью calc()
.
После синтаксиса относительного цвета любой цвет в любом пространстве можно деконструировать, изменить и вернуть как цвет, и все это в одной строке CSS. Никаких ограничений для HSL больше нет — манипуляции можно выполнять в любом желаемом цветовом пространстве, и для облегчения этого необходимо создавать гораздо меньше пользовательских свойств.
В следующем примере синтаксиса предоставляется базовый шестнадцатеричный код и относительно него создаются два новых цвета. Первый цвет --absolute-change
создает новый цвет в LCH из базового цвета, затем заменяет яркость базового цвета на 75%
, сохраняя цветность ( c
) и оттенок ( h
). Второй цвет --relative-change
создает в LCH новый цвет из базового цвета, но на этот раз уменьшает цветность ( c
) на 20%.
.relative-color-syntax {
--color: #0af;
--absolute-change: lch(from var(--color) 75% c h);
--relative-change: lch(from var(--color) l calc(c-20%) h);
}
Это похоже на смешивание цветов, но больше похоже на изменения, чем на смешивание. Вы можете получить цвет из другого цвета, получив доступ к трем значениям каналов, названным в соответствии с используемой цветовой функцией, с возможностью настройки этих каналов. В общем, это очень крутой и мощный синтаксис цвета.
В следующей демонстрации я использовал синтаксис относительного цвета для создания более светлых и темных вариантов базового цвета и использовал color-contrast()
чтобы обеспечить правильный контраст меток:
Эту функцию также можно использовать для создания цветовой палитры. Вот демо-версия, в которой целые палитры генерируются на основе предоставленного базового цвета. Этот один набор CSS поддерживает все различные палитры, каждая палитра просто предоставляет другую основу. В качестве бонуса, поскольку я использовал LCH, посмотрите, насколько воспринимаемы даже палитры — благодаря этому цветовому пространству не видно никаких горячих или мертвых зон.
:root {
--_color-base: #339af0;
--color-0: lch(from var(--_color-base) 98% 10 h);
--color-1: lch(from var(--_color-base) 93% 20 h);
--color-2: lch(from var(--_color-base) 85% 40 h);
--color-3: lch(from var(--_color-base) 75% 46 h);
--color-4: lch(from var(--_color-base) 66% 51 h);
--color-5: lch(from var(--_color-base) 61% 52 h);
--color-6: lch(from var(--_color-base) 55% 57 h);
--color-7: lch(from var(--_color-base) 49% 58 h);
--color-8: lch(from var(--_color-base) 43% 55 h);
--color-9: lch(from var(--_color-base) 39% 52 h);
--color-10: lch(from var(--_color-base) 32% 48 h);
--color-11: lch(from var(--_color-base) 25% 45 h);
--color-12: lch(from var(--_color-base) 17% 40 h);
--color-13: lch(from var(--_color-base) 10% 30 h);
--color-14: lch(from var(--_color-base) 5% 20 h);
--color-15: lch(from var(--_color-base) 1% 5 h);
}
Надеюсь, теперь вы понимаете, как цветовые пространства и различные цветовые функции могут использоваться для разных целей, в зависимости от их сильных и слабых сторон.
Ресурсы
- Спецификация синтаксиса относительного цвета
- Создание цветовых палитр с относительным цветовым синтаксисом
- Создание вариантов цвета с относительным синтаксисом цветов
Градиентные цветовые пространства
До появления градиентных цветовых пространств по умолчанию использовалось цветовое пространство sRGB. sRGB в целом надежен, но имеет некоторые недостатки, такие как серая мертвая зона .
После градиентных цветовых пространств сообщите браузеру, какое цветовое пространство использовать для интерполяции цвета. Это дает разработчикам и дизайнерам возможность выбирать градиент, который они предпочитают. Цветовое пространство по умолчанию также меняется на LCH вместо sRGB.
Добавление синтаксиса идет после направления градиента, использует новый in
и является необязательным:
background-image: linear-gradient(
to right in hsl,
black, white
);
background-image: linear-gradient(
to right in lch,
black, white
);
Вот базовый и важный градиент от черного к белому. Посмотрите на диапазон результатов в каждом цветовом пространстве. Некоторые достигают темно-черного цвета раньше других, некоторые выцветают до белого слишком поздно.
В следующем примере черный цвет превращается в синий, поскольку это известная проблемная область для градиентов. Большинство цветовых пространств переходят в фиолетовый цвет во время цветовой интерполяции или, как мне нравится это думать, когда цвета перемещаются внутри своего цветового пространства из точки А в точку Б. Поскольку градиент будет проходить по прямой линии от точки А до точки Б, форма цветового пространства радикально меняет остановки, которые проходит путь.
Более глубокие исследования, примеры и комментарии можно найти в этой теме в Твиттере .
Ресурсы
- Спецификация градиентной интерполяции
- Демонстрация сравнения градиентов в пространствах
- Наблюдаемый блокнот для сравнения градиентов
inert
До появления inert
хорошей практикой было направлять внимание пользователя на те области страницы или приложения, которые требовали немедленного внимания. Эта стратегия управляемого фокуса стала известна как захват фокуса, потому что разработчики помещали фокус в интерактивное пространство, прослушивали события изменения фокуса, и, если фокус покидал интерактивное пространство, он возвращался обратно. Пользователи, пользующиеся клавиатурой или программами чтения с экрана, направляются назад. в интерактивное пространство, чтобы убедиться, что задача выполнена, прежде чем двигаться дальше.
После inert
перехват не требуется, поскольку вы можете заморозить или защитить целые разделы страницы или приложения. Щелчки и попытки изменения фокуса просто недоступны, пока эти части документа инертны. Можно также думать об этом как об охранниках, а не о ловушках, где inert
не заинтересован в том, чтобы вы оставались где-то, а скорее делает другие места недоступными.
Хорошим примером этого является функция alert()
в JavaScript:
Обратите внимание, что в предыдущем видео страница была доступна с помощью мыши и клавиатуры до тех пор, пока не был вызван метод alert()
. После отображения всплывающего диалогового окна предупреждения остальная часть страницы была заморожена или inert
. Внимание пользователей сосредоточено внутри диалогового окна предупреждения, и ему больше некуда идти. Как только пользователь взаимодействует и выполняет запрос функции оповещения, страница снова становится интерактивной. inert
позволяет разработчикам с легкостью добиться такого же эффекта управляемой фокусировки.
Вот небольшой пример кода, показывающий, как это работает:
<body>
<div class="modal">
<h2>Modal Title</h2>
<p>...<p>
<button>Save</button>
<button>Discard</button>
</div>
<main inert>
<!-- cannot be keyboard focused or clicked -->
</main>
</body>
Диалог — отличный пример, но inert
также полезен для таких вещей, как выдвижное боковое меню. Когда пользователь выдвигает боковое меню, нельзя позволять мыши или клавиатуре взаимодействовать со страницей позади него; это немного сложно для пользователей. Вместо этого, когда отображается боковое меню, сделайте страницу инертной, и теперь пользователи должны закрывать это боковое меню или перемещаться по нему и никогда не потеряются где-нибудь еще на странице с открытым меню.
Ресурсы
Шрифты COLRv1
До появления шрифтов COLRv1 в Интернете были шрифты OT-SVG , а также открытый формат шрифтов с градиентами, встроенными цветами и эффектами. Однако они могли стать очень большими, и, хотя они позволяли редактировать текст, возможностей для настройки было мало.
После шрифтов COLRv1 в Интернете появились шрифты меньшего размера, векторного масштабирования, изменения положения, градиента и режима наложения, которые принимают параметры для настройки шрифта для каждого случая использования или для соответствия бренду.
Вот пример сообщения в блоге разработчиков Chrome о смайлах. Возможно, вы заметили, что если увеличить размер шрифта смайлика, он не останется четким. Это изображение, а не векторная графика. Часто в приложениях, когда используется смайлик, он заменяется на более качественный ресурс. Благодаря шрифтам COLRv1 смайлы получаются векторными и красивыми:
Иконочные шрифты могут творить с этим форматом удивительные вещи, предлагая пользовательские двухтоновые цветовые палитры и многое другое. Загрузка шрифта COLRv1 аналогична загрузке любого другого файла шрифта:
@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);
Настройка шрифта COLRv1 выполняется с помощью @font-palette-values
, специального правила CSS для группировки и именования набора параметров настройки в пакет для дальнейшего использования. Обратите внимание, как вы указываете пользовательское имя, как и пользовательское свойство, начиная с --
:
@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);
@font-palette-values --colorized {
font-family: "Bungee Spice";
base-palette: 0;
override-colors: 0 hotpink, 1 cyan, 2 white;
}
Если --colorized
является псевдонимом для настроек, последним шагом будет применение палитры к элементу, использующему семейство цветных шрифтов:
@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);
@font-palette-values --colorized {
font-family: "Bungee Spice";
base-palette: 0;
override-colors: 0 hotpink, 1 cyan, 2 white;
}
.spicy {
font-family: "Bungee Spice";
font-palette: --colorized;
}
Поскольку становится доступным все больше и больше вариативных и цветных шрифтов, веб-типографика находится на великолепном пути к богатой настройке и творческому самовыражению.
Ресурсы
- Спецификация Colrv1 на Github
- Разработчики Chrome: шрифты Colrv1
- Объясняющее видео для разработчиков BlinkOn
Единицы видового экрана
До появления новых вариантов области просмотра в Интернете предлагались физические единицы, помогающие подобрать область просмотра. Был один для высоты, ширины, наименьшего размера (vmin) и наибольшей стороны (vmax). Они хорошо работали во многих случаях, но мобильные браузеры создавали сложности.
На мобильных устройствах при загрузке страницы отображается строка состояния с URL-адресом, и эта панель занимает часть пространства области просмотра. Через несколько секунд и некоторую интерактивность строка состояния может сдвинуться, открывая пользователю больший обзор. Но когда эта полоса выдвигается, высота области просмотра изменяется, и любые блоки vh
будут смещаться и изменять размер по мере изменения их целевого размера. В последующие годы подразделению vh
пришлось решать, какой из двух размеров области просмотра он будет использовать, поскольку это вызывало неприятные проблемы с визуальным макетом на мобильных устройствах. Было решено, что vh
всегда будет представлять самую большую область просмотра.
.original-viewport-units {
height: 100vh;
width: 100vw;
--size: 100vmin;
--size: 100vmax;
}
После появления новых вариантов области просмотра стали доступны маленькие, большие и динамические единицы области просмотра с добавлением логических эквивалентов к физическим. Идея состоит в том, чтобы дать разработчикам и дизайнерам возможность выбирать, какое устройство они хотят использовать в своем конкретном сценарии. Возможно, это нормально, если произойдет небольшой резкий сдвиг макета, когда строка состояния исчезнет, поэтому тогда можно будет использовать dvh
(динамическую высоту области просмотра) без беспокойства.
Вот полный список всех новых вариантов единиц видового экрана, доступных в новых вариантах видового экрана:
.new-height-viewport-units { height: 100vh; height: 100dvh; height: 100svh; height: 100lvh; block-size: 100vb; block-size: 100dvb; block-size: 100svb; block-size: 100lvb; }
.new-width-viewport-units { width: 100vw; width: 100dvw; width: 100svw; width: 100lvw; inline-size: 100vi; inline-size: 100dvi; inline-size: 100svi; inline-size: 100lvi; }
.new-min-viewport-units { --size: 100vmin; --size: 100dvmin; --size: 100svmin; --size: 100lvmin; }
.new-max-viewport-units { --size: 100vmax; --size: 100dvmax; --size: 100svmax; --size: 100lvmax; }
Надеемся, что это даст разработчикам и дизайнерам гибкость, необходимую для создания адаптивного дизайна в области просмотра.
Ресурсы
- Спецификация относительных единиц видового экрана
- Bramus : большие, маленькие и динамические видовые экраны
:has()
До :has()
тема селектора всегда находилась в конце. Например, предметом этого селектора является элемент списка: ul > li
. Псевдоселекторы могут изменить селектор, но не меняют тему: ul > li:hover
или ul > li:not(.selected)
.
После :has()
субъект, находящийся выше в дереве элементов, может оставаться субъектом, обеспечивая при этом запрос о дочерних элементах: ul:has(> li)
. Легко понять, почему :has()
получил общее имя «родительский селектор», поскольку в этом случае субъект селектора теперь является родительским.
Вот базовый пример синтаксиса, в котором класс .parent
остается субъектом, но выбирается только в том случае, если дочерний элемент имеет класс .child
:
.parent:has(.child) {...}
Вот пример, где элементом <section>
является тема, но селектор соответствует только в том случае, если один из дочерних элементов имеет :focus-visible
:
section:has(*:focus-visible) {...}
Селектор :has()
начинает становиться фантастической утилитой, как только становятся очевидными более практичные варианты использования. Например, в настоящее время невозможно выбирать теги <a>
, когда они оборачивают изображения, что затрудняет обучение тега привязки изменению его стилей в этом случае использования. Хотя это возможно с помощью :has()
:
a:has(> img) {...}
Все это были примеры, когда :has()
выглядит только как родительский селектор. Рассмотрим вариант использования изображений внутри элементов <figure>
и настройку стилей изображений, если рисунок имеет <figcaption>
. В следующем примере выбираются рисунки с figcaptions, а затем изображения в этом контексте. :has()
используется и не меняет тему, поскольку объектом, на который мы ориентируемся, являются изображения, а не фигуры:
figure:has(figcaption) img {...}
Комбинации кажутся бесконечными. Объедините :has()
с запросами количества и настройте макеты сетки CSS в зависимости от количества дочерних элементов. Объедините :has()
с интерактивными состояниями псевдоклассов и создавайте приложения, реагирующие новыми творческими способами.
Проверка поддержки упрощается с помощью @supports
и ее функции selector()
, которая проверяет, понимает ли браузер синтаксис перед его использованием:
@supports (selector(:has(works))) {
/* safe to use :has() */
}
Ресурсы
- :has() спецификация
- :has() на MDN
- Селектор CSS
:has()
— это нечто большее, чем «родительский селектор».
2022 год и далее
Есть еще ряд вещей, которые будет сложно сделать после того, как все эти удивительные функции появятся в 2022 году. В следующем разделе рассматриваются некоторые оставшиеся проблемы и решения, которые активно разрабатываются для их решения. Эти решения являются экспериментальными, хотя они могут быть указаны или доступны за флажками в браузерах.
Выводом из следующих разделов должно быть то, что перечисленные проблемы заставляют многих людей из многих компаний искать решения, а не то, что эти решения будут выпущены в 2023 году.
Слабо типизированные пользовательские свойства
Пользовательские свойства CSS просто потрясающие. Они позволяют хранить все виды вещей внутри именованной переменной, которую затем можно расширять, вычислять, совместно использовать и т. д. На самом деле, они настолько гибкие, что было бы неплохо иметь менее гибкие.
Рассмотрим сценарий, в котором box-shadow
использует пользовательские свойства для своих значений:
box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);
Все это работает хорошо, пока какое-либо из свойств не будет изменено на значение, которое CSS не принимает, например --x: red
. Вся тень разрывается, если какая-либо из вложенных переменных отсутствует или ей присвоен недопустимый тип значения.
Здесь на помощь приходит @property
: --x
может стать типизированным пользовательским свойством, уже не свободным и гибким, а безопасным с некоторыми определенными границами:
@property --x {
syntax: '<length>';
initial-value: 0px;
inherits: false;
}
Теперь, когда box-shadow
использует var(--x)
и позже --x: red
, red
будет игнорироваться, поскольку это не <length>
. Это означает, что тень продолжает работать, даже если одному из ее пользовательских свойств было присвоено недопустимое значение. Вместо сбоя он возвращается к initial-value
0px
.
Анимация
Помимо безопасности типов, это также открывает множество возможностей для анимации. Гибкость синтаксиса CSS делает невозможной анимацию некоторых вещей, например градиентов. @property
здесь помогает, потому что типизированное свойство CSS может информировать браузер о намерениях разработчика внутри слишком сложной интерполяции. По сути, это ограничивает возможности настолько, что браузер может анимировать аспекты стиля, чего раньше он не мог.
Рассмотрим этот демонстрационный пример, где радиальный градиент используется для создания части наложения, создавая эффект фокусировки прожектора. JavaScript устанавливает координаты x и y мыши при нажатии клавиши alt/opt, а затем изменяет фокусный размер на меньшее значение, например 25 %, создавая круг фокусировки прожектора в позиции мыши:
.focus-effect {
--focal-size: 100%;
--mouse-x: center;
--mouse-y: center;
mask-image: radial-gradient(
circle at var(--mouse-x) var(--mouse-y),
transparent 0%,
transparent var(--focal-size),
black 0%
);
}
Однако градиенты нельзя анимировать. Они слишком гибкие и слишком сложные, чтобы браузер мог «просто определить», как вы хотите их анимировать. Однако с помощью @property
одно свойство можно ввести и анимировать изолированно, что позволяет браузеру легко понять назначение.
Видеоигры, в которых используется этот эффект фокуса, всегда анимируют круг: от большого до круга с точечным отверстием. Вот как можно использовать @property
в нашей демонстрации, чтобы браузер анимировал градиентную маску:
@property --focal-size {
syntax: '<length-percentage>';
initial-value: 100%;
inherits: false;
}
.focus-effect {
--focal-size: 100%;
--mouse-x: center;
--mouse-y: center;
mask-image: radial-gradient(
circle at var(--mouse-x) var(--mouse-y),
transparent 0%,
transparent var(--focal-size),
black 0%
);
transition: --focal-size .3s ease;
}
Браузер теперь может анимировать размер градиента, поскольку мы уменьшили площадь поверхности модификации до одного свойства и ввели значение, чтобы браузер мог разумно интерполировать длины.
@property
может сделать гораздо больше, но эти небольшие возможности могут иметь большое значение.
Ресурсы
- @property спецификация
- @property на MDN
- @property на сайте web.dev
- Демонстрация масштабирования фокуса
- CSS-хитрости: изучение @property и его возможностей анимации
Был в min-width
или max-width
Перед диапазонами медиа-запросов медиа-запрос CSS использует min-width
и max-width
для обозначения условий «над» и «под». Это может выглядеть так:
@media (min-width: 320px) {
…
}
После диапазонов медиазапросов тот же медиазапрос может выглядеть так:
@media (width >= 320px) {
…
}
Медиа-запрос CSS, использующий как min-width
так и max-width
может выглядеть следующим образом:
@media (min-width: 320px) and (max-width: 1280px) {
…
}
После диапазонов медиазапросов тот же медиазапрос может выглядеть так:
@media (320px <= width <= 1280px) {
…
}
В зависимости от вашего опыта программирования один из них будет выглядеть гораздо более разборчивым, чем другой. Благодаря дополнениям к спецификациям разработчики смогут выбирать, какие из них они предпочитают, или даже использовать их как взаимозаменяемые.
Ресурсы
- Спецификация синтаксиса диапазона медиа-запроса
- Синтаксис диапазона медиа-запроса в MDN
- Синтаксис диапазона медиа-запроса Плагин PostCSS
Нет переменных медиа-запроса
До появления @custom-media
медиазапросы должны были повторяться снова и снова или полагаться на препроцессоры для генерации правильного вывода на основе статических переменных во время сборки.
После @custom-media
CSS позволяет использовать псевдонимы медиа-запросов и ссылаться на них, как на пользовательское свойство.
Именование вещей очень важно: оно может согласовать цель с синтаксисом, упрощая обмен информацией и использование в группах. Вот несколько пользовательских медиа-запросов, которые следуют за мной между проектами:
@custom-media --OSdark (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);
@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse (hover) and (pointer: fine);
@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);
Теперь, когда они определены, я могу использовать один из них следующим образом:
@media (--OSdark) {
:root {
…
}
}
Полный список пользовательских медиа-запросов, которые я использую, можно найти в моей библиотеке пользовательских свойств CSS Open Props .
Ресурсы
Вложенность селекторов — это так здорово
До появления @nest
в таблицах стилей было много повторений. Это становилось особенно громоздким, когда селекторы были длинными и каждый из них нацелен на небольшие различия. Удобство вложенности — одна из наиболее распространенных причин использования препроцессора.
После @nest
повторение исчезло. Почти все функции вложенности с поддержкой препроцессора будут встроены в CSS.
article {
color: darkgray;
}
article > a {
color: var(--link-color);
}
/* with @nest becomes */
article {
color: darkgray;
& > a {
color: var(--link-color);
}
}
Что для меня наиболее важно во вложении, помимо отсутствия повторения article
во вложенном селекторе, так это то, что контекст стиля остается в пределах одного блока стиля. Вместо того, чтобы подпрыгивать от одного селектора и его стилей к другому селектору со стилями (пример 1), читатель может оставаться в контексте статьи и увидеть, как статья владеет ссылками внутри нее. Отношения и намерения стиля объединяются вместе, поэтому article
может иметь свои собственные стили.
Собственность также можно рассматривать как централизацию. Вместо того, чтобы осматривать таблицу стилей для соответствующих стилей, их все можно найти в контексте. Это работает с родителями и детьми отношениями, а также с детьми и родителями.
Рассмотрим компонент ребенка, который хочет приспособиться, когда он находится в другом родительском контексте, в отличие от родителя, владеющего стилем, и менять ребенка:
/* parent owns this, adjusting children */
section:focus-within > article {
border: 1px solid hotpink;
}
/* with @nest becomes */
/* article owns this, adjusting itself when inside a section:focus-within */
article {
@nest section:focus-within > & {
border: 1px solid hotpink;
}
}
@nest
помогает в целом в организации, централизации и владении более здоровым стилем. Компоненты могут группировать и владеть своими собственными стилями, вместо того, чтобы они распространялись среди других блоков стиля. Это может показаться небольшим в этих примерах, но это может иметь очень большое воздействие, как для удобства, так и для разборчивости.
Ресурсы
Стили общего числа действительно сложные
До @scope
существовало много стратегий, потому что стили в CSS Cascade, наследуя и по умолчанию глобально охватываются по умолчанию. Эти особенности CSS очень удобны для многих вещей, но для сложных участков и приложений, с потенциально множеством различных стилей компонентов, глобальное пространство и природа каскада могут привести к тому, что стили чувствуют, что они протекают.
После @scope
, не только стили могут быть охвачены только в контексте, например, класс, они также могут сформулировать, где заканчиваются стили и не продолжают каскад или наследу.
В следующем примере, соглашение с соглашением от BEM , можно обратить вспять на фактическое намерение. Селектор BEM пытается охватить цвет элемента header
в .card
. Это требует, чтобы заголовок имел это имя класса, достигнув цели. С @scope
не требуется соглашений об именах, чтобы достичь одной и той же цели, не отмечая элемент заголовка:
.card__header {
color: var(--text);
}
/* with @scope becomes */
@scope (.card) {
header {
color: var(--text);
}
}
Вот еще один пример, менее специфичный для компонентов и больше о глобальной природе CSS. Темные и легкие темы должны сосуществовать в таблице стилей, где порядок имеет значение при определении стиля выигрыша. Обычно это означает, что темные стили темы приходят после легкой темы; Это устанавливает свет как по умолчанию и темный, как необязательный стиль. Избегайте упорядочения и сражения с масштабами с @scope
:
@scope (.light-theme) {
a { color: purple; }
}
@scope (.dark-theme) {
a { color: plum; }
}
Чтобы завершить историю здесь, @scope
также позволяет установить, где заканчивается прицел стиля. Это нельзя сделать с какой -либо соглашением об именах или препроцессором; Это особенное и только что-то, что может сделать CSS, встроенный в браузер. В следующем примере стили img
и .content
применяются исключительно, когда ребенок из .media-block
брат или родитель .content
@scope (.media-block) to (.content) {
img {
border-radius: 50%;
}
.content {
padding: 1em;
}
}
Ресурсы
Нет пути CSS для масонства
Перед каменной кладкой CSS с помощью сетки JavaScript стал лучшим способом достижения масонства, так как любой из методов CSS с столбцами или Flexbox будет неточно представлять порядок содержания.
После каменной кладки CSS с помощью сетки не требуется библиотеки JavaScript, и заказ на содержание будет правильным.
Предыдущая демонстрация достигается со следующим CSS:
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: masonry;
}
Приятно знать, что это на радаре в качестве стратегии недостающих макетов, плюс вы можете попробовать его сегодня в Firefox .
Ресурсы
- Спецификация масонства
- Масонство масонство на MDN
- Smashing Magazine: Нативная масонство CSS с CSS Grid
CSS не может помочь пользователям уменьшить данные
Перед тем, prefers-reduced-data
медиа-запроса DATA, JavaScript и сервер могут изменить свое поведение на основе операционной системы пользователя или опции браузера «Saver», но CSS не мог.
После prefers-reduced-data
запросе CSS может присоединиться к улучшению пользовательского опыта и сыграть свою роль в сохранении данных.
@media (prefers-reduced-data: reduce) {
picture, video {
display: none;
}
}
Предыдущий CSS используется в этом компоненте прокрутки медиа -прокрутки , и экономия может быть огромной. В зависимости от того, насколько велик видовой порт, тем больше сбережений, которые можно получить при загрузке страницы. Сохранение продолжается, поскольку пользователи взаимодействуют с медиа -спирольрами. Все изображения имеют loading="lazy"
атрибуты на них, и что, в сочетании с CSS, полностью скрывающим элемент, означает, что сетевой запрос на изображение никогда не производится.
Для моего тестирования, в среднем просмотре просмотр, 40 запросов и 700 КБ ресурсов были первоначально загружены. В качестве пользователя прокручивают выбор носителя, загружаются больше запросов и ресурсов. Благодаря CSS и сниженным запросу средств массовой информации, 10 запросов и 172 КБ ресурсов загружаются. Это половина мегабайта сбережений, и пользователь даже не проскальзывал ни одного средства массовой информации, и в этот момент нет дополнительных запросов.
В этом сокращенном опыте данных есть больше преимуществ, чем просто экономия данных. Можно увидеть больше названий, и нет отвлекающих изображений обложки, чтобы украсть внимание. Многие пользователи просматривают в режиме спасения данных, потому что они платят за мегабайт данных - очень приятно видеть, что CSS может помочь здесь.
Ресурсы
- Предпочитает спецификация DEM-DATA
- Предпочитает-уменьшенные даты на MDN
- Предполагает снижение-дату в GUI Challenge
- Smashing Magazine: улучшение основных веб -Vitals, пример Smashing Magazine Trake
Прокрутите функции SNAP слишком ограничены
Перед этим прокручивающимся предложениями, написание своего собственного JavaScript для управления каруселью, слайдером или галереей может быстро стать сложным, со всеми наблюдателями и управлением государством. Кроме того, если не осторожно, естественные скорости прокрутки могут быть нормализованы сценарием, заставляя взаимодействие с пользователем чувствовать себя немного неестественным и потенциально неуклюжим.
Новые API
snapChanging()
Как только браузер выпустил ребенка Snap, это событие стреляет. Это позволяет пользовательскому интерфейсу отражать отсутствие ускоренного ребенка и неопределенное состояние Snap Scroller, поскольку он сейчас используется и приземлится где -нибудь новое.
document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()
Как только браузер пришел к новому ребенку, и прокрутка отдохнула, это событие стреляет. Это позволяет любому пользовательскому интерфейсу, который зависит от того, что сломанный ребенок обновляет и отражает соединение.
document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
console.log('Snap changed', event.snappedTargetsList);
});
scroll-start
Прокрутка не всегда начинается с самого начала. Рассмотрим обширные компоненты, где проводят влево или правое, вызывает различные события или строку поиска, которая на странице изначально скрыта до тех пор, пока вы не прокрутите вверх. Это свойство CSS позволяет разработчикам указать, что прокрутка должна начинаться в определенном моменте.
:root { --nav-height: 100px }
.snap-scroll-y {
scroll-start-y: var(--nav-height);
}
:snap-target
Этот селектор CSS будет соответствовать элементам в контейнере для прокрутки, который в настоящее время складывается браузером.
.card {
--shadow-distance: 5px;
box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
transition: box-shadow 350ms ease;
}
.card:snapped {
--shadow-distance: 30px;
}
После того, как эти предложения прокрутки Snap, сделать слайдер, карусель или галерею намного проще, так как браузер теперь предлагает удобства для этой задачи, исключая наблюдатели и код оркестровки прокрутки в пользу использования встроенных API.
Это все еще очень ранние дни для этих функций CSS и JS, но будьте в поисках полифиллов, которые могут помочь в усыновлении и тестировании в ближайшее время.
Ресурсы
Езда на велосипеде между известными государствами
До toggle()
только состояния, встроенные в браузер, уже могут быть использованы для стиля и взаимодействия. Например, ввод флага имеет :checked
внутренне управляемое состояние браузера для ввода, который CSS может использовать для визуального изменения элемента.
После toggle()
пользовательские состояния могут быть созданы на любом элементе для CSS, чтобы измениться и использовать для стиля. Это позволяет группы, ездить на велосипеде, направить переключение и многое другое.
В следующем примере достигается тот же эффект элемента списка, но без каких -либо элементов флажона:
<ul class='ingredients'>
<li>1 banana
<li>1 cup blueberries
...
</ul>
И соответствующие стили CSS toggle()
:
li {
toggle-root: check self;
}
li:toggle(check) {
text-decoration: line-through;
}
Если вы знакомы с государственными машинами, вы можете заметить, сколько кроссовера с toggle()
. Эта функция позволит разработчикам превратить больше своего состояния в CSS, надеясь, что приведет к более четким и более семантическим способам организации взаимодействия и состояния.
Ресурсы
Настройка элементов выбора
Перед <selectmenu>
CSS не имела возможности настраивать элементы <option>
с богатым HTML или много изменить отображение списка параметров. Это привело к тому, что разработчики загружают внешние библиотеки, которые воссоздали большую часть функциональности <select>
, что в конечном итоге стало большой работой.
После <selectmenu>
разработчики могут предоставить богатый HTML для элементов опционов и стилизовать их столько, сколько им необходимо, при этом соответствовать требованиям доступности и предоставления семантического HTML.
В следующем примере, взятой на странице <selectmenu>
Объяснителя , новое меню Select создается с некоторыми основными параметрами:
<selectmenu>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</selectmenu>
CSS может нацеливаться и уладить части элемента:
.my-select-menu::part(button) {
color: white;
background-color: red;
padding: 5px;
border-radius: 5px;
}
.my-select-menu::part(listbox) {
padding: 10px;
margin-top: 5px;
border: 1px solid red;
border-radius: 5px;
}
Вы можете попробовать элемент <selectmenu>
на хроме в канарейке с включенным флагом веб -экспериментов. Остерегайтесь в 2023 году и далее для настраиваемых элементов выбора меню.
Ресурсы
Закрепление элемента на другой
Перед anchor()
, позиционировать абсолютное и относительное, были стратегии положения, предоставленные разработчикам, чтобы детские элементы перемещались в родительском элементе.
После anchor()
разработчики могут позиционировать элементы на другие элементы, независимо от того, что они являются ребенком или нет. Это также позволяет разработчикам указать, с каким преимуществом позиционирует и другие тонкости для создания позиционных отношений между элементами.
Объяснитель имеет несколько отличных примеров и предоставленных образцов кода, если вы заинтересованы в изучении большего.