Такой разный color input: межбраузерный кошмар перфекциониста

Frontend стремится к унификации, но браузеры остаются своевольными ребятами. Разбираемся в межбраузерных различиях элемента color input.

[codepen_embed height="265" theme_id="0" slug_hash="xvxQjL" default_tab="html,result" user="mohnatus-the-lessful"]See the Pen <a href='https://codepen.io/mohnatus-the-lessful/pen/xvxQjL/'>input type color</a> by FurryCat (<a href='https://codepen.io/mohnatus-the-lessful'>@mohnatus-the-lessful</a>) on <a href='https://codepen.io'>CodePen</a>.[/codepen_embed]

Что внутри?

Чтобы исследовать инпут, нужно получить доступ к его внутренней структуре (shadow DOM).

В Chrome:

  • Откройте DevTools;
  • В разделе Settings (F1) -> Preferences найдите пункт Elements;
  • Поставьте галочку Show user agent shadow DOM.

Появятся два элемента <div>. Внешний доступен по селектору ::-webkit-color-swatch-wrapper, внутренний – ::-webkit-color-swatch.

Такой разный color input: межбраузерный кошмар перфекциониста

В Firefox:

  • Откройте about:config;
  • Поставьте true для флага devtools.inspector.showAllAnonymousContent.
  • Откройте DevTools;
  • В настройках (F1) найдите раздел Инспектор;
  • Включите опцию Отображать стили браузера.

Здесь появился всего один элемент. Он доступен по селектору ::moz-color-swatch, что можно увидеть в панели стилей.

Такой разный color input: межбраузерный кошмар перфекциониста

К сожалению в старом Edge нет возможности просмотреть и стилизовать теневой DOM.

Где смотреть?

Браузеры позволяют просматривать вычисленные стили (computed styles), а в Chrome и Firefox также можно увидеть таблицы стилей самого браузера, влияющие на элемент.

Такой разный color input: межбраузерный кошмар перфекциониста
Стили браузера в Chrome (сверху) и Firefox (снизу)

В Firefox также можно посмотреть на полный файл стилей для форм view-source:resource://gre-resources/forms.css.

Такой разный color input: межбраузерный кошмар перфекциониста

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

Собственно color input

Перейдем к свойствам самого элемента color input и их дефолтным значениям в разных браузерах.

Box model

box-sizing

В Firefox по умолчанию установлено значение border-box, а Chrome и Edge, похоже, просто не изменяют дефолтное значение content-box.

Такой разный color input: межбраузерный кошмар перфекциониста
box-sizing в Chrome, Firefox и Edge (сверху вниз)

margin

Вычисленное значение margin везде равно 0.

Такой разный color input: межбраузерный кошмар перфекциониста
margin в Chrome, Firefox и Edge (сверху вниз)

border

А вот рамка (border) везде разная. В Chrome и Edge ее толщина составляет 1px, в Firefox – 2px. Цвета тоже отличаются:

Такой разный color input: межбраузерный кошмар перфекциониста
border в Chrome, Firefox и Edge (сверху вниз)

В Firefox (по крайней мере в Windows) настройки масштабирования ОС (Настройки -> Система -> Дисплей -> Масштаб и разметка) влияют на вычисленное значение свойства border-width и, похоже, это как-то связано со стилем рамки.

Самое странное, что вычисленные значения для различных уровней масштабирования, похоже, выбраны случайно. Если сохранить исходный стиль border-style: outset, мы получим:

  • 1.6px – 125%;
  • 2px – 150%;
  • 1.7px – 175%;
  • 1.5px – 200%;
  • 1.8px – 225%;
  • 1.6px – 250%;
  • 1.66667px – 300%.

Но если поменять его на border-style: solid, то на всех масштабах, кратных 50%, вычисленная толщина рамки станет равна 2px. Да, frontend разработка зависит от многих внешних факторов.

padding

В Chrome и Edge паддинги color input имеют значение 1px 2px, а в стилях Firefox – везде 1px.

Такой разный color input: межбраузерный кошмар перфекциониста
padding в Chrome, Firefox и Edge (сверху вниз)

Но во вкладке computed в Firefox паддинги равны 0 8px. В чем тут дело?

Такой разный color input: межбраузерный кошмар перфекциониста

Дело в том, что браузер использует flow-relative паддинги (логические свойства CSS – вы про них вообще слышали?).

Такой разный color input: межбраузерный кошмар перфекциониста

Безусловно, для frontend разработчика было бы лучше, если бы это переопределение было явно обозначено в DevTools (свойство padding должно быть серым и перечеркнутым).

На данный момент логические свойства для color input использует только Firefox, но в будущем все может измениться. Давайте помнить про эту тонкость.

Размеры

Значение width для цветового инпута в Chrome и Edge составляет 44px, а в Firefox – 64px.

Такой разный color input: межбраузерный кошмар перфекциониста
Ширина color input в Chrome, Firefox и Edge (сверху вниз)

Свойство height во всех браузерах равно 23px.

Такой разный color input: межбраузерный кошмар перфекциониста
Высота color input Chrome, Firefox и Edge (сверху вниз)

