Стандарт для нестандартного
Многое из того, чем люди активно пользуются в вебе, почему-то не охвачено стандартами. Часто соблазн быстро решить задачу одной-двумя нестандартными строчками слишком велик. Особенно если по этой строчке не видно, что она нестандартная. Когда-то давно, в эпоху префиксов, некоторые браузеры любили выпускать свою отсебятину под видом экспериментальных новинок. А в самых запущенных случаях браузеры и вовсе годами тихо саботируют стандарт, принятый остальными, не оставляя разработчикам другого выбора.
Чтобы не отстать от конкурентов, другим браузерам пришлось понемногу внедрять эту отсебятину и у себя. Со временем она стала стандартом де-факто. И практикам из WHATWG ничего не осталось, как описать ее в особом стандарте — стандарте совместимости (Compatibility Standard). Давайте посмотрим, что там есть и где оно нам может пригодиться!
-webkit-всё-подряд
Первое, что бросается в глаза, на каком месте ни раскрой эту спецификацию — обилие префикса -webkit-
. Он и в @-директивах (напр. @keyframes
), и в медиавыражениях, и в CSS-свойствах, и в DOM API… Всё верно: стандарт совместимости предписывает всем браузерам понимать записи с чужим браузерным префиксом. Так поневоле исторически сложилось. Одно время слишком многие веб-разработчики чересчур увлекались экспериментальными новинками за префиксом -webkit-
. Особенно за рубежом, где идеи веб-стандартов продвигали не так активно. Так что на всякий случай не полагайтесь на префикс -webkit-
как хак, чтобы какой-то код сработал только в WebKit-браузерах: это уже так не работает, браузеры давно стали «всеядными». И это стандарт.
Чаще всего по стандарту совместимости записи с префиксом -webkit-
должны считаться просто псевдонимом, «алиасом» для нормальных, беспрефиксных CSS-записей. Это касается директивы @keyframes
и целой кучи CSS-свойств, прежде всего относящихся к CSS-трансформациям, анимациям и флексбоксам (в общем, почти всему тому, что когда-то давно называлось звучным словом «CSS3»). Но есть некоторые исключения и нюансы.
Старые градиенты
Стандарт совместимости предписывает браузерам понимать префикс -webkit-
для CSS-градиентов — линейных и радиальных, обычных и повторяющихся (-repeating-
). Но здесь нюанс: они соответствуют не современной редакции спецификации градиентов, а архивной редакции 2011 г. Без ключевого слова to и «волшебных углов». Так что браузеры теперь вынуждены тащить старый движок градиентов в придачу к новому. Это, конечно, не повод пользоваться старым вместо нового. Но это напоминание о цене изменений в вебе, особенно для чего-то, уже массово внедренного. Будем надеяться, что рабочая группа CSS извлекла из этой истории урок.
Проверка на «ретину»
Казалось бы, CSS-медиавыражения — давно стандарт (рекомендация W3C, самый зрелый статус). В том числе проверка разрешения экрана (min-
/max-resolution
). Но один браузер (Safari) почему-то уже много лет не торопится выпускать поддержку стандартного синтаксиса resolution
из-за флага. Из-за этого приходится использовать стандартный синтаксис параллельно со старым -webkit-device-pixel-ratio
, совсем как давным-давно.
Стандарт совместимости предписывает, чтобы браузеры воспринимали -webkit-device-pixel-ratio
как псевдоним для resolution
, со значением в единицах dppx
(«точек экрана на CSS-пиксель»). Так что, теоретически, можно обойтись одним нестандартным -webkit-device-pixel-ratio
и рассчитывать, что все браузеры его поймут. Хотя лично я бы не рисковал:)
Заливка и обводка для текста
Дизайнеры любят эффектные заголовки, где контуры букв залиты градиентом или другой картинкой. Когда-то единственным способом сверстать это была картинка. Уже давно это можно кроссбраузерно сделать встроенным SVG с элементом <text>, к которому применимы все SVG-шные (и многие СSS-ные) украшения, при этом он остается выделяемым и копируемым текстом. В современном CSS есть и еще более удобные решения этой задачи. Но часто хочется чего-нибудь «попроще и побыстрее»… Лет 10 назад Apple втихаря добавили такой соблазн, и он стал так популярен, что попал в стандарт совместимости.
Соблазн «маскируется» под стандартное CSS-свойство background-clip
: вдобавок к трем стандартным значениям коварные искусители с яблоком добавили для своей префикснутой версии четвертое — text
. Оно обрезает фон по контуру символов текста. Т.е. выделяет заливку для переднего плана (англ. «Foreground»), действуя через задний план (англ. «Background»). Заголовок соотв. раздела стандарта совместимости — для англоговорящих он выглядит как «Обрезка текста переднего плана: свойство “обрезка-заднего-плана”» — наглядно подчеркивает эту нелогичность.
Неудивительно, что официальные стандарты долго и упорно сопротивлялись странному «нововведению», и даже в черновике фонов и границ 4 уровня это значение пока под большим вопросом. Но все современные браузеры поддерживают его (с префиксом). Так что сегодня -webkit-background-clip: text
— решение не только простое, но и достаточно кроссбраузерное.
Одна проблема: фона, обрезанного по границам текста, не видно за цветом самого текста. И по сей день в сети встречаются примеры самого «очевидного» и «лобового» решения этой проблемы (например, на CSS-Tricks):
Не надо так. Не надо делать текст по умолчанию невидимым везде, чтобы потом браузер, может быть, если повезет, применил какую-то магию и опять «проявил» его. Невидимый текст вызывает подозрения, что его пытались спрятать, а это не любят поисковики. Да и пользователи IE и Оперы Мини имеют право хотя бы прочитать тот заголовок. Не убивайте текст, пожалуйста!
Лучше пусть старый добрый color
у текста останется неизменным и служит надежным фолбэком, а заодно индикатором того, что вы ни от кого его не прячете. А чтобы заливка текста не мешала показу фона, используйте специальное свойство из того же стандарта совместимости: -webkit-text-fill-color
. Оно работает в тех же самых браузерах, что и -webkit-background-clip: text
. У него приоритет перед color
, а значение по умолчанию —currentColor
(текущее значение color
), поэтому по умолчанию его действие незаметно, но его легко переопределить. Так что в старых браузерах сработает обычный color
и пользователи увидят обычный текст. А в браузерах, поддерживающих стандарт совместимости, -webkit-text-fill-color: transparent
получит приоритет над color
, и пользователи увидят фон, красиво обрезанный по контуру букв благодаря -webkit-background-clip: text
:
See the Pen BPXzrM by Ilya Streltsyn (@SelenIT) on CodePen.
Кстати, при виде свойства для заливки текста у меня давно возникает вопрос: что мешало добавить к -webkit-text-fill-color
еще и -webkit-text-fill-image
— и заливать текст картинкой не через задни…й план, а напрямую, явно? Были бы два похожих, но независимых набора свойств — один для заднего плана (background-*
), другой для переднего (text-fill-*
). Разве не логичнее? На вопрос, почему так не сделали сразу, мне приводили аргументы про сложности с очередностью отрисовки теней и т.п., но меня они пока не убедили. Может, вы убедите меня в комментариях?
Пока же необходимость вынужденного сосуществования стандартного background-clip
и «стандартно нестандартного» -webkit-background-clip: text
вынуждает постоянно быть начеку: ведь где сложность, там и баги. Например, Firefox впадает в панику, когда к одному элементу нужно применить несколько фонов, один из которых обрезан по тексту (спасибо за бдительность Ане Тюдор). Даже фолбэк в этой ситуации не спасает.
Чтобы текст эффектного заголовка оставался читаемым при любом раскладе, можно воспользоваться еще одним свойством из того же раздела того же стандарта совместимости (и с той же браузерной поддержкой): -webkit-text-stroke
. Оно — сокращение для двух подсвойств, -webkit-text-stroke-width
и -webkit-text-stroke-color
, и принимает соответственно толщину и цвет обводки контура символов. Лучше, конечно, обсудить это с дизайнером — вдруг он просто «не знал, что так можно» и сам с радостью ухватится за эту идею. Но во многих случаях, думаю, если большому картиночному заголовку добавить что-то типа -webkit-text-stroke: .5px rgba(0,0,0,.2)
, ничьи эстетические чувства особо не пострадают: да, граница текста будет выглядеть чуть контрастнее, но это можно даже считать плюсом. Зато если картинка по какой-то причине не загрузилась или не обрезалась, как надо, можно будет хоть контуры букв разглядеть.
See the Pen WKVxLe by Ilya Streltsyn (@SelenIT) on CodePen.
В общем, если уж делать градиентный/графический текст нестандартными средствами — давайте хотя бы делать это по стандарту для нестандартного, используя всю его мощь! :)
Хорошая новость
Как и все стандарты WHATWG, стандарт совместимости — это «живой стандарт», постоянно обновляемый и всегда актуальный на текущий момент. Если присмотреться к нему, можно заметить, что когда-то этот список вынужденно поддерживаемой нестандартщины был больше, чем теперь. Например, целый раздел «Интерфейс WebKitCSSMatrix
» сейчас состоит из единственного примечания:
Примечание: WebKitCSSMatrix теперь определяется спецификацией DOM Geometry. [geometry-1].
Ссылка ведет на отдельный модуль геометрических интерфейсов 1 уровня — совместное детище рабочих групп CSS и SVG, описывающее DOM-интерфейсы для всяких геометрических трансформаций над точками и фигурами, в том числе страшные матрицы. В нем сказано, что старый нестандартный синтаксис для этих матриц теперь будет просто псевдонимом для нового интерфейса DOMMatrix
.
Так что иногда вынужденно стандартизированные нестандартные штуки со временем добираются до «нормальных» стандартов, и необходимость в «нестандартном стандарте» для них отпадает.
Но пока стандартные нестандартные штуки существуют — о них как минимум полезно знать. Чтобы применять их с умом и с пользой, без вреда для доступности и совместимости.
P.S. Это тоже может быть интересно: