22
Июл
2019

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

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

See the Pen input type color by FurryCat (@mohnatus-the-lessful) on CodePen.0

Что внутри?

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

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

Запись Такой разный color input: межбраузерный кошмар перфекциониста впервые появилась Библиотека программиста.
Share

Тебе может это понравится...