Состояние CSS 2022

Возможности веб-стиля сегодняшнего и завтрашнего дня, представленные на Google IO 2022, а также некоторые дополнительные возможности.

2022 год станет одним из величайших годов CSS, как с точки зрения функций, так и совместных выпусков функций браузера, с совместной целью реализовать 14 функций!

Обзор

Этот пост представляет собой статью в форме доклада, прозвучавшего на Google IO 2022. Он не предназначен для того, чтобы быть подробным руководством по каждой функции, а скорее представляет собой введение и краткий обзор, призванный пробудить ваш интерес, предоставляя широту, а не глубину. Если ваш интерес заинтересовался, проверьте в конце раздела ссылки на ресурсы для получения дополнительной информации.

Оглавление

Используйте список ниже, чтобы перейти к интересующим темам:

Совместимость с браузером

Основная причина, по которой так много функций CSS планируется выпустить совместно, связана с усилиями Interop 2022 . Прежде чем изучать усилия Interop, важно взглянуть на усилия Compat 2021 .

Совместимость 2021

Цели на 2021 год, основанные на отзывах разработчиков через опросы, заключались в стабилизации текущих функций, улучшении набора тестов и повышении проходных баллов браузеров по пяти функциям:

  1. sticky позиционирование
  2. изменение aspect-ratio
  3. flex макет
  4. grid
  5. transform позиционирование и анимацию

Результаты тестов были повышены по всем направлениям, что продемонстрировало повышенную стабильность и надежность. Поздравляем команды здесь!

Взаимодействие 2022

В этом году браузеры встретились, чтобы обсудить функции и приоритеты, над которыми они намеревались работать, объединив свои усилия. Они планировали предоставить разработчикам следующие веб-функции:

  1. @layer
  2. Цветовые пространства и функции
  3. Сдерживание
  4. <dialog>
  5. Совместимость форм
  6. Прокрутка
  7. Подсетка
  8. Типография
  9. Единицы видового экрана
  10. Веб-совместимость

Это захватывающий и амбициозный список, и мне не терпится увидеть его раскрытие.

Новинка 2022 года

Неудивительно, что на состояние CSS 2022 существенно влияет работа Interop 2022.

Каскадные слои

Поддержка браузера

  • Хром: 99.
  • Край: 99.
  • Фаерфокс: 97.
  • Сафари: 15.4.

Источник

До появления @layer обнаруженный порядок загруженных таблиц стилей был очень важен, поскольку стили, загруженные последними, могли перезаписать ранее загруженные стили. Это привело к тщательно управляемым таблицам стилей ввода, в которые разработчикам приходилось сначала загружать менее важные стили, а затем более важные. Существуют целые методологии, помогающие разработчикам управлять этой важностью, такие как ITCSS .

С помощью @layer входной файл может заранее определить слои и их порядок. Затем, когда стили загружаются, загружаются или определяются, их можно поместить в слой, что позволяет сохранить важность переопределения стиля, но без тщательно управляемой оркестрации загрузки.

Видео показывает, как определенные каскадные слои обеспечивают более свободный и свободный процесс разработки и загрузки, сохраняя при этом каскад по мере необходимости.

Chrome DevTools помогает визуализировать, какие стили из каких слоев берутся:

Снимок экрана боковой панели «Стили» инструментов разработчика Chrome, на котором показано, как стили отображаются в новых группах слоев.

Ресурсы

Подсетка

Поддержка браузера

  • Хром: 117.
  • Край: 117.
  • Фаерфокс: 71.
  • Сафари: 16.

Источник

До появления 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). На следующем изображении родительская сетка и подсетки наложены друг на друга. Теперь это напоминает то, как дизайнеры думали о планировке.

Снимок экрана: демонстрация подсетки с использованием инструмента наложения сетки Chrome Devtools для отображения линий, определенных CSS.

На панели элементов инструментов разработчика вы можете увидеть, какие элементы являются сетками и подсетками, что очень полезно для отладки или проверки макета.

Снимок экрана панели «Элементы» Chrome Devtools, на которой указано, какие элементы имеют макет сетки или подсетки.
Скриншот из Firefox Devtools

Ресурсы

Контейнерные запросы

Поддержка браузера

  • Хром: 105.
  • Край: 105.
  • Фаерфокс: 110.
  • Сафари: 16.

Источник

До появления @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 можно принять множество интересных и значимых дизайнерских решений.

Ресурсы