В итоге мы наблюдаем такие box model в разных браузерах:

Такой разный color input: межбраузерный кошмар перфекциониста
Box Model цветового инпута в Chrome, Firefox и Edge (сверху вниз)
  • content-box: Chrome и Edge – 44 x 23, Firefox – 44 x 19;
  • padding-box: Chrome и Edge – 48 x 25, Firefox – 60 x 19;
  • border-box: Chrome и Edge – 50 x 27, Firefox – 64 x 23.

В Chrome эти размеры установлены явно (в Edge возможно тоже). В Firefox на вкладке computed нельзя увидеть, откуда они взялись. Однако в стилях можно найти flow-relative размеры элемента.

Такой разный color input: межбраузерный кошмар перфекциониста

Шрифты

Шрифты используются разные, но нас волнует только размер, который, к счастью, везде один – 13.33(33)px.

Такой разный color input: межбраузерный кошмар перфекциониста
Размер шрифта в Chrome, Firefox и Edge (сверху вниз)

Фон

В Edge color input имеет свойство background-image с градиентным значением. В Chrome и Firefox цвет фона равен ButtonFace (еще одно устаревшее значение CSS2). По идее это rgb(240, 240, 240), но Chrome вычисляет его как rgb(221, 221, 221).

Такой разный color input: межбраузерный кошмар перфекциониста
background в Chrome, Firefox и Edge (сверху вниз)

Однако визуально у инпута в Chrome градиентный фон. Colorpicker показывает, что градиент идет сверху вниз от #f8f8f8 до #ddd.

Такой разный color input: межбраузерный кошмар перфекциониста

В Edge тоже есть странный эффект. Изменение background-color приводит к изменению background-image, background-origin, border-color или border-style.

Такой разный color input: межбраузерный кошмар перфекциониста
Edge: побочные эффекты изменения цвета фона color input

Состояния color input

Установить для элемента псевдоклассы в Chrome и Firefox можно, нажав на кнопку :hov на панели стилей. В Edge для тех же целей служит кнопка :a.

Такой разный color input: межбраузерный кошмар перфекциониста
Панель состояний в Chrome, Firefox, Edge (сверху вниз)

Внимание! В Firefox к состояниям, установленным таким способом, применяются только пользовательские стили без стилей браузера.

:disabled

Атрибут disabled можно добавить к color input вручную в инспекторе.

В Chrome немного изменился background-colorrgb(235, 235, 228) против стандартного rgb(221, 221, 221).

Такой разный color input: межбраузерный кошмар перфекциониста

Но визуально это практически не заметно.

Такой разный color input: межбраузерный кошмар перфекциониста

В Firefox меняется только курсор.

Такой разный color input: межбраузерный кошмар перфекциониста

Edge справился лучше всех – он изменяет и фон, и рамку.

Такой разный color input: межбраузерный кошмар перфекциониста

Такой разный color input: межбраузерный кошмар перфекциониста

:focus

В Chrome у псевдокласса :focus появляется заметный синий (rgb(77, 144, 254)) контур.

Такой разный color input: межбраузерный кошмар перфекциониста

В Firefox DevTools бесполезен, но сфокусировавшись на инпуте с помощью Tab, мы увидим синюю рамку и пунктирный прямоугольник внутри.

Такой разный color input: межбраузерный кошмар перфекциониста

Объяснение этому можно найти в файле forms.css. Пунктирная рамка появляется у псевдоэлемента ::-moz-focus-inner, который почему не отображается в Shadow DOM. При фокусировке добавляется псевдокласс (:moz-focusring) – старая версия нового стандарта :focus-visible, который сейчас поддерживается лишь частично в Chrome.

А синяя рамка, похоже, задается на уровне ОС.

Такой разный color input: межбраузерный кошмар перфекциониста

В Edge очень похожее поведение: псевдокласс :focus в DevTools не работает, а при реальной фокусировке появляется пунктирный прямоугольник.

Такой разный color input: межбраузерный кошмар перфекциониста

:hover

Chrome не имеет никаких особых стилей для hover-состояния color input.

В Firefox все сложнее. Для псевдокласса :hover появляется новое правило:

Такой разный color input: межбраузерный кошмар перфекциониста

При наведении курсора фон color input становится светло-синим, а рамка – синей. Первая мысль: -moz-buttonhoverface – это и есть светло-синий. Однако в вычисленных стилях браузера фон не изменяется относительно нормального состояния. Так что вероятно этот эффект также задается ОС.

Такой разный color input: межбраузерный кошмар перфекциониста

В Edge псевдокласс :hover устанавливает для color input светло-синий фон (rgb(166, 244, 255)) и синюю рамку (rgb(38, 160, 218)). Точные значения цветов можно найти во вкладке computed.

Такой разный color input: межбраузерный кошмар перфекциониста

:active

Псевдокласс :active в Chrome не имеет каких-то особенных стилей. Но если кликнуть по инпуту, едва заметный градиент фона изменится на противоположный.

