Пропустить навигацию
Часть I Глава 1

CSS

Hero image of Web Almanac characters measuring and painting a web page.

Введение

Каскадные таблицы стилей (CSS) — язык, применяемый для раскладки, форматирования и рисования веб-страниц и другого медиа-контента. Это один из трёх главных языков для построения веб-сайтов. Другие два — HTML, применяемый для структурирования, и JavaScript, применяемый для описания поведения.

В прошлогоднем самом первом издании Web Almanac мы смотрели на разнообразие CSS-метрик, полученных при помощи 41 SQL-запроса в хранилища HTTP Archive, чтобы получить доступ к состоянию технологии в 2019. В этом году мы погрузились намного глубже, чтобы измерить не только то, сколько страниц используют ту или иную возможность CSS, но также как они её используют.

В целом, мы наблюдали, как веб двигается в двух разных направлениях, когда дело доходит до применения CSS. В наших блогах и «пузырях» в Твиттере мы, как правило, обсуждаем самое новое и яркое, тем не менее миллионы сайтов всё ещё используют код десятилетней давности. Вещи вроде вендорных префиксов из прошлой эпохи, проприетарные фильтры для IE, флоаты для раскладки во всей своей clearfix-красе. Но также мы наблюдали впечатляющее внедрение многих новых функций — даже тех, которые получили повсеместную поддержку только в этом году, вроде min() и max(). Тем не менее, как правило, существует обратная корреляция между тем, насколько крутым что-то кажется, и тем, как часто это используется. Например, передовые возможности Houdini практически нигде не применяются.

Аналогично, в наших докладах на конференциях мы часто склонны фокусироваться на сложных, тщательно продуманых вариантах применения, которые взрывают мозг и заполняют Твиттер постами вроде «CSS умеет так?!». Однако, как оказалось, по большей части использование CSS в дикой природе довольное простое. CSS-переменные чаще всего используются как константы и редко обращаются к другим переменным, calc() в основном использует две составляющие, градиенты по большей части имеют две точки остановки и так далее.

Веб больше не подросток — ему уже 30 лет и ведёт он себя соответствующе. Он всё больше отдаёт предпочтение стабильности, а не новизне, и удобству чтения, а не сложности, оставляя в стороне случайные удовольствия.

Методология

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

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

Для сбора данных для этой главы понадобился 121 SQL-запрос, всего более 10 тысяч строк SQL, включая 3 тысячи строк JavaScript-функций внутри SQL. Это делает эту главу крупнейшей в истории издания Web Almanac.

Много инженерной работы пришлось проделать, чтобы сделать анализ такого масштаба возможным. Как и в прошлом году, мы прогнали весь CSS-код через парсер CSS и сохранили абстрактные синтаксические деревья (AST) для всех таблиц стилей в массиве, что вылилось в колоссальные 10 ТБ данных. В этом году мы дополнительно разработали библиотеку хелперов для работы с AST и парсер селекторов — обе разработки мы также зарелизили как отдельные опенсорс-проекты. Большая часть метрик использовала JavaScript для сбора данных из отдельного AST и SQL для агрегации этих данных по всему массиву. Любопытно, как ваш собственный CSS соотносится с нашими метриками? Мы сделали онлайн-песочницу, в которой вы можете опробовать их на ваших сайтах.

Для определённых метрик смотреть в CSS AST было недостаточно. Мы хотели посмотреть на SCSS везде, где это можно было сделать через карты кода, так как это показывает нам, в чём разработчики нуждаются от CSS, что ещё невозможно получить, в то время как изучение CSS показывает нам, для чего разработчики уже сейчас его используют. Для этого нам пришлось применить кастомную метрику — код на JavaScript, который запускается краулером, когда он посещает заданную страницу. Мы не могли использовать полноценный SCSS-парсер, так как он мог слишком сильно замедлить краулинг, поэтому нам пришлось прибегнуть к регулярным выражениям (о ужас!). Несмотря на грубый подход, мы получили множество инсайтов!

Кастомные метрики также были использованы для части анализа кастомных свойств. Хотя мы и можем получить много информации о том, как используются кастомные свойства, прямо из таблиц стилей, мы не можем построить граф зависимостей без возможности смотреть на DOM-дерево для контекста, так как кастомные свойства наследуются. Исследование вычисленных стилей для DOM-узлов также даёт нам информацию вроде типов элементов, к которым каждое из свойств применяется, и какие из них зарегистрированы — данные, которые тоже не могут быть получены из таблиц стилей.

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

Применение

Хотя JavaScript намного превосходит CSS по своей доле в общем весе страницы, CSS определённо за годы вырос в размерах: медианная страница для десктопа загружает 62 КБ CSS-кода, а каждая десятая страница загружает более 240 КБ CSS. Мобильные страницы используют немного меньше CSS-кода на всех перцентилях, но всего на 4–7 КБ. И хотя такие значения определённо больше, чем в предыдущие годы, это даже не близко к колоссальным значениям для JavaScript в 444 КБ на медиане и в 1,2 МБ для верхних 10%.

График 1.1. Распределение передаваемого размера таблиц стилей на страницу.

Было бы разумно предположить, что большая часть этого CSS генерируется препроцессорами или другими сборщиками, однако только для 15% включены карты кода. Неясно, говорит ли это больше об использовании карт кода или применении сборщиков. Из них подавляющее большинство (45%) пришло из других файлов CSS, что указывает на использование таких процессов сборки, работающих с CSS-файлами, как минификация, автопрефиксер и/или PostCSS. Sass был намного более популярным, чем Less (34% таблиц стилей с картами кода против 21%), с SCSS как самым популярным диалектом (33% для .scss против 1% для .sass).

Все эти килобайты кода обычно распределены по множеству файлов и элементам <style>; только около 7% страниц концентрируют весь свой CSS-код в одной удалённой таблице стилей, как нас часто учат делать. Фактически, медианная страница содержит 3 элемента <style> и 6 удалённых таблиц стилей, а 10% страниц содержат больше 14 элементов <style> и больше 20 удалённых CSS-файлов! И если для десктопов это приемлемо, такая ситуация на самом деле убивает производительность на мобильных, где задержка приёма-передачи важнее, чем скорость загрузки.

График 1.2. Самое большое количество таблиц стилей, загруженных на странице.

Поразительно, максимальное количество таблиц стилей на странице составляет 26 777 элементов <style> и 1 379 удалённых файлов! Я опредёленно не хочу загружать эту страницу!

График 1.3. Распределение количества таблиц стилей на страницу.

Другая метрика размера — количество правил. Медианная страница включает 448 правил и 5 454 объявления. Что интересно, 10% страниц включают крошечное количество CSS: меньше 13 правил! Несмотря на то, что мобильные страницы имеют слегка меньшие таблицы стилей, в них также немного больше правил, что указывает на меньшие правила в целом (как это обычно бывает с медиа-выражениями).

График 1.4. Распределение общего количества стилевых правил на страницу.

Селекторы и каскад

CSS предлагает множество способов применить стили к странице, от классов, идентификаторов и использования исключительно важного каскада для избегания дублирования стилей. Так как же разработчики применяют стили к своим страницам?

Имена классов

Для чего разработчики используют имена классов в наши дни? Чтобы ответить на этот вопрос, мы посмотрели на самые популярные имена классов. В списке преобладали классы из Font Awesome, причём 192 из 198 — это fa или fa-*! Единственное, о чём могло нам рассказать начальное исследование, это то, что Font Awesome чрезвычайно популярен и используется почти на трети веб-сайтов!

Тем не менее, когда мы выкинули классы fa-*, а затем wp-* (которые приходят из WordPress, другого крайне популярного ПО), то получили более значимые результаты. Если пренебречь этими классами, классы про состояния выглядят самыми популярными: .active встречается почти на половине веб-сайтов, а .selected и .disabled — где-то следом за ним.

Только несколько классов из топ-списка были презентационными, большая часть из которых либо про выравнивание (pull-right и pull-left из старых версий Bootstrap, alignright, alignleft и т.д.), либо clearfix, который всё ещё встречается на 22% веб-сайтов, несмотря на то, что вёрстка флоатами для раскладки вытесняется более современными гридами и флексбоксами.

График 1.5. Самые популярные имена классов по проценту страниц.

Идентификаторы

Несмотря на то, что использование идентификаторов в некоторых кругах не приветствуется из-за их гораздо большей специфичности, большинство веб-сайтов всё ещё используют их, хоть и скудно. Меньше половины страницы использовали более одного идентификатора в любом из своих селекторов (с максимальной специфичностью (1,x,y) или меньше) и почти все имели медианную специфичность (0,x,y), которая не включает идентификаторы. Смотрите спецификацию по селекторам для подробностей о вычислении специфичности и её нотации (a,b,c).

Но для чего эти идентификаторы используются? Оказывается, самые популярные идентификаторы — структурные: #content, #footer, #header, #main, несмотря на существование соответствующих элементов HTML, которые могли бы быть использованы в качестве селекторов, попутно улучшая семантическую разметку.

График 1.6. Самые популярные идентификаторы по проценту страниц.

Идентификаторы также могут использоваться для намеренного уменьшения или увеличения специфичности. Хак над специфичностью с написанием селектора по идентификатору как селектора по атрибуту ([id="foo"] вместо #foo для уменьшения специфичности) применяется на удивление редко: только 0,3% страниц используют его хотя бы один раз. Другой ID-специфичный хак — применение отрицания и селектора потомка вроде :not(#nonexistent) .foo вместо .foo для увеличения специфичности — также встречается крайне редко: всего на 0,1% страниц.

!important

А вот старый и грубый !important всё ещё используется довольно часто, несмотря на его хорошо известные недостатки. Медианная страница использует !important в около 2% объявлений, или в 1 из 50.

График 1.7. Мобильные страницы, использующие !important в каждом объявлении!

Некоторые разработчики буквально не могут им насытиться: мы нашли 2 304 десктопные страницы и 2 138 мобильных страниц, которые используют !important в каждом объявлении!

График 1.8. Распределение процента свойств с !important на страницу.

Что же разработчики так старательно перезаписывают? Мы посмотрели на разбивку по свойствам и обнаружили, что почти 80% страниц используют !important со свойством display. Распространённой практикой является применять display: none !important для прятания контента в классах-хелперах, чтобы перезаписать существующий CSS, который использует display для определения режима раскладки. Это побочный эффект того, что в ретроспективе было упущением в CSS. Он объединил три ортогональные характеристики в одну: внутренний режим раскладки, поведение потока и состояние видимости — всё это контролируется свойством display. Предпринимаются попытки разделить эти значения на отдельные ключевые слова display, чтобы их можно было настраивать независимо через кастомные свойства, но браузерная поддержка на данный момент практически отсутствует.

График 1.9. Топ свойств с !important по проценту страниц.

Специфичность и классы

Кроме того, что идентификаторы и !important можно по пальцам сосчитать, существует тренд на то, чтобы полностью обмануть специфичность, втиснув все критерии выбора селектора в одно имя класса, тем самым вынуждая все правила иметь одинаковую специфичность и превращая каскад в более простую систему «последний выигрывает». БЭМ — популярная, но не единственная методология подобного типа. И хотя трудно оценить, сколько веб-сайтов применяют исключительно БЭМ-подобные методологии, так как доскональное следование им крайне редкое (даже веб-сайт БЭМ во многих селекторах использует несколько классов), около 10% страниц имеют медианную специфичность (0,1,0), что может свидетельствовать в основном о следовании БЭМ-подобной методологии. На противолоположном конце от БЭМ разработчики часто применяют дублирование классов для увеличения специфичности и проталкивания селектора вперёд другого (например, .foo.foo вместо .foo). Хаки специфичности такого типа в действительности более популярны, чем БЭМ, будучи представлены на 14% мобильных веб-сайтов (9% для десктопов)! Это может указывать на то, что большинство разработчиков на самом деле не хотят полностью избавляться от каскада, им просто нужно больше контроля над ним.

Перцентиль Десктоп Мобильные
10 0,1,0 0,1,0
25 0,2,0 0,1,2
50 0,2,0 0,2,0
75 0,2,0 0,2,0
90 0,3,0 0,3,0
График 1.10. Распределение медианной специфичности на страницу.

Селекторы по атрибутам

Самый популярный селектор по атрибуту, безусловно, по атрибуту type — применяется на 45% страниц, вероятно, для стилизации инпутов различных видов: например, для стилизации текстовых инпутов отдельно от радио-кнопок, чекбоксов, слайдеров, элементов загрузки файлов и так далее.

График 1.11. Самые популярные селекторы по атрибутам по процентам страниц.

Псевдоклассы и псевдоэлементы

Когда мы что-то меняем в веб-платформе после того, как она уже давно устоялась, всегда возникает большая инерция. Как пример, веб всё ещё по большей части не осознал псевдоэлементы с синтаксисом, отличным от псевдоклассов, несмотря на то, что это изменение произошло более десяти лет назад. Все псевдоэлементы, которые доступны с синтаксисом псевдокласса по легаси-причинам, гораздо чаще встречаются (в 2,5–5 раз!) с синтаксисом псевдокласса.

График 1.12. Применение устаревшего синтаксиса :псевдокласс для ::псевдоэлементов как процент от мобильных страниц.

Безусловно, самые популярные псевдоклассы — взаимодействия с пользователем: :hover, :focus, and :active в верху списка, все они используются более чем на двух третях страниц, что указывает на то, что разработчикам нравится удобство декларативного описания взаимодействий с пользовательским интерфейсом.

:root, кажущийся гораздо более популярным, чем это оправдано его функциональностью, используется на трети страниц. В HTML-контенте он всего лишь выбирает элемент <html>, так почему же разработчики не использовали просто html? Возможно, ответ заключается в распространённой практике определения кастомных свойств, которые также широко используются, на псевдоклассе :root. Другой ответ может заключаться в специфичности: :root, будучи псевдоклассом, имеет более высокую специфичность, чем html: (0,1,0) против (0,0,1). Распространенным способом повышения специфичности селектора является добавление к нему :root, например, :root .foo имеет специфичность (0,2,0) по сравнению с просто (0,1,0) для .foo. Часто этого достаточно, чтобы слегка подтолкнуть один селектор рядом с другим в гонке каскада и избежать кувалды по имени !important. Чтобы проверить эту гипотезу, мы также измерили вот что: сколько страниц используют :root в начале селектора потомка? Результаты подтвердили нашу гипотезу: 29% страниц используют :root именно таким образом! Более того, 14% десктопных страниц и 19% мобильных страниц используют html в начале селектора потомка, возможно, чтобы придать селектору ещё меньший прирост специфичности. Популярность этих хаков специфичности убедительно указывает на то, что разработчикам нужен более точечный контроль над настройками специфичности, чем тот, что им предоставляется через !important. К счастью, он скоро появится с :where(), который уже много где реализован (хотя в Chrome пока что только за флагом).

График 1.13. Самые популярные псевдоклассы как процент от страниц.

Что касается псевдоэлементов, после привычно подозреваемых ::before и ::after почти все популярные псевдоэлементы — браузерные расширения для стилизации элементов форм и другого нативного UI, что сильно вторит потребности разработчика в более точечном контроле над нативными стилями UI. Самые популярные: стилизация кольца фокуса, плейсхолдеров, инпутов поиска, спиннеров, выделения, полос прокрутки, кнопок управления мультимедиа.

График 1.14. Самые популярные псевдоэлементы как процент от страниц.

Значения и единицы измерения

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

Размеры

Скромная единица измерения px за эти годы множество раз была под негативным давлением. Сначала из-за того, что она не очень хорошо сочеталась со старыми функциями масштабирования в Internet Explorer, а в последнее время из-за того, что для большинства задач существуют более подходящие единицы измерения, которые масштабируются на основании других дизайн-факторов, таких как размер вьюпорта, размер шрифта элемента или корневой размер шрифта, сокращая усилия на поддержку, делая неявные связи в дизайне явными. Главный продающий аргумент в пользу px — его соответствие одному пикселю устройства, дающее дизайнерам полный контроль — также исчез, поскольку пиксель больше не является пикселем устройства для современных экранов с высокой плотностью пикселей. Несмотря на всё это, CSS-пиксели по-прежнему почти повсеместно управляют дизайнами в вебе.

График 1.15. Процент значений <length>, которые используют единицу измерения px.

Единица измерения px всё ещё сильна как самая популярная единица длины в целом, с колоссальными 72,58% всех значений длины во всех таблицах стилей, использующих px! А если исключить проценты (поскольку они на самом деле не являются единицей измерения), доля px вырастает до ещё больших 84,14%.

График 1.16. Самые популярные единицы измерения <length> как процент появлений.

Как эти px распределены по свойствам? Есть какая-нибудь разница в зависимости от свойства? Определённо. Например, как и следовало ожидать, px намного более популярен для задания границ (80–90%) в сравнении с относящимися к шрифтам метрикам вроде font-size, line-height или text-indent. Тем не менее, даже для них использование px значительно превосходит использование любых других единиц измерения. Фактически, единственные свойства, для которых другая единица измерения (любая другая) используется чаще, чем px, это vertical-align (55% em), mask-position (50% em), padding-inline-start (62% em), margin-block-start и margin-block-end (65% em), а также совершенно новый gap с 62% rem.

Можно легко возразить, что большая часть этого контента банально устарела, была написана до того, как авторы научились использовать относительные единицы измерения, чтобы делать свои проекты более адаптируемыми и экономить себе время в будущем. Однако это легко опровергнуть, взглянув на более свежие свойства, такие как grid-gap (62% px).

Свойство px <число> em % rem pt
font-size 70% 2% 17% 6% 4% 2%
line-height 54% 31% 13% 3%
border 71% 27% 2%
border-radius 65% 21% 3% 10%
text-indent 32% 51% 8% 9%
vertical-align 29% 12% 55% 4%
grid-gap 63% 11% 9% 1% 16%
mask-position 50% 50%
padding-inline-start 33% 5% 62%
gap 21% 16% 1% 62%
margin-block-end 4% 31% 65%
margin-inline-start 38% 46% 14% 1%
График 1.17. Использование единиц измерения внутри свойства.

Аналогично, несмотря на широко разрекламированные преимущества rem перед em во многих случаях и его всеобщую браузерную поддержку в течение многих лет, веб всё ещё в значительной степени не втянулся в rem: надёжный em составляет 87% от всех используемых относительных шрифту единиц измерения, а rem сильно отстаёт с его 12%. Мы действительно видели некоторое использование ch (ширина символа ’0’) и ex (высота символа ’x’ применяемого шрифта) в дикой природе, но очень мало (всего 0,37% и 0,19% от всех относительных шрифту единиц измерения).

График 1.18. Относительная доля шрифтовых единиц измерения

Длина — это единственный тип значения в CSS, для которого мы можем опустить единицу измерения, когда значение равно нулю, то есть мы можем написать 0 вместо 0px или 0em и т.д. Разработчики (или CSS-минификаторы?) активно пользуются преимуществом от этого: из всех значений 0 89% были безразмерными.

График 1.19. Относительная популярность длины 0 на единицу измерения в процентах появления на мобильных страницах.

Вычисления

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

Сегодня calc() поддерживается каждым браузером на протяжении уже девяти лет, поэтому неудивительно, что он получил такое широкое распространение: 60% страниц использовали его хотя бы один раз. Во всяком случае, мы ожидали даже более широкого распространения, чем это.

calc() прежде всего используется для размеров, 96% его применения сконцентрировано в свойствах, которые принимают значения типа <length>, причём 60% от этого (58% от общего применения) — в свойстве width!

График 1.20. Относительная популярность свойств, использующих calc(), в процентах случаев.

Похоже, что большая часть этого использования заключается в вычитании пикселей из процентов, о чём свидетельствует тот факт, что наиболее распространёнными единицами измерения в calc() являются px (51% использования calc()) и % (42% использования calc()), и что 64% использования calc() содержат вычитание. Интересно, что самые популярные единицы длины с calc() отличаются от самых популярных единиц длины в целом (например, rem более популярна, чем em, за ними следуют единицы измерения размера вьюпорта), скорее всего из-за того, что код, использующий calc(), более новый.

График 1.21. Относительная популярность единиц измерения, использующихся внутри calc(), в процентах случаев.
График 1.22. Относительная популярность операторов, использующихся в calc(), в процентах случаев.

Большинство вычислений очень просты: 99,5% вычислений включают до 2 различных единиц измерения, 88,5% вычислений включают до 2 операторов и 99,4% вычислений включают один набор скобок или меньше (3 из 4 вычислений не содержат скобок вообще).

График 1.23. Распределение количества единиц измерения на вхождение calc().

Глобальные ключевые слова и all

В течение долгого времени CSS поддерживал только одно глобальное ключевое слово, inherit, которое включает сброс наследуемого свойства до его унаследованного значения или повторное использование родительского значения для данного ненаследуемого свойства. Оказывается, первое встречается гораздо чаще, чем второе: 81,37% случаев использования inherit обнаружилось в наследуемых свойствах. Остальное — в основном для наследования фона, границ или размеров. Последнее, вероятно, указывает на проблемы с раскладкой, так как при правильном режиме раскладки редко возникает нужда принудительно наследовать width и height.

Ключевое слово inherit было особенно полезно для сброса вырвиглазных цветов ссылок по умолчанию до цвета текста родителя, когда мы намереваемся использовать что-то, кроме цвета, для доступности ссылок. Поэтому неудивительно, что цвет — наиболее распространённое свойство, для которого используется inherit. Почти треть всех случаев применения inherit приходится на свойство color. 75% страниц хотя бы один раз используют color: inherit.

Хотя изначальное значение свойства — концепция, которая существует со времён CSS 1, оно получило собственное ключевое слово, initial, чтобы явно ссылаться на него, только 17 лет спустя, и потребовалось ещё два года, чтобы это ключевое слово получило всеобщую поддержку браузеров в 2015 году. Поэтому неудивительно, что оно используется гораздо реже, чем inherit. В то время как старое наследование было найдено на 85% страниц, initial появляется на 51% из них. Более того, существует большая путаница вокруг того, что на самом деле делает initial, поскольку display возглавляет список свойств, наиболее часто используемых с initialdisplay: initial появляется на 10% страниц. Предположительно, разработчики думали, что такая запись сбрасывает display на его значение из таблиц стилей браузера, и использовали его для включения и выключения display: none. Однако начальное значение свойства displayinline, так что display: initial — просто ещё один способ написать display: inline, который не имеет никаких зависящих от контекста магических свойств.

Вместо этого display: revert фактически сделал бы то, что, вероятно, ожидали эти разработчики, и сбросил бы display до UA-значения для данного элемента. Однако revert намного новее: он был определён в 2015 году и получил всеобщую браузерную поддержку только в этом году, что объясняет его недоиспользование: он появляется только на 0,14% страниц, а половина его использования — это line-height: revert, найденный в последних версиях темы TwentyTwenty для WordPress.

Последнее глобальное ключевое слово, unset, по сути, представляет собой гибрид initial и inherit. Для унаследованных свойств он становится inherit, для остальных — initial, по сути, сбрасывая свойство во всех источниках каскада. Точно так же, как и initial, оно было определено в 2013 году и получило полную браузерную поддержку в 2015 году. Несмотря на более высокую полезность ключевого слова unset, оно используется только на 43% страниц, тогда как initial используется на 51% страниц. Кроме того, за исключением max-width и min-width, в любом другом свойстве использование initial перевешивает использование unset.

График 1.24. Принятие глобальных ключевых слов в процентах от страниц.

Свойство all было представлено в 2013 году и получило почти полную поддержку в 2016 году (кроме Edge) и полную поддержку в начале этого года. Это сокращение для почти всех свойств в CSS (кроме кастомных свойств, direction и unicode-bidi), и принимает только четыре глобальных ключевых слова (initial, inherit, unset и revert) в качестве значений. Оно было задумано как однострочник для сброса CSS, либо как all: unset, либо как all: revert, в зависимости от того, какой сброс мы хотели. Однако распространение всё ещё очень низкое: мы нашли all всего на 477 страницах (0,01% от всех страниц) и только применённое с ключевым словом revert.

Цвет

Говорят, старые шутки самые лучшие, и это также касается цветов. Оригинальный, криптографический, шестнадцатеричный синтаксис #rrggbb остаётся самым популярным способом указать цвет в CSS в 2020 году: половина всех цветов написана таким образом. Следующим по популярности форматом является несколько более короткий трёхзначный шестнадцатеричный формат #rgb с 26%. Хоть он и короче, в то же время он может выражать намного меньше цветов — всего 4 096 из 16,7 миллионов возможных значений sRGB.

График 1.25. Относительная популярность цветовых форматов в процентах случаев.

Также 99,89% функционально определённых цветов sRGB используют устаревший формат с запятыми rgb(127, 255, 84), а не новую форму без запятых rgb(127 255 84). Потому что, несмотря на то, что все современные браузеры принимают новый синтаксис, изменение не даёт разработчикам никаких преимуществ.

Так почему же люди отклоняются от этих проверенных временем форматов? Для задания альфа-прозрачности. Это становится очевидно, если посмотреть на rgba(), который используется в 40 раз чаще, чем rgb() (13,82% против 0,34% от всех цветов), и hsla(), который используется в 30 раз чаще, чем hsl() (0,25% против 0,01% от всех цветов).

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

График 1.26. Относительная популярность цветовых форматов, сгруппированных по поддержке прозрачности, в процентах от их появления на мобильных страницах (исключая #rrggbb и #rgb).

А как насчёт именованных цветов? Ключевое слово transparent, которое просто другой способ сказать rgb(0 0 0 / 0), является самым популярным — 8,25% всех значений sRGB (66% всего использования именованных цветов); за ним следуют все именованные (X11) цвета — я смотрю на тебя, papayawhip — 1,48%. Самыми популярными из них были понятные имена, такие как white, black, red, gray, blue. whitesmoke был наиболее распространённым из необычных имен (конечно, мы можем визуализировать белый дым, ага), в то время как gainsboro, lightCoral и burlywood использовались гораздо реже. Мы можем понять почему — вам нужно сначала найти их, чтобы понять, что они на самом деле означают!

И если уж вы собираетесь использовать причудливые названия цветов, почему бы не определить свои собственные с помощью кастомных свойств в CSS? --intensePurple и --corporateBlue обозначают всё, что вы хотите, чтобы они обозначали. Это, вероятно, объясняет, почему 50% кастомных свойств используются для цветов.

График 1.27. Исследуйте данные о применении именованных цветов с помощью этого интерактивного приложения!
Ключевое слово Десктоп Мобильные
transparent 84,04% 83,51%
white 6,82% 7,34%
black 2,32% 2,42%
red 2,03% 2,01%
currentColor 1,43% 1,43%
gray 0,75% 0,79%
silver 0,66% 0,58%
grey 0,35% 0,31%
green 0,36% 0,30%
magenta 0,00% 0,13%
blue 0,16% 0,13%
whitesmoke 0,17% 0,12%
lightgray 0,06% 0,11%
orange 0,12% 0,10%
lightgrey 0,04% 0,10%
yellow 0,08% 0,06%
Highlight 0,01% 0,04%
gold 0,04% 0,04%
pink 0,03% 0,03%
teal 0,03% 0,02%
График 1.28. Относительная популярность именованных цветов в процентах случаев.

И, наконец, некогда устаревшие, а теперь частично не рекомендуемые системные цвета вроде Canvas и ThreeDDarkShadow — это была ужасная идея, введённая для эмуляции типичного пользовательского интерфейса таких вещей, как Java или Windows 95, и уже не способная угнаться даже за Windows 98 — вскоре оказались на обочине. Некоторые сайты используют эти системные цвета, чтобы попытаться составить ваш цифровой отпечаток — лазейка, которую мы пытаемся закрыть, как мы говорим. Есть несколько веских причин для их использования, а большинство веб-сайтов (99,99%) их не поддерживают, так что всё в порядке.

Как ни странно, довольно полезное значение currentColor составляет всего 0,14% от всех sRGB цветов (1,62% от всех именованных цветов).

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

И мы всё ещё что-то упускаем. Несмотря на реализацию в Safari в 2016 году, применение цветов пространства display-p3 на веб-страницах ничтожно малое. Наш краулинг веба нашёл всего 29 мобильных и 36 десктопных страниц, использующих его! (Причем более половины из них — синтаксические ошибки, описки или попытки использовать нигде не реализованную функцию color-mod()). Нам было любопытно, почему.

Совместимость, так? Вы же не хотите, чтобы всё ломалось? Не хотите. В исследованных нами таблицах стилей мы нашли надёжное использование фолбэков: с порядком в документе, каскадом, @supports, медиа-запросом color-gamut и всякими подобными хорошими штуками. Так что в таблице стилей мы увидим тот цвет, который хотел дизайнер, записанный в display-p3, а также фолбэчный цвет в sRGB. Мы вычислили видимую разницу (расчёт называется ΔE2000) между желаемым и фолбэчным цветом, и она была, как правило, довольно скромной. Небольшая поправка. Тщательное исследование. Фактически, в 37,6% случаев цвет, указанный в display-p3, фактически попадал в диапазон цветов (гамму), с которым может справиться sRGB. Кажется, сейчас люди скорее осторожно экспериментируют с этим, чем пытаются получить реальную выгоду, но в этом пространстве наверняка появятся новые возможности, так что за ними стоит следить.

sRGB display-p3 ΔE2000 В гамме
rgba(255,205,63,1) color(display 1 0.80 0.25 / 1) 3,880 нет
rgba(120,0,255,1) color(display 0.47 0 1 / 1) 1,933 нет
rgba(121,127,132,1) color(display 0.48 0.50 0.52 / 1) 0,391 да
rgba(200,200,200,1) color(display 0.78 0.78 0.78 / 1) 0,274 да
rgba(97,97,99,1) color(display 0.39 0.39 0.39 / 1) 1,474 да
rgba(0,0,0,1) color(display 0 0 0 / 1) 0,000 да
rgba(255,255,255,1) color(display 1 1 1 / 1) 0,015 нет
rgba(84,64,135,1) color(display 0.33 0.25 0.53 / 1) 1,326 да
rgba(131,103,201,1) color(display 0.51 0.40 0.78 / 1) 1,348 да
rgba(68,185,208,1) color(display 0.27 0.75 0.82 / 1) 5,591 нет
rgb(255,0,72) color(display 1 0 0.2823 / 1) 3,529 нет
rgba(255,205,63,1) color(display 1 0.80 0.25 / 1) 3,880 нет
rgba(241,174,50,1) color(display 0.95 0.68 0.17 / 1) 4,701 нет
rgba(245,181,40,1) color(display 0.96 0.71 0.16 / 1) 4,218 нет
rgb(147, 83, 255) color(display 0.58 0.33 1 / 1) 2,143 нет
rgba(75,3,161,1) color(display 0.29 0.01 0.63 / 1) 1,321 нет
rgba(255,0,0,0.85) color(display 1 0 0 / 0.85) 7,115 нет
rgba(84,64,135,1) color(display 0.33 0.25 0.53 / 1) 1,326 да
rgba(131,103,201,1) color(display 0.51 0.40 0.78 / 1) 1,348 да
rgba(68,185,208,1) color(display 0.27 0.75 0.82 / 1) 5,591 нет
#6d3bff color(display .427 .231 1) 1,584 нет
#03d658 color(display .012 .839 .345) 4,958 нет
#ff3900 color(display 1 .224 0) 7,140 нет
#7cf8b3 color(display .486 .973 .702) 4,284 да
#f8f8f8 color(display .973 .973 .973) 0,028 да
#e3f5fd color(display .875 .945 .976) 1,918 да
#e74832 color(display .905882353 .282352941 .196078431 / 1) 3,681 да
График 1.29. В этой таблице показаны фолбэчные цвета sRGB, а затем цвета display-p3. Разница в цвете (ΔE2000): 1 — едва заметна, 5 — отчётливо видна. Это сводная таблица (смотри полную таблицу).
График 1.30. УФ-цветность указанных display-p3 цветов и их фолбэков.

Пурпурные цвета похожи в sRGB и display-p3, возможно, потому, что оба этих цветовых пространства имеют один и тот же базовый синий цвет. Различные красные, оранжево-жёлтые и зеленые цвета находятся рядом с границей гаммы sRGB (почти настолько насыщенные, насколько это возможно) и соответствуют аналогичным точкам около границы гаммы display-p3.

Кажется, есть две причины, по которым веб застрял в sRGB. Первая — отсутствие инструментов, отсутствие хороших палитр, недостаток понимания того, насколько более яркие цвета доступны. Но основная причина, по нашему мнению, заключается в том, что на сегодняшний день Safari является единственным браузером, в котором это реализовано. Ситуация быстро меняется — Chrome и Firefox в процессе реализации прямо сейчас — но до тех пор, пока эта поддержка не появится в стабильных версиях, вероятно, использование display-p3 требует слишком много усилий и приносит слишком мало пользы, потому что только 17% пользователей увидят такие цвета. Большинство людей увидят фолбэк. Таким образом, текущее применение — скорее тонкий сдвиг в яркости цвета, чем большая разница.

Будет интересно посмотреть, как использование цветов display-p3 (существуют и другие варианты, но это единственный, который мы нашли в дикой природе) изменится в течение следующего года или двух.

Потому что широкая цветовая гамма (wide color gamut, WCG) — это только начало. Теле- и киноиндустрия уже перешли от P3 к ещё более широкому диапазону Rec. 2020; а также к более широкому диапазону яркости: от ослепляющих отражений до самых глубоких теней. Расширенный динамический диапазон (High Dynamic Range, HDR) уже доступен в домашних условиях, особенно в играх, потоковом телевидении и фильмах. Интернету есть где навёрстывать упущенное.

Градиенты

Несмотря на моду на минимализм и плоский дизайн, CSS-градиенты применяются на 75% страниц. Как и ожидалось, почти все градиенты используются в фонах. 74,45% страниц задают градиент для фона, и только 7% — для любых других свойств.

Линейные градиенты в 5 раз популярнее радиальных: они появляются почти на 73% страниц в сравнении с 15% для радиальных градиентов. Разница в популярности настолько ошеломляющая, что даже -ms-linear-gradient(), который никогда не был нужен (Internet Explorer 10 поддерживал градиенты как с префиксом -ms-, так и без него), более популярен, чем radial-gradient()! Недавно поддержанный conic-gradient() применяется ещё меньше: он появляется всего на 652 десктопных страницах (0,01%) и 848 мобильных страницах (0,01%), что ожидаемо, поскольку Firefox только-только зарелизил свою реализацию в стабильной версии.

Повторяющиеся градиенты всех типов также довольно недоиспользуются: repeating-linear-gradient() появляется только на 3% страниц, а остальные отстают ещё больше (repeating-conic-gradient() используется всего на 21 странице!).

Градиенты с префиксами также всё ещё очень распространены, хотя нет нужды в префиксах для градиентов с 2013 года. Примечательно, что -webkit-gradient() по-прежнему используется на половине всех веб-сайтов, хотя он не нужен с 2011 года. А -webkit-linear-gradient() по-прежнему является второй наиболее часто используемой градиентной функцией из всех, появляясь на 57% веб-сайтов, при этом также используются другие префиксные формы — их содержат от трети до половины страниц.

График 1.31. Наиболее популярные градиентные функции как процент от страниц.
График 1.32. Наиболее популярные градиентные функции как процент от страниц, исключая вендорные префиксы

Использование цветовых остановок с разными цветами в одной и той же позиции (резкие переходы) для создания полос и других узоров — техника, впервые популяризированная Лией Веру в 2010 году, которая к настоящему времени имеет множество интересных вариаций, в том числе некоторые действительно крутые с режимами наложения. Хоть это и может выглядеть хаком, резкие переходы обнаруживаются на 50% страниц, что указывает на сильную потребность разработчиков в легковесной графике на CSS, чтобы не прибегать к редакторам изображений или внешним SVG-файлам.

Подсказки для интерполяции (или, как называет их Adobe, популяризировавший эту технику, «промежуточные точки») встречаются только на 22% страниц, несмотря на почти универсальную поддержку браузеров с 2015 года. Что позорно, потому что без них цветовые остановки соединяются прямыми линиями в цветовом пространстве, а не плавными кривыми. Такое малое использование, вероятно, отражает неправильное понимание того, что они делают или как их использовать. Сравните это с переходами и анимациями в CSS, где функции плавности (которые делают почти то же самое, т.е. соединяют ключевые кадры кривыми, а не резкими прямыми линиями) используются гораздо чаще (80% переходов). «Промежуточные точки» — не очень понятное описание, а «подсказка для интерполяции» звучит так, будто вы помогаете браузеру выполнять простую арифметику.

В большинстве случаев использование градиентов довольно простое: более 75% градиентов, обнаруженных во всём наборе данных, используют всего 2 цветовые остановки. Фактически, чуть менее половины страниц содержат всего один градиент с более чем тремя цветовыми остановками!

Градиент с наибольшим количеством цветовых остановок — вот этот с 646 остановками! Такой красивый! Он почти наверняка сгенерирован, а его результирующий CSS-код составляет 8 КБ, так что PNG высотой в 1 пиксель, вероятно, также справился бы с этой задачей, ещё и с меньшим размером (наше изображение ниже — 1,1 КБ).

График 1.33. Градиент с самым большим количеством цветовых остановок, 646.

Раскладка

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

Принятие флексов и гридов

В издании 2019 года 41% мобильных и десктопных страниц были помечены как использующие свойства флексбокса. В 2020 году это число выросло до 63% для мобильных и 65% для десктопов. Учитывая количество легаси-сайтов, разработанных до того, как флексбокс стал жизнеспособным инструментом, мы можем с уверенностью сказать, что этот способ раскладки получил широкое распространение.

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

График 1.34. Применение флексов и гридов по годам как процент мобильных страниц.
График 1.35. Применение флексов и гридов по годам как процент десктопных страниц.

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

Итак, давайте рассмотрим ещё одну метрику: на скольких страницах в таблицах стилей указаны display: grid и display: flex? Эта метрика значительно увеличивает применение гридов: 30% страниц используют display: grid хотя бы один раз. Однако такой подход не так сильно влияет на применение флексов, поскольку только 68% страниц содержат display: flex. Хоть это и звучит как впечатляюще-большое распространение флексов, стоит отметить, что таблицы в CSS по-прежнему гораздо более популярны: 80% страниц используют табличные значения для display! Частично такое использование может быть связано с определенными способами задать clearfix, в которых используется display: table, а не с фактической раскладкой.

График 1.36. Методы раскладки и процент страниц, на которых они появляются. Эти данные представляют собой комбинацию определенных значений из свойств display, position и float

Учитывая, что флексы можно было использовать в браузерах раньше, чем гриды, вполне вероятно, что частично флексы применялись для задания сеток. Чтобы использовать флексы в качестве сетки, авторам необходимо выключить некоторую гибкость, присущую флексам. Для этого вы устанавливаете для свойства flex-grow значение 0, а затем задаёте размер флекс-элементов в процентах. Используя эту информацию, мы смогли разобраться, что 19% сайтов, как на десктопах, так и на мобильных, использовали флексы для задания сетки.

Причиной выбора флексов вместо гридов часто упоминается браузерная поддержка, учитывая, что гридовая раскладка не поддерживается в Internet Explorer. Кроме того, некоторые авторы, возможно, ещё не изучили гриды или используют фреймворк с сеткой на основе флексов. Фреймворк Bootstrap в настоящее время использует сетку на основе флексов, как и несколько других популярных фреймворков.

Применение различных раскладок на гридах

Спецификация гридов даёт множество способов описать и определить раскладку в CSS. Самый простой способ использования включает размещение элементов от одной линии сетки к другой. Как насчёт именования линий или использования grid-template-areas?

Для именованных линий мы проверяли на присутствие квадратных скобок в списке треков. Имя или имена размещаются внутри квадратных скобок.

.wrapper {
  display: grid;
  grid-template-columns: [main-start] 1fr [content-start] 1fr [content-end] 1fr [main-end];
}

Результат показал, что на 0,23% мобильных страниц, использующих гриды, есть именованные линии, аналогично на 0,27% десктопов.

Грид-область, позволяющая авторам задавать имена грид-элементам, а затем помещать их в сетку в качестве значения свойства grid-template-areas, показала себя немного лучше. 19% сайтов, имеющих гриды на мобильных страницах, и 20% на десктопах использовали этот метод.

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

Мультиколоночная раскладка

Спецификация мультиколоночной раскладки или мультиколонок позволяет размещать контент в столбцах, как в газете. Хотя мультиколонки и популярны в CSS, поскольку он используется для печати, они менее полезны в Интернете из-за риска создания ситуации, когда читателю нужно скроллить вверх и вниз, чтобы прочитать содержимое. Однако, судя по данным, мультиколоночных страниц значительно больше, чем гридовых: 15,33% на десктопах и 14,95% на мобильных устройствах. В то время как базовые свойства мультиколонок хорошо поддерживаются, более сложное использование и управление разрывами столбцов с помощью фрагментации имеет разношерстную поддержку. Принимая этот факт во внимание, мы были удивлены, какое большое здесь применение.

Размеры блока

Полезно знать, насколько большими будут блоки на вашей странице, но при использовании стандартной блочной модели CSS добавление отступов и границ к размерам content-box требует задавать блоку размер меньше, чем необходимо для рендеринга на вашей странице. Хоть мы и не можем изменить прошлое, свойство box-sizing позволяет авторам переключаться на применение указанного размера к border-box, поэтому размер, который вы устанавливаете, соответствует размеру, который вы видите при рендеринге. Сколько сайтов используют свойство box-sizing? Большинство! Свойство box-sizing появляется в 83,79% десктопных CSS-файлов и в 86,39% CSS-файлов для мобильных.

График 1.37. Распределение количества объявлений border-box на странице.

Медианная десктопная страница имеет 14 объявлений box-sizing. Мобильная — 17. Возможно, из-за того, что системы компонентов вставляют объявление для каждого компонента отдельно, а не как глобальное правило для всех элементов в таблице стилей.

Переходы и анимации

Переходы (transition) и анимации (animation) в целом стали очень популярными: свойство transition используется на 81% всех страниц, а свойство animation — на 73% мобильных страниц и 70% десктопных страниц. Несколько удивительно, что использование на мобильных устройствах, где можно было бы ожидать, что экономия заряда батареи будет приоритетной задачей, не ниже. С другой стороны, CSS-анимации намного более энергоэффективны, чем JS-анимации, особенно то большинство из них, которые анимируют только трансформации и непрозрачность (см. следующий раздел).

Наиболее часто задаваемое свойство перехода (transition) — all, оно используется на 41% страниц. Это немного сбивает с толку, потому что all — начальное значение, его не нужно явно указывать. Затем идут переходы постепенного появления/исчезновения, которые, по-видимому, являются наиболее распространенным типом, используемым более чем на трети просканированных страниц. За ними следуют переходы по свойству transform (чаще всего переходы вращения, масштабирования, перемещения). Удивительно, но переход height гораздо более популярен, чем переход max-height, даже несмотря на то, что последний — часто предлагаемый костыль в ситуациях, когда начальная или конечная высота неизвестны (auto). Также было удивительно увидеть значительное использование свойства scale (2%), несмотря на то, что оно не поддерживается нигде, кроме Firefox. Намеренное использование передового CSS, опечатка или непонимание того, как анимировать трансформации?

График 1.38. Применение свойств перехода в процентах от страниц.

Мы были рады обнаружить, что большинство этих переходов довольно короткие, при медианной продолжительности перехода всего 300 мс, а у 90% веб-сайтов медианная продолжительность составляет менее половины секунды. Это хорошая практика, поскольку более длинные переходы могут сделать пользовательский интерфейс медлительным, в то время как короткий переход сообщает об изменении, не мешая.

График 1.39. Распределение продолжительности переходов.

Авторы спецификации поняли всё правильно! Ease — самая популярная задаваемая функция времени, хоть она и используется по умолчанию и поэтому её можно опустить. Возможно, люди явно указывают значения по умолчанию, потому что предпочитают самодокументирующуюся многословность, или, что более вероятно, потому что они не знают, что это значения по умолчанию. Несмотря на недостатки линейно-прогрессирующей анимации (она имеет тенденцию выглядеть скучно и неестественно), linear является второй наиболее часто используемой функцией времени с показателем 19,1%. Интересно также, что встроенные функции плавности охватывают более 87% всех переходов: только 12,7% решили задать кастомную плавность через cubic-bezier().

График 1.40. Относительная популярность функций времени как процент появления на мобильных страницах.

Похоже, что основным двигателем внедрения анимаций является Font Awesome, о чём свидетельствует имя анимации fa-spin, которое появляется на четверти страниц и, таким образом, возглавляет список самых популярных имён анимаций. Хотя существует множество имён анимаций, похоже, что большинство из них попадает всего в несколько основных категорий, причём каждая пятая анимация является своего рода анимацией вращения. Это также может объяснить высокий процент линейно-прогрессирующих переходов и анимаций: если мы хотим плавное постоянное вращение, то лучше всего использовать linear.

График 1.41. Относительная популярность категорий используемых имён анимаций как процент появлений.

Визуальные эффекты

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

Режимы смешивания

В прошлом году 8% страниц использовали режимы смешивания. В этом году применение выросло значительно: 13% страниц применяют режимы смешивания на элементах (mix-blend-mode) и 2% на фонах (background-blend-mode).

Фильтры

Применение фильтров осталось на высоком уровне, свойство filter появляется на 79,43% страниц. Хотя сначала это было довольно интересно, многие их них, скорее всего, старые фильтры IE DX (-ms-filter), которые используют такое же имя свойства. Как только мы приняли во внимание валидные CSS-фильтры, которые распознаются движком Blink, статистика использования упала до 22% на мобильных и 20% на десктопах, с самым популярным фильтром blur(), появляющимся на 4% страниц.

Другой фильтр, backdrop-filter, позволяет нам применять фильтры только к области позади элемента, что крайне полезно для улучшения контраста на полупрозрачном фоне и создания элегантного эффекта «матового стекла», пришедшего из многих нативных интерфейсов. И хоть он не настолько популярен, как filter, мы нашли backdrop-filter на 6% страниц.

Функция filter() позволяет нам применить фильтр только на конкретном изображении, что чрезвычайно полезно для фонов. К сожалению, сейчас она поддержана только в Safari. Мы нигде не нашли применения filter().

Маски

Десять лет назад у нас появились маски в Safari с -webkit-mask-image, и это было волнующе. Их использовали все кому не лень. В конце концов мы получили спецификацию и набор свойств без префиксов, смоделированных по образцу прототипов в WebKit, и казалось только вопросом времени, когда маскирование станет стандартом с единым синтаксисом во всех браузерах. Перенесёмся на 10 лет вперед, а синтаксис без префикса всё ещё не поддерживается в Chrome и Safari, что означает, что он доступен менее чем в 5% браузеров пользователей по всему миру. Поэтому неудивительно, что -webkit-mask-image по-прежнему более популярен, чем его аналог из стандарта, и встречается на 22% страниц. Однако, несмотря на очень плохую поддержку, mask-image встречается на 19% страниц. Мы видим аналогичный паттерн для большинства других свойств маскирования, причем версии без префикса появляются почти на том же количестве страниц, что и страницы с -webkit-. В целом, несмотря на то, что они больше не на хайпе, маски всё ещё можно найти почти в четвёртой части веба, что указывает на то, что варианты применения всё ещё существуют, несмотря на отсутствие интереса со стороны разработчиков (намёк, намёк!).

График 1.42. Относительная популярность свойств маскирования как процент появлений.

Контуры обрезки

Примерно в то же время, когда стали популярны маски, на сцену вышло ещё одно похожее, но более простое свойство (пришедшее из SVG): clip-path. В отличие от масок, у него была более яркая судьба. Оно довольно быстро было стандартизовано и относительно быстро получило поддержку по всем направлениям, последним форпостом стал Safari, отказавшийся от префикса в 2016 году. Сегодня оно встречается на 19% страниц без префикса и на 13% — с префиксом -webkit-.

Отзывчивый дизайн

Создание сайтов, которые справляются с множеством различных размеров экрана и устройствами, через которые просматривают веб-сайты, стало несколько проще с новыми встроенными гибкими и отзывчивыми методами раскладки, такими как флексы и гриды. Эти методы обычно дополнительно усиливаются использованием медиавыражений. Данные показывают, что 80% десктопных сайтов и 83% мобильных сайтов используют связанные с отзывчивым дизайном медиавыражения, такие как min-width.

Какие медиафичи используют люди?

Как вы могли ожидать, наиболее распространенными медиафичами являются запросы размера вьюпорта, которые использовались с первых дней отзывчивого веб-дизайна. Процент сайтов, проверяющих max-width — 78% как для десктопов, так и для мобильных устройств. Проверка min-width есть на 75% мобильных и 73% десктопных сайтов.

Медиафичу orientation, которая позволяет авторам дифференцировать их раскладку, основываясь на том, портретная или альбомная ориентация у экрана, можно найти на 33% всех сайтов.

Мы видим, что в статистике появляются некоторые новые медиафичи. Медиафича prefers-reduced-motion даёт способ проверить, запрашивал ли пользователь ограничение движений, чтобы веб-сайты могли регулировать количество используемых на них анимаций. Такое можно включить либо явно через пользовательскую настройку в операционной системе, либо неявно, например, из-за разрядки батареи. 24% сайтов проверяют эту медиафичу.

Из других хороших новостей, начинают появляться более новые фичи из спецификации Media Queries Level 4. На мобильных устройствах 5% сайтов проверяют тип указателя, который есть у пользователей. Указатель coarse говорит, что они используют сенсорный экран, тогда как fine говорит про устройство с указателем. Понимание того, как пользователь взаимодействует с вашим сайтом, часто так же полезно, если не более полезно, чем анализ размера экрана. Человек может использовать небольшое экранное устройство с клавиатурой и мышью или устройство с большим экраном высокого разрешения с сенсорным экраном и извлечь выгоду из более крупных областей попадания.

График 1.43. Самые популярные медиафичи как процент страниц.

Распространённые контрольные точки

Самая распространённая контрольная точка, используемая на десктопных и мобильных — min-width в 768px. 54% сайтов используют эту контрольную точку, близко к следующей max-width в 767px в 50% случаев. Фреймворк Bootstrap использует min-width в 768px как свой «средний» размер, так что это может быть причиной такого большого применения. Другие два топ-значения min-width в 1200px (40%) и 992px (37%) также найдены в Bootstrap.

График 1.44. Самые популярные контрольные точки min-width и max-width как процент мобильных страниц.

Пиксели — самая частая единица измерения, применяемая для контрольных точек. Есть несколько появлений em во всём списке, однако указание контрольных точек в пикселях, по-видимому, является популярным выбором. Вероятно, для этого есть много причин. Легаси: все ранние статьи про адаптивный дизайн используют пиксели, и многие люди всё ещё думают про завязывание на конкретные устройства при создании адаптивных дизайнов. Размеры: использование em учитывает размер контента, а не устройства, и это более новый способ мышления про веб-дизайн — возможно, ещё один, позволяющий полностью воспользоваться преимуществами методов задания внутренних размеров для раскладки.

Свойства внутри медиавыражений

На мобильных устройствах 79% и на десктопах 77% медиавыражений используются для изменения свойства display. Возможно, указывая на то, что люди проводят тесты перед переключением на контекст форматирования гридов или флексов. Опять же, это может быть связано с фреймворками, например, с утилитами отзывчивости в Bootstrap. 78% авторов изменяют свойство width внутри медиавыражений, margin, padding и font-size также высоко в рейтинге изменяемых свойств.

График 1.45. Самые популярные свойства, используемые в медиавыражениях, как процент страниц.

Кастомные свойства

В прошлом году только 5% веб-сайтов использовали кастомные свойства. В этом году количество использований взлетело до небес. Согласно прошлогоднему запросу (в котором учитывались только объявления, устанавливающие значения для кастомных свойств), использование увеличилось в четыре раза на мобильных устройствах (19,29%) и в три раза на десктопах (14,47%). Однако, когда мы смотрим на значения, которые ссылаются на кастомные свойства через var(), мы получаем ещё лучшую картину: 27% мобильных страниц и 22% десктопных страниц использовали функцию var() по крайней мере один раз, что указывает на то, что существует значительное количество страниц, использующих var(), только чтобы предложить хуки для настройки, без какой-либо установки значения кастомного свойства.

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

Именование

График 1.46. Относительная популярность имён кастомных свойств для каждой программной сущности в процентах от их появления на мобильных страницах.

Из 1 000 самых популярных имён свойств менее 13 являются «кастомными», как если бы они были придуманы отдельными веб-разработчиками. Подавляющее большинство из них связано с популярным программным обеспечением, таким как WordPress, Elementor и Avada. Чтобы определить это, мы приняли во внимание не только то, какие кастомные свойства появляются в каком программном обеспечении (путём поиска по GitHub), но также и то, какие свойства появляются группами с одинаковой частотой. Это не обязательно означает, что основной способ попадания кастомного свойства на веб-сайт — использование этого программного обеспечения (люди всё ещё копипастят!), но это указывает на то, что у кастомных свойств, определяемых разработчиками, не так много органических общих черт. Единственные имена кастомных свойств, которые, кажется, органически вписались в топ-1000, — это --height, --primary-color и --caption-color.

Применение по типу

Чаще всего кастомные свойства используются, судя по всему, для присвоения имён цветам и поддержания консистентности цветов повсюду. Примерно 1 из 5 десктопных страниц и 1 из 6 мобильных страниц используют кастомные свойства внутри background-color, а топ-11 свойств, которые содержат ссылки на var(), являются либо свойствами цвета, либо сокращениями, которые содержат цвета. Длина является вторым типом по количеству применений, при этом width и height используются с var() на 7% мобильных страниц (что интересно, только на около 3% десктопных страниц). Это также подтверждается типами наиболее популярных значений: значения цветов составляют 52% от всех объявлений кастомных свойств. Размеры (число + единица измерения, например, длины, углы, время и т.д.) были вторым по популярности типом, превышающим безразмерные числа (12%). И это несмотря на рекомендацию отдавать предпочтение последним, поскольку числа могут быть преобразованы в размеры с помощью calc() и умножения, а размеры не могут быть преобразованы в числа, поскольку деление на размеры пока не поддерживается.

График 1.47. Самые частые имена свойств, использующие внутри кастомные свойства, как процент страниц.

В препроцессорах цветовыми переменными часто манипулируют для создания цветовых вариаций, например, различных оттенков. Однако в CSS функции модификации цветов являются просто нереализованным черновиком. Прямо сейчас единственный способ генерировать новые цвета из переменных — использовать переменные для отдельных компонентов и вставлять их в функции цвета, такие как rgba() и hsla(). Однако так делают менее 4% мобильных страниц и 0,6% десктопных страниц, указывая, что частое использование цветовых переменных в первую очередь нужно для хранения целых цветов, причем их вариации являются отдельными переменными, а не генерируются динамически.

График 1.48. Самые популярные имена функций, использующих кастомные свойства, как процент страниц.

Сложность

Затем мы рассмотрели, насколько сложным является применение кастомных свойств. Один из способов оценить сложность кода при разработке программного обеспечения — это форма графа зависимостей. Сначала мы рассмотрели глубину каждого кастомного свойства. Кастомное свойство, для которого задано буквальное значение, например, #fff, имеет глубину 0, тогда как свойство, ссылающееся на него через var(), будет иметь глубину 1 и так далее. Например:

:root {
  --base-hue: 335; /* глубина = 0 */
  --base-color: hsl(var(--base-hue) 90% 50%); /* глубина = 1 */
  --background: linear-gradient(var(--base-color), black); /* глубина = 2 */
}

2 из 3 проверенных кастомных свойств (67%) имели глубину, равную 0, 30% — глубину 1 (немного меньше на мобильных). Менее 1,8% имели глубину 2, практически никакие (0,7%) имели глубину 3 и больше, что говорит о базовом применении. Плюс такого базового применения в том, что так труднее делать ошибки: менее 0,5% страниц содержат циклы.

График 1.49. Распределение глубин кастомных свойств как процент появлений.

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

CSS и JS

В последние несколько лет наблюдается большее взаимодействие между CSS и JavaScript, чем простое указание CSS-классов и стилей или их выключение. Итак, как много мы используем такие технологии, как Houdini, и такие техники, как CSS-in-JS?

Houdini

Вероятно, вы уже слышали о Houdini. Houdini — это набор низкоуровневых API, которые раскрывают части движка CSS, давая разработчикам возможность расширять CSS, подключаясь к процессам стилизации и компоновки в движке рендеринга браузера. Поскольку несколько спецификаций Houdini уже добавлены в браузеры, мы решили, что пора проверить, действительно ли они применяются на практике. Короткий ответ: нет. А теперь более подробный ответ…

Сначала мы рассмотрели Properties & Values API, который позволяет разработчикам зарегистрировать кастомное свойство и задать ему тип, начальное значение и предотвратить его наследование. Одним из основных вариантов использования является возможность анимировать кастомные свойства, поэтому мы также посмотрели, как часто анимируются кастомные свойства.

Как это часто бывает с передовыми технологиями, особенно когда они не поддерживаются во всех браузерах, применение в дикой природе было чрезвычайно низким. Было обнаружено, что только 32 десктопные страницы и 20 мобильных страниц имеют какие-либо зарегистрированные кастомные свойства, хотя это не включает кастомные свойства, которые были зарегистрированы, но не применялись во время сканирования. Только 325 мобильных страниц и 330 десктопных страниц (0,00%) используют кастомные свойства в анимации, и большая часть (74%) из них, похоже, привнесена Vue-компонентом. Практически никакие из них, похоже, не зарегистрированы, хотя, это может быть связано с тем, что анимация не была активна во время краулинга, поэтому не нужно было регистрировать вычисляемый стиль.

Paint API — более широко реализованная спецификация Houdini, которая позволяет разработчикам создавать кастомные CSS-функции, возвращающие значения <image>, например, для реализации кастомных градиентов или шаблонов. Было обнаружено, что всего 12 страниц использовали paint(). Имя каждого ворклета (hexagon, ruler, lozenge, image-cross, grid, dashed-line, ripple) появлялось всего на одной странице каждое, поэтому, скорее всего, единсветнные случаи применения в дикой природе — демки.

Typed OM, ещё одна спецификация Houdini, позволяет получить доступ к структурированным значениям вместо строк в классическом CSS OM. Похоже, что этот API имеет значительно более широкое распространение по сравнению с другими спецификациями Houdini, хотя оно в целом всё ещё остается низким. Typed OM используется на 9 864 десктопных страницах (0,18%) и 6 391 мобильной (0,1%). Хотя эти значения могут показаться низкими, для сравнения, эти числа аналогичны применению <input type="date">! Обратите внимание, что в отличие от большинства статистических данных в этой главе, эти числа отражают фактическое применение, а не только включение в ассеты веб-сайта.

CSS-in-JS

По поводу CSS-in-JS ведётся так много дискуссий (или споров), что можно предположить, что все, кому не лень, применяют его.

График 1.50. Процент сайтов, использующих какую-либо технику CSS-in-JS.

Тем не менее, когда мы посмотрели на использование различных CSS-in-JS-библиотек, оказалось, что всего около 2% веб-сайтов используют какую-либо технику CSS-in-JS, причём Styled Components составляют почти половину от этого.

График 1.51. Относительная популярность библиотек CSS-in-JS как процент появлений на мобильных страницах.

Интернационализация

Английский, как и многие другие языки, пишется горизонтальными линиями, а символы располагаются слева направо. Но некоторые языки (например, арабский и иврит) в основном пишутся справа налево, а есть языки, которые могут быть написаны вертикальными линиями сверху вниз. Не говоря уже о цитатах с других языков. Так что некоторые вещи могут стать довольно сложными. И в HTML, и в CSS есть способы справиться с этим.

Направление письма

Когда текст представлен горизонтальными линиями, большинство систем письма отображают символы слева направо. Урду, арабский язык и иврит отображают символы справа налево, за исключением цифр, которые пишутся слева направо — эти языки двунаправленные. Некоторые символы, такие как скобки, кавычки, знаки препинания, могут использоваться в контексте слева направо или справа налево и считаются нейтральными к направлению. Ситуация усложняется, когда текстовые строки на разных языках вложены друг в друга: например, английский текст, содержащий короткую цитату на иврите, которая содержит некоторые английские слова. Двунаправленный алгоритм Юникода определяет, как размещать абзацы текста с разнонаправленным текстом, но ему необходимо знать базовое направление абзаца.

Для поддержки двунаправленности явная поддержка задания направления доступна как в HTML (через атрибут dir и элемент bdo), так и в CSS (свойства direction и unicode-bidi). Мы рассмотрели использование как HTML, так и CSS.

Только 12,14% мобильных страниц (и примерно 10,76% десктопных) задают атрибут dir в элементе <html>. И это нормально: большинство систем письма в мире — ltr, а значение dir по умолчанию — ltr. Из страниц, которые установили dir на <html>, 91% задали ему значение ltr, в то время как 8,5% задали значение rtl и 0,32% — auto (явное направление — неизвестное значение, в основном полезно для шаблонов, которые будут заполнены неизвестным содержимым). Ещё меньшее число, 2,63%, устанавливают dir на <body>, а не на <html>. Это хорошо, потому что задание его на <html> также затрагивает содержимое в <head>: например, в <title>.

Зачем задавать направление с помощью атрибутов HTML, а не стилей CSS? Одна из причин — разделение ответственности: направление связано с контентом, который входит в компетенцию HTML. Это также рекомендуемая практика: Избегайте использования CSS или управляющих кодов Юникода для задания направления, если вы можете использовать разметку . В конце концов, таблица стилей может не загрузиться, а текст по-прежнему должен быть читабельным.

Логические или физические свойства

Многие из свойств, которым нас учат в начале, когда мы изучаем CSS, такие как width, height, margin-left, padding-bottom, right и так далее, основаны на определенном физическом направлении. Однако, когда контент должен быть представлен на нескольких языках с разными характеристиками направленности, эти физические направления зачастую зависят от языка, например, margin-left часто необходимо переделать в margin-right в языках с письмом справа налево, например в арабском. Направленность — двухмерная характеристика. Например, может потребоваться переделать height в width, когда мы представляем контент вертикальным письмом (например, традиционным китайским).

В прошлом единственным решением этих проблем была отдельная таблица стилей с переопределениями для разных систем письма. Однако совсем недавно CSS приобрёл логические свойства и значения, которые работают так же, как их физические аналоги, но чувствительны к направленности их контекста. Например, вместо width мы можем написать inline-size, а вместо left использовать свойство inset-inline. Помимо логических свойств, существуют также логические ключевые слова, такие как float: inline-start вместо float: left.

Хотя эти свойства достаточно хорошо поддерживаются (за некоторыми исключениями), они мало используются за пределами таблиц стилей браузеров. Ни одно из логических свойств не использовалось более чем на 0,6% страниц. Чаще всего использовались маржины и паддинги. Логические ключевые слова для text-align использовались на 2,25% страниц, но, кроме этого, ни одно из других ключевых слов вообще не встречалось. Это в значительной степени обусловлено браузерной поддержкой: text-align: start и end имеют довольно хорошую браузерную поддержку, тогда как логические ключевые слова для clear и float поддерживаются только в Firefox.

Браузерная поддержка

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

Вендорные префиксы

График 1.52. Процент мобильных страниц, применяющих какие-либо фичи за вендорным префиксом.

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

График 1.53. Самые популярные фичи с вендорными префиксами по типу как процент страниц.

Львиная доля от этого приходится на свойства за префиксом, поскольку 84% всех используемых фичей с префиксом были свойствами, и они использовались на 90,76% мобильных страниц и 89,66% десктопных страниц. Скорее всего, это пережиток префиксной эпохи в CSS3 примерно 2009–2014 годов. Это также видно по самым популярным префиксам, ни один из которых не нуждается в префиксе с 2014 года:

График 1.54. Относительная популярность свойств, которые больше всего используются с вендорными префиксами, как процент появлений.

Некоторые их этих префиксов, вроде -moz-border-radius, не были полезными с 2011 года. Еще больший взрыв мозга от того, что другие свойства с префиксом, которые никогда не существовали, всё ещё довольно распространены: примерно 9% всех страниц включают -o-border-radius!

Не будет сюрпризом, что -webkit- — самый популярный префикс, половина свойств за префиксом используют его:

График 1.55. Относительная популярность вендорных префиксов, как процент появлений.

Псевдоклассы с префиксом не так распространены, как свойства, и ни один из них не используется более чем на 10% страниц. Почти две трети всех псевдоклассов с префиксом в целом предназначены для стилизации плейсхолдеров. Напротив, стандартный псевдокласс :placeholder-shown почти не используется, встречается менее чем на 0,34% страниц.

График 1.56. Самые популярные псевдоклассы с вендорным префиксом в процентах от страниц.

Самый распространенный псевдоэлемент с префиксом — ::-moz-focus-inner, используемый для отключения внутреннего кольца фокуса в Firefox. Он составляет почти четверть от префиксных псевдоэлементов, для которых нет стандартной альтернативы. Еще одна четверть псевдоэлементов с префиксом снова предназначена для стилизации плейсхолдеров, в то время как стандартная версия, ::placeholder, сильно отстаёт и используется только на 4% страниц.

Оставшаяся половина псевдоэлементов с префиксом в основном предназначена для стилизации полос прокрутки и Shadow DOM нативных элементов (инпуты поиска, элементы управления видео и аудио, кнопки-спиннеры, слайдеры, индикаторы, прогрессбары). Это указывает на сильную потребность разработчика в кастомизации нативных элементов управления пользовательского интерфейса, для которой соответствующий стандартам CSS всё ещё не соответствует требованиям, хотя есть несколько текущих обсуждений рабочей группы CSS, чтобы исправить это.

График 1.57. Использование псевдоэлементов с префиксом по категориям.

Не секрет, что Chrome и Safari были более удобны для использования префиксов, но это особенно верно для псевдоэлементов: почти половина всех префиксных псевдоэлементов, которые мы обнаружили, имели префикс -webkit-.

График 1.58. Относительная популярность вендорных префиксов у псевдоэлементов в процентах от их появления на мобильных страницах.

Практически все функции с префиксом (98%) используются для задания градиентов, хотя в этом нет необходимости с 2014 года. Самая популярная из них — -webkit-linear-gradient(), которая используется более чем на четверти изученных страниц. Остальные <2% в основном предназначены для calc, для которого префикс не нужен с 2013 года.

График 1.59. Процент градиентных функций среди всех появлений функций с вендорным префиксом на мобильных страницах

Использование медиафичей с префиксом в целом ниже, при этом самая популярная из них, -webkit-min-pixel-ratio, используется на 13% страниц для определения Retina-экранов. Соответствующая стандартная медиафича resolution наконец превзошла её по популярности и используется на 22% мобильных страниц и 15% десктопных страниц.

В целом, -*-min-pixel-ratio включает три четверти медиафичей с префиксом на десктопах и около половины на мобильных устройствах. Причина такой разницы не в уменьшении использования мобильных устройств, а в том, что другая медиафича с префиксом, -*-high-contrast, гораздо более популярна на мобильных устройствах, составляя почти всю вторую половину медиафичей с префиксом, но всего 18% на десктопах. Соответствующая стандартная медиафича forced-colors все еще является экспериментальной и находится под флагом в Chrome и Firefox и вообще не фигурировала в нашем анализе.

График 1.60. Относительная популярность медиафичей с вендорным префиксом как процент появлений на мобильных страницах.

Директива поддержки фичей

Директива поддержки фичей (@supports) в течение последних нескольких лет неуклонно набирала обороты и использовалась на 39% страниц, что является заметным увеличением по сравнению с 30% в прошлом году.

Но для чего они используются? Мы рассмотрели самые популярные проверки. Результаты могут стать большим сюрпризом — так было для нас! Мы ожидали, что проверки, связанные с гридами, будут возглавлять список, но вместо этого наиболее популярные проверки фичей на сегодняшний день относятся к position: sticky! Они составляют половину всех директив поддержки фичей и используются примерно на четверти страниц. Напротив, проверки, связанные с гридами, составляют всего 2% всех проверок, что указывает на то, что разработчики чувствуют себя достаточно комфортно с браузерной поддержкой гридов, что им не нужно использовать их только в качестве прогрессивного улучшения.

Что ещё большая загадка, так это то, что сам position: sticky не применяется так часто, как проверка его поддержки, появляясь на 10% десктопных страниц и 13% мобильных страниц. Таким образом, существует более полумиллиона страниц, которые проверяют поддержку position: sticky, даже не используя его! Чтобы что?!

Наконец, обнадеживает то, что max() уже входит в десятку наиболее часто проверяемых функций, появляясь на 0,6% десктопных страниц и 0,7% мобильных страниц. Учитывая, что max()min(), и clamp()) получили поддержку только в этом году, это впечатляющее внедрение и подчеркивает, насколько отчаянно в нём нуждались разработчики.

Небольшое, но заметное количество страниц (около 3000 или 0,05%) странным образом использовало @supports с синтаксисом CSS 2, таким как display: block или padding: 0px, который существовал задолго до того, как @supports был реализован. Непонятно, для чего это было нужно. Возможно, он использовался для отделения CSS-правил в старых браузерах, которые ещё не реализовали @supports?

График 1.61. Относительная популярность фичей внутри @supports как процент появлений.

Мета

До сих пор мы смотрели на то, что использовали CSS-разработчики, но в этом разделе мы хотим узнать больше о том, как они это используют.

Повторные объявления

Для определения того, насколько эффективна и удобна в поддержке таблица стилей, одним из грубых факторов является повторение объявлений, то есть соотношение между количеством уникальных (разных) объявлений и общим количеством объявлений. Фактор является приблизительным, потому что нормализовать объявления сложно (border: none, border: 0, даже border-width: 0, плюс ещё несколько — все разные, но говорят одно и то же), а также потому, что существуют уровни повторения: медиа-запрос (самый полезный, но трудный для измерения), таблица стилей или уровень набора данных, как с общими метриками Альманаха.

Мы изучили повторение объявлений и обнаружили, что медианная веб-страница на мобильных устройствах использует в общей сложности 5 454 объявлений, из которых 2 398 являются уникальными. Медианное соотношение (которое основано на наборе данных, а не на этих двух значениях) составляет 45,43%. Это означает, что на медианной странице каждое объявление используется примерно два раза.

Перцентиль Уникальных / Всего
10 30,97%
50 45,43%
90 63,67%
График 1.62. Распределение соотношения повторений на мобильных страницах.

Таким образом, эти соотношения лучше, чем те, что мы знаем из скудных предыдущих данных. В 2017 году Дженс Оливер Мейерт проанализировал 220 популярных веб-сайтов и опубликовал следующие средние значения: 6 121 объявление, из которых 1 698 были уникальными, а соотношение уникальных/всего — 28% (медианное — 34%). Эта тема может потребовать дальнейшего изучения, но, судя по тому немногому, что нам известно на данный момент, повторение объявлений ощутимо — и, возможно, оно либо улучшилось, либо стало более серьёзной задачей для более популярных и, вероятно, более крупных сайтов.

Сокращения и полные свойства

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

Сокращения перед полными свойствами

Использование сокращения и его переопределение несколькими полными свойствами в одном правиле — хорошая стратегия по разным причинам.

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

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

margin: 1em;
margin-bottom: 0;

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

background: url("one.png"), url("two.png"), url("three.png");
background-repeat: no-repeat;

В-третьих, в тех случаях, когда части синтаксиса сокращений выглядят слишком странно, полные свойства могут улучшить читаемость:

/* Вместо: */
background: url("one.svg") center / 50% 50% content-box border-box;

/* Так более читаемо: */
background: url("one.svg") center;
background-size: 50% 50%;
background-origin: content-box;
background-clip: border-box;

Так как часто это происходит? Оказывается, очень часто. 88% страниц используют такую стратегию хотя бы один раз. Безусловно, самое частое свойство, с которым такое происходит, — background-size, составляющее 40% от всех полных свойств, которые идут после своих сокращений, что указывает на то, что синтаксис с косой чертой для background-size в background, возможно, был не самым читаемым или запоминающимся из тех, которые мы могли придумать. Ни одно другое полное свойство не приближается к этой частоте. Остальные 60% — длинный хвост, равномерно распределённый по многим другим свойствам.

График 1.63. Самые популярные полные свойства, которые идут после сокращений в том же правиле.

font

Сокращение font — довольно популярное (используется 49 миллионов раз на 80% страниц), но применяется гораздо реже, чем большинство его полных свойств (кроме font-variant и font-stretch). Это указывает на то, что большинству разработчиков удобно его использовать (поскольку оно появляется на очень многих веб-сайтах). Разработчикам часто приходится переопределять определенные аспекты типографики для правил у потомков, что, вероятно, объясняет, почему полные свойства используются гораздо чаще.

График 1.64. Распространение сокращения font и его полных свойств.

background

Как одно из самых старых, сокращение background также очень широко используется — оно встречается 1 миллиард раз на 92% страниц. Оно используется чаще, чем любое из его полных свойств, кроме background-color, которое используется 1,5 миллиарда раз примерно на том же количестве страниц. Однако это не означает, что разработчики полностью довольны его полным синтаксисом: почти всё (>90%) использование background очень простое, с одним или двумя значениями, скорее всего, цветами и изображениями или изображениями и позиционированием. Для всего остального полные свойства выглядят более самоочевидными.

График 1.65. Сравнение использования сокращения background и его полных свойств.

Маржины и паддинги

Сокращения margin и padding, а также их полные свойства, были одними из наиболее часто используемых CSS-свойств. Паддинг с большей вероятностью будет указываться как сокращение (1,5 миллиарда использований для padding против 300–400 миллионов для каждого полного свойства), тогда как для маржина разница меньше (1,1 миллиарда использований margin против 500–800 миллионов для каждого из его полных свойств). Учитывая первоначальное замешательство многих CSS-разработчиков относительно порядка значений по часовой стрелке в этих сокращениях и правил повторения для двух или трёх значений, мы ожидали, что большинство из этих вариантов использования сокращений будет простым (одно значение), однако мы увидели полный диапазон из одного, двух, трёх или четырёх значений. Очевидно, одно или два значения были более распространенными, но три или четыре были вовсе не редкостью, встречаясь более чем в 25% случаев применения margin и более чем в 10% случаев применения padding.

График 1.66. Сравнение использования сокращений margin и padding и их полных свойств.

flex

Почти все свойства flex, flex-* очень широко применяются, появляясь на 30–60% страниц. Тем не менее, и flex-wrap, и flex-direction применяются гораздо чаще, чем их сокращение. Свойство flex-flow, как правило, применяется с двумя значениями, то есть как более короткий способ задать оба его полных свойства. Несмотря на тщательно продуманные и здравые значения по умолчанию для использования flex с одним или двумя значениями, около 90% применений состоит из синтаксиса с тремя значениями, явно задавая все три его полных свойства.

График 1.67. Сравнение использования сокращений flex и их полных свойств.

grid

Вы знали, что grid-template-columns, grid-template-rows и grid-template-areas имеют сокращение grid-template? Вы знали, что есть свойство grid, и всё это некоторые из его полных свойств? Нет? Что ж, вы в хорошей компании: большинство разработчиков не знало. Свойство grid применялось всего на 5 279 сайтах (0,08%), а grid-template — на 8 215 сайтах (0,13%). Для сравнения, свойство grid-template-columns использовалось на 1,7 миллиона сайтов, почти в 200 раз больше!

График 1.68. Сравнение использования сокращений grid и их полных свойств.

Ошибки в CSS

Как и в случае с любой сложной, развивающейся платформой, не всё сделано правильно. Итак, давайте посмотрим на некоторые ошибки, которые допускают разработчики.

Синтаксические ошибки

Для большинства метрик в этой главе мы использовали CSS-парсер Rework. Это помогает значительно повысить точность, но также означает, что мы менее толерантны к синтаксическим ошибкам по сравнению с браузером. Даже если одно объявление во всей таблице стилей содержит синтаксическую ошибку, парсинг завершится неудачно, а эта таблица стилей будет исключена из анализа. Но сколько таблиц стилей содержат такие синтаксические ошибки? На десктопных страница гораздо больше, чем на мобильных! В частности, почти 10% таблиц стилей, обнаруженных на десктопных страницах, содержали по крайней мере одну неустранимую синтаксическую ошибку, тогда как для мобильных — только 2% таблиц. Заметьте, что это, по сути, нижние границы для синтаксических ошибок, поскольку не все синтаксические ошибки приводят к ошибке парсинга. Например, пропущенная точка с запятой просто приведёт к тому, что следующее объявление будет распаршено как часть значения (например, {property: "color", value: "red background: yellow"}), это не приведёт к ошибке парсинга.

Несуществующие свойства

Мы также рассмотрели наиболее распространённые несуществующие свойства, используя список известных свойств. Мы исключили из этой части анализа свойства с префиксом и вручную убрали проприетарные свойства без префикса (например, behavior для Internet Explorer, которое, как ни странно, всё ещё появляется на 200 000 веб-сайтов). Из оставшихся несуществующих свойств:

  • 37% были сломанной формой свойства с префиксом (например, webkit-transition или -transition).
  • 43% — свойство без префикса, которое существует только с префиксом (например, font-smoothing, которое появилось на 384 000 веб-сайтов), вероятно, включённое для совместимости из-за неправильного предположения, что оно есть в стандарте, или из-за принятия желаемого за действительное, что оно появится в стандарте.
  • Опечатка, которая попала в популярную библиотеку. В ходе этого анализа мы обнаружили, что свойство white-wpace присутствует на 234 027 веб-сайтах. Это слишком много, чтобы одна и та же опечатка произошла естественным путём, поэтому мы решили разобраться в ней. И о чудо, оказывается, это был виджет Facebook! Фикс уже сделан.
  • И ещё одна странность: свойство font-rendering появляется на 2 575 страницах. Однако мы не можем найти свидетельств существования такого свойства, с префиксом или без него. Существует нестандартный -webkit-font-smoothing, который очень популярен и встречается на 3 миллионах веб-сайтов, или примерно на 49% страниц, но font-rendering не настолько близок к тому, чтобы быть орфографической ошибкой. Существует text-rendering, который используется примерно на 100 тысячах веб-сайтов, поэтому вполне возможно, что 2 500 разработчиков неправильно запомнили и cложили в одно font-smoothing и text-rendering.
График 1.69. Самые частые неизвестные свойства.

Полные свойства перед сокращениями

Использование полных свойств после сокращений — хороший способ использовать значения по умолчанию и переопределить несколько свойств. Это особенно полезно для свойств со списком значений, где использование полного свойства помогает нам избежать повторения одного и того же значения несколько раз. С другой стороны, противоположное — использование полного свойства перед сокращением — всегда ошибка, так как сокращённая запись перезапишет полную. Например, взгляните на это:

background-color: rebeccapurple; /* полное свойство */
background: linear-gradient(white, transparent); /* сокращение */

Такая запись создаст градиент не от white к rebeccapurple, а от white к transparent. Цвет фона rebeccapurple будет перезаписан сокращением background, которое следует после него и сбрасывает все его полные свойства до их начальных значений.

Есть две основные причины, по которым разработчики совершают такую ошибку: либо недопонимание того, как работают сокращения и какое полное свойство от какого сокращения сбрасывается, либо просто оставшийся мусор после перемещения объявлений в коде.

Так насколько часто встречается эта ошибка? Это же не может быть распространённой ошибкой среди 6 миллионов лучших веб-сайтов, правильно? Неправильно! Оказывается, это чрезвычайно частая ошибка, которая встречается хотя бы один раз на 54% веб-сайтов!

Подобного рода путаница, кажется, происходит с сокращением background чаще, чем с любым другим сокращением: более половины (55%) этих ошибок связаны с помещением полных свойств background-* перед background. В таком случае это может быть вовсе не ошибкой, а хорошим прогрессивным улучшением: браузеры, которые не поддерживают фичу (вроде линейных градиентов) отрендерят определённые ранее полные значения, в данном случае цвет фона. Браузеры, которые понимают сокращённое свойство, явно или неявно переопределяют полное свойство.

График 1.70. Самые частые сокращения после полных свойств.

Sass

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

Мы уже давно знаем, что разработчикам нужны функции изменения цвета, и мы работаем над ними в спецификации CSS Color 5. Однако анализ вызовов SCSS-функций даёт нам достоверные данные о том, насколько необходимы функции изменения цвета, а также говорит нам, в каких типах изменений цвета разработчики нуждаются чаще всего.

В целом, более одной трети всех вызовов Sass-функций связаны с модификацией цветов или извлечением цветовых компонентов. Практически все найденные нами модификации цветов были довольно простыми. Половина — чтобы сделать цвета темнее. Фактически, darken() был самым популярным вызовом Sass-функции среди всех и использовался даже чаще, чем if()! Похоже, что распространенной стратегией является определение ярких основных цветов и использование darken() для создания их более тёмных вариаций. Противоположное, осветление, встречается реже: lighten() составляет всего 5% от вызовов функций, хотя в целом эта функция по-прежнему занимает 6 место по популярности. Функции, изменяющие альфа-канал, составили около 4% от общего числа вызовов функций, а смешивание цветов составило 3,5% от всех вызовов функций. Другие типы цветовых модификаций, вроде регулировки оттенка, насыщенности, RGB-каналов или ещё более сложная adjust-color(), использовались крайне редко.

График 1.71. Самые популярные вызовы Sass-функций.

Определение кастомных функций — это то, что уже много лет обсуждается в Houdini, но изучение таблиц стилей Sass даёт нам данные, насколько велика эта потребность. Оказывается, довольно велика. По крайней мере половина изученных нами таблиц стилей SCSS содержит кастомные функции, поскольку медианная SCSS-таблица содержит не одну, а две кастомные функции.

В рабочей группе CSS также недавно обсуждалось введение ограниченной формы условных выражений, а Sass даёт нам некоторые данные о том, как часто в этом нуждаются. Почти две трети SCSS-таблиц содержат по крайней мере один блок @if, что составляет почти две трети от всех операторов потока управления. Также существует функция if() для условных выражений внутри значений, которая является второй наиболее часто используемой функцией среди всех (14%).

График 1.72. Использование операторов потока управления в SCSS.

Ещё одна будущая спецификация, над которой сейчас ведётся работа, — это спецификация CSS Nesting, которая даст нам возможность вкладывать правила в другие правила аналогично тому, как мы умеем в Sass и других препроцессорах, используя &. Как часто в SCSS-таблицах используется вложенность? Оказывается, очень часто. Подавляющее большинство SCSS-таблиц используют по крайней мере один явно вложенный селектор: с псевдоклассами (например, &:hover) и классами (например, &.active), составляющими три четверти от случаев вложенности. И это не считая неявную вложенность, когда потомок допускается, а символ & не требуется.

График 1.73. Использование явной вложенности в SCSS.

Вывод

Ух! Очень много данных! Мы надеемся, что вы нашли их такими же интересными, как и мы, и, возможно, даже сформировали собственное мнение о некоторых из них.

Один из наших выводов заключался в том, что популярные библиотеки, такие как WordPress, Bootstrap и Font Awesome, являются основными драйверами внедрения новых функций, в то время как отдельные разработчики, как правило, более консервативны.

Ещё одно наблюдение: старого кода в вебе больше, чем нового. Веб на практике охватывает огромный диапазон: от кода, который мог быть написан 20 лет назад, до новейших технологий, которые работают только в последних версиях браузеров. Однако это исследование показало нам, что существуют мощные фичи, которые зачастую недопоняты и недоиспользуемы, несмотря на хорошую совместимость.

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

Мы вдохновлены тем, как этот анализ может ещё больше повлиять на то, как мы разрабатываем веб-сайты, и с нетерпением ждём возможности увидеть, как эти метрики будут развиваться с течением времени!

Авторы

Цитата

BibTeX
@inbook{WebAlmanac.2020.CSS,
author = "Verou, Lea и Lilley, Chris и Andrew, Rachel и Weyl, Estelle и fantasai, Elika Etemad aka и Meiert, Jens Oliver и Suzanne, Miriam и Rosu, Catalin и Bell, Andy и Viscomi, Rick и Dmitry, Pokidov N. и Pollard, Barry",
title = "CSS",
booktitle = "Web Almanac за 2020 год",
chapter = 1,
publisher = "HTTP Archive",
year = "2020",
language = "Русский",
url = "https://almanac.httparchive.org/en/2020/css"
}