accent-color

Поддержка браузера

  • Хром: 93.
  • Край: 93.
  • Фаерфокс: 92.
  • Сафари: 15.4.

Источник

До появления accent-color , когда вам нужна была форма с цветами, соответствующими бренду, вы могли столкнуться со сложными библиотеками или решениями CSS, которыми со временем становилось трудно управлять. Хотя они предоставили вам все возможности и, надеюсь, включили в себя доступность, выбор между использованием встроенных компонентов или принятием собственных становится утомительным, чтобы продолжать выбирать.

После accent-color одна строка CSS добавляет цвет бренда к встроенным компонентам. Помимо оттенка, браузер разумно выбирает подходящие контрастные цвета для вспомогательных частей компонента и адаптируется к цветовым схемам системы (светлым или темным).

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

Светлые и темные элементы HTML с акцентом расположены рядом для сравнения.

Чтобы узнать больше об accent-color , прочтите мою публикацию на web.dev , где я рассматриваю многие другие аспекты этого полезного свойства 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()

Поддержка браузера

  • Хром: 101.
  • Край: 101.
  • Фаерфокс: 96.
  • Сафари: 15.

Источник

HWB означает оттенок, белизну и черноту. Он представляет собой удобный для человека способ выражения цвета, поскольку это всего лишь оттенок и количество белого или черного цвета, которые можно осветлить или затемнить. Художники, смешивающие цвета с белым или черным, возможно, оценят это дополнение цветового синтаксиса.

Использование этой цветовой функции приводит к получению цветов из цветового пространства sRGB, такого же, как HSL и RGB. Что касается новизны 2022 года, это не придаёт вам новых красок, но может облегчить некоторые задачи любителям синтаксиса и ментальной модели.

Ресурсы

Цветовые пространства

Представление цветов осуществляется с помощью цветового пространства. Каждое цветовое пространство предлагает различные функции и компромиссы для работы с цветом. Некоторые могут объединить все яркие цвета вместе; некоторые могут сначала выстроить их в ряд, исходя из их легкости.

В 2022 году CSS предложит 10 новых цветовых пространств, каждое из которых обладает уникальными функциями, которые помогут дизайнерам и разработчикам отображать, выбирать и смешивать цвета. Раньше sRGB был единственным вариантом работы с цветом, но теперь CSS открывает новый потенциал и новое цветовое пространство по умолчанию — LCH.

color-mix()

Поддержка браузера

  • Хром: 111.
  • Край: 111.
  • Фаерфокс: 113.
  • Сафари: 16.2.

Источник

До появления 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-contrast()

Поддержка браузера

  • Хром: не поддерживается.
  • Край: не поддерживается.
  • Firefox: не поддерживается.
  • Сафари: за флагом.

Источник

До появления color-contrast() авторам таблиц стилей необходимо было заранее знать доступные цвета. Часто палитра отображает черный или белый текст на образце цвета, чтобы указать пользователю цветовой системы, какой цвет текста потребуется для правильного контраста с этим образцом.

Снимок экрана: 3 палитры материалов, показывающие 14 цветов и соответствующие им белые или черные контрастные цвета для текста.
Пример из цветовых палитр Material Design 2014 г.

После color-contrast() авторы таблиц стилей могут полностью переложить задачу на браузер. Вы можете не только использовать браузер для автоматического выбора черного или белого цвета, но и предоставить ему список цветов, подходящих для системы дизайна, и заставить его выбрать первый, соответствующий желаемому коэффициенту контрастности.

Вот скриншот демонстрационного набора цветовой палитры HWB , где цвета текста автоматически выбираются браузером на основе образца цвета:

Снимок экрана демо-версии 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.

Ресурсы

Относительный синтаксис цвета

Поддержка браузера

  • Хром: 111.
  • Край: 111.
  • Фаерфокс: 113.
  • Сафари: 15.

Источник

До появления синтаксиса относительного цвета для расчета цвета и внесения корректировок цветовые каналы необходимо было индивидуально поместить в пользовательские свойства. Это ограничение также сделало 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);
}
Скриншот 15 палитр, динамически генерируемых CSS.
Попробуйте демо

Надеюсь, теперь вы понимаете, как цветовые пространства и различные цветовые функции могут использоваться для разных целей, в зависимости от их сильных и слабых сторон.

Ресурсы

Градиентные цветовые пространства

До появления градиентных цветовых пространств по умолчанию использовалось цветовое пространство sRGB. sRGB в целом надежен, но имеет некоторые недостатки, такие как серая мертвая зона .

4 градиента в сетке, от голубого до темно-розового. LCH и LAB имеют более равномерную яркость, тогда как sRGB немного обесцвечивается в середине.

После градиентных цветовых пространств сообщите браузеру, какое цветовое пространство использовать для интерполяции цвета. Это дает разработчикам и дизайнерам возможность выбирать градиент, который они предпочитают. Цветовое пространство по умолчанию также меняется на LCH вместо sRGB.

Добавление синтаксиса идет после направления градиента, использует новый in и является необязательным:

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);

Вот базовый и важный градиент от черного к белому. Посмотрите на диапазон результатов в каждом цветовом пространстве. Некоторые достигают темно-черного цвета раньше других, некоторые выцветают до белого слишком поздно.

Показаны 11 цветовых пространств для сравнения черного и белого.

В следующем примере черный цвет превращается в синий, поскольку это известная проблемная область для градиентов. Большинство цветовых пространств переходят в фиолетовый цвет во время цветовой интерполяции или, как мне нравится это думать, когда цвета перемещаются внутри своего цветового пространства из точки А в точку Б. Поскольку градиент будет проходить по прямой линии от точки А до точки Б, форма цветового пространства радикально меняет остановки, которые проходит путь.

Показаны 11 цветовых пространств для сравнения синего и черного.

Более глубокие исследования, примеры и комментарии можно найти в этой теме в Твиттере .

Ресурсы

inert

Поддержка браузера

  • Хром: 102.
  • Край: 102.
  • Фаерфокс: 112.
  • Сафари: 15.5.

Источник

До появления inert хорошей практикой было направлять внимание пользователя на те области страницы или приложения, которые требовали немедленного внимания. Эта стратегия управляемого фокуса стала известна как захват фокуса, потому что разработчики помещали фокус в интерактивное пространство, прослушивали события изменения фокуса, и, если фокус покидал интерактивное пространство, он возвращался обратно. Пользователи, пользующиеся клавиатурой или программами чтения с экрана, направляются назад. в интерактивное пространство, чтобы убедиться, что задача выполнена, прежде чем двигаться дальше.

После inert перехват не требуется, поскольку вы можете заморозить или защитить целые разделы страницы или приложения. Щелчки и попытки изменения фокуса просто недоступны, пока эти части документа инертны. Можно также думать об этом как об охранниках, а не о ловушках, где inert не заинтересован в том, чтобы вы оставались где-то, а скорее делает другие места недоступными.

Хорошим примером этого является функция alert() в JavaScript:

Веб-сайт отображается как интерактивный, затем вызывается alert(), и страница больше не активна.

Обратите внимание, что в предыдущем видео страница была доступна с помощью мыши и клавиатуры до тех пор, пока не был вызван метод 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 в Интернете появились шрифты меньшего размера, векторного масштабирования, изменения положения, градиента и режима наложения, которые принимают параметры для настройки шрифта для каждого случая использования или для соответствия бренду.

Сравнительная визуализация и гистограмма, показывающая, насколько шрифты COLRv1 стали четче и меньше.
Изображение взято с https://developer.chrome.com/blog/colrv1-fonts/.

Вот пример сообщения в блоге разработчиков 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;
}
Скриншот шрифта Bungee Spice со словом DUNE.
Шрифт Bungee Spice показан в специальных цветах, источник: https://developer.chrome.com/blog/colrv1-fonts/.

Поскольку становится доступным все больше и больше вариативных и цветных шрифтов, веб-типографика находится на великолепном пути к богатой настройке и творческому самовыражению.

Ресурсы

Единицы видового экрана

Рисунок, показывающий, что экран устройства, окно браузера и iframe имеют разные области просмотра.

До появления новых вариантов области просмотра в Интернете предлагались физические единицы, помогающие подобрать область просмотра. Был один для высоты, ширины, наименьшего размера (vmin) и наибольшей стороны (vmax). Они хорошо работали во многих случаях, но мобильные браузеры создавали сложности.

На мобильных устройствах при загрузке страницы отображается строка состояния с URL-адресом, и эта панель занимает часть пространства области просмотра. Через несколько секунд и некоторую интерактивность строка состояния может сдвинуться, открывая пользователю больший обзор. Но когда эта полоса выдвигается, высота области просмотра изменяется, и любые блоки vh будут смещаться и изменять размер по мере изменения их целевого размера. В последующие годы подразделению vh пришлось решать, какой из двух размеров области просмотра он будет использовать, поскольку это вызывало неприятные проблемы с визуальным макетом на мобильных устройствах. Было решено, что vh всегда будет представлять самую большую область просмотра.

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