В Firefox :active сам по себе тоже не вызывает никаких изменений. Но если добавить к нему :hover, появится новый набор правил, который устанавливает инлайновые паддинги, новый border-style и уже знакомый ButtonFace для background-color.

Такой разный color input: межбраузерный кошмар перфекциониста

На практике единственное совпадение – это горизонтальный сдвиг внутреннего контейнера. Цвет фона становится более светлым, чем в состоянии :hover, а граница – синей. Эти изменения, вероятно, происходят на уровне ОС.

Такой разный color input: межбраузерный кошмар перфекциониста

В Edge стили для :active те же, что и для :hover. Но если эти псевдоклассы объединить, картина изменится. Становятся темнее фон (rgb(52, 180, 227)) и рамка (rgb(0, 137, 180)).

Такой разный color input: межбраузерный кошмар перфекциониста

Swatch wrapper

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

У swatch wrapper нет маргинов и рамок:

Такой разный color input: межбраузерный кошмар перфекциониста

Однако присутствуют паддинги (4px 2px), которые нужно будет обнулить:

Такой разный color input: межбраузерный кошмар перфекциониста

Оба размера равны 100%, так что с ними можно не возиться:

Такой разный color input: межбраузерный кошмар перфекциониста

Свойство box-sizing имеет значение border-box.

Такой разный color input: межбраузерный кошмар перфекциониста

Все это означает, что padding-box, border-box и margin-box обертки равны и идентичны размерам content-box самого color input (44 x 23). А content-box имеет размеры (40 x 15).

Такой разный color input: межбраузерный кошмар перфекциониста

Фон прозрачный:

Такой разный color input: межбраузерный кошмар перфекциониста

Следует обратить внимание на свойство display, равное flex.

Такой разный color input: межбраузерный кошмар перфекциониста

Swatch

Этот элемент Shadow DOM доступен для стилизации в Chrome и Firefox.

Свойства box-sizing равно content-box в Chrome и border-box в Firefox, так что его придется унифицировать.

Такой разный color input: межбраузерный кошмар перфекциониста
swatch box-sizing в Chrome (наверху) и Firefox (внизу)

Размер шрифта наследуется от самого элемента color input.

Такой разный color input: межбраузерный кошмар перфекциониста
swatch font-size в Chrome (наверху) и Firefox (внизу)

Маргины обнулены:

Такой разный color input: межбраузерный кошмар перфекциониста
swatch margin в Chrome (наверху) и Firefox (внизу)

Интересно, что стили Firefox устанавливают для инлайновых маргинов значение auto, которое все равно вычисляется как нулевое. (Почему так – увидим чуть позже)

Такой разный color input: межбраузерный кошмар перфекциониста

Стиль и толщина границы одинаковы (solid 1px), отличается только цвет:

  • rgb(119, 119, 119) в Chrome;
  • grey (rgb(128, 128, 128)) в Firefox.
Такой разный color input: межбраузерный кошмар перфекциониста
swatch border в Chrome (наверху) и Firefox (внизу)

Помните, что вычисленная толщина границы в Firefox (по крайней мере, в Windows) зависит от параметров масштабирования ОС.

Паддинги и там, и там обнулены:

Такой разный color input: межбраузерный кошмар перфекциониста
swatch padding в Chrome (наверху) и Firefox (внизу)

Box model выглядит вполне предсказуемо – swatch занимает весь content-box своего родителя (swatch wrapper в Chrome и сам color input в Firefox):

Такой разный color input: межбраузерный кошмар перфекциониста
swatch box model в Chrome (наверху) и Firefox (внизу)

В Firefox оба размера равны 100%, именно поэтому значение auto для горизонтальных маргинов превращается в 0.

Такой разный color input: межбраузерный кошмар перфекциониста
Размеры swatch в Chrome (наверху) и Firefox (внизу)

А в Chrome размеры элемента определяются flex-моделью.

Такой разный color input: межбраузерный кошмар перфекциониста

Проблемы доступности

Современные frontend технологии стремятся к обеспечению доступности веба для людей с ограниченными возможностями.

В Firefox на Windows поле для ввода цвета имеет огромные проблемы с доступностью. Вы можете сфокусироваться на нем (Tab) и даже открыть диалог выбора (Enter), но перемещаться по нему с помощью клавиатуры нельзя. К счастью, привычная комбинация для выхода (Alt + F4) работает.

В тикете этого бага можно найти обходной маневр. Если переключиться на другое окно, а затем обратно на текущее (Alt + Tab) диалоговое окно станет доступно.

В Safari дела обстоят еще хуже. Не работает даже фокусировка, если не включен VoiceOver.

Кошмар перфекциониста

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

Жизнь frontend developer не так трудна и интересна, как лет 10 назад, но и сейчас браузеры продолжают радовать нас несогласованностью.

Увы, даже если вам удастся привести color input к единому виду, проблемы доступности никуда не денутся :( Возможно, пора подтолкнуть разработчиков к их решению.

Была ли статья полезной? Делитесь своими идеями для следующих статей в комментариях :)

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
DevOps
Санкт-Петербург, от 150000 RUB до 400000 RUB
PHP Developer
от 200000 RUB до 270000 RUB

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