После появления новых вариантов области просмотра стали доступны маленькие, большие и динамические единицы области просмотра с добавлением логических эквивалентов к физическим. Идея состоит в том, чтобы дать разработчикам и дизайнерам возможность выбирать, какое устройство они хотят использовать в своем конкретном сценарии. Возможно, это нормально, если произойдет небольшой резкий сдвиг макета, когда строка состояния исчезнет, ​​поэтому тогда можно будет использовать dvh (динамическую высоту области просмотра) без беспокойства.

Изображение с тремя телефонами, помогающее проиллюстрировать DVH, LVH и SVH. В примере телефона DVH есть две вертикальные линии: одна между нижней частью панели поиска и нижней частью области просмотра, а другая - между верхней панелью поиска (под строкой состояния системы) и нижней частью области просмотра; показывая, как DVH может иметь любую из этих двух длин. LVH отображается посередине с одной линией между нижней частью строки состояния устройства и кнопкой окна просмотра телефона. Последний пример модуля SVH, показывающий линию от нижней части панели поиска браузера до нижней части области просмотра.

Вот полный список всех новых вариантов единиц видового экрана, доступных в новых вариантах видового экрана:

Единицы высоты видового экрана
​​.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;
}

Надеемся, что это даст разработчикам и дизайнерам гибкость, необходимую для создания адаптивного дизайна в области просмотра.

Ресурсы

:has()

Поддержка браузера

  • Хром: 105.
  • Край: 105.
  • Фаерфокс: 121.
  • Сафари: 15.4.

Источник

До :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() */
}

Ресурсы

2022 год и далее

Есть еще ряд вещей, которые будет сложно сделать после того, как все эти удивительные функции появятся в 2022 году. В следующем разделе рассматриваются некоторые оставшиеся проблемы и решения, которые активно разрабатываются для их решения. Эти решения являются экспериментальными, хотя они могут быть указаны или доступны за флажками в браузерах.

Выводом из следующих разделов должно быть то, что перечисленные проблемы заставляют многих людей из многих компаний искать решения, а не то, что эти решения будут выпущены в 2023 году.

Слабо типизированные пользовательские свойства

Поддержка браузера

  • Хром: 85.
  • Край: 85.
  • Фаерфокс: 128.
  • Сафари: 16.4.

Источник

Пользовательские свойства 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 может сделать гораздо больше, но эти небольшие возможности могут иметь большое значение.

Ресурсы

Был в 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) {
  
}

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

Ресурсы

Нет переменных медиа-запроса

До появления @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 помогает в целом в организации, централизации и владении более здоровым стилем. Компоненты могут группировать и владеть своими собственными стилями, вместо того, чтобы они распространялись среди других блоков стиля. Это может показаться небольшим в этих примерах, но это может иметь очень большое воздействие, как для удобства, так и для разборчивости.

Ресурсы

Стили общего числа действительно сложные

Поддержка браузера

  • Хром: 118.
  • Край: 118.
  • Firefox: за флагом.
  • Сафари: 17.4.

Источник

До @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, и заказ на содержание будет правильным.

Снимок экрана масонства, который показывает цифры, движущиеся вдоль вершины, а затем спускаются.
Изображение и демонстрация из журнала Smashing
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

Предыдущая демонстрация достигается со следующим CSS:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

Приятно знать, что это на радаре в качестве стратегии недостающих макетов, плюс вы можете попробовать его сегодня в Firefox .

Ресурсы

CSS не может помочь пользователям уменьшить данные

Поддержка браузера

  • Хром: за флагом.
  • Край: За флагом.
  • Firefox: не поддерживается.
  • Сафари: не поддерживается.

Источник

Перед тем, 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 может помочь здесь.

Ресурсы

Прокрутите функции 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() разработчики могут позиционировать элементы на другие элементы, независимо от того, что они являются ребенком или нет. Это также позволяет разработчикам указать, с каким преимуществом позиционирует и другие тонкости для создания позиционных отношений между элементами.

Объяснитель имеет несколько отличных примеров и предоставленных образцов кода, если вы заинтересованы в изучении большего.

Ресурсы