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
.
В Firefox:
- Откройте about:config;
- Поставьте true для флага devtools.inspector.showAllAnonymousContent.
- Откройте DevTools;
- В настройках (
F1
) найдите раздел Инспектор; - Включите опцию Отображать стили браузера.
Здесь появился всего один элемент. Он доступен по селектору ::moz-color-swatch
, что можно увидеть в панели стилей.
К сожалению в старом Edge нет возможности просмотреть и стилизовать теневой DOM.
Где смотреть?
Браузеры позволяют просматривать вычисленные стили (computed styles), а в Chrome и Firefox также можно увидеть таблицы стилей самого браузера, влияющие на элемент.
В Firefox также можно посмотреть на полный файл стилей для форм view-source:resource://gre-resources/forms.css.
Мы будем использовать и стили браузера, и вычисленные стили для разных свойств в зависимости от их информативности.
- Элементы CSS: селекторы и позиционирование c примерами
- Большая подборка лучших ресурсов для изучения CSS
- Самые важные концепции CSS
Собственно color input
Перейдем к свойствам самого элемента color input и их дефолтным значениям в разных браузерах.
Box model
box-sizing
В Firefox по умолчанию установлено значение border-box
, а Chrome и Edge, похоже, просто не изменяют дефолтное значение content-box
.
margin
Вычисленное значение margin
везде равно 0
.
border
А вот рамка (border
) везде разная. В Chrome и Edge ее толщина составляет 1px
, в Firefox – 2px
. Цвета тоже отличаются:
- Chrome –
rgb(169, 169, 169)
; - Edge –
rgb(112, 112, 112)
; - Firefox –
ThreeDLightShadow
– устаревшее значение CSS2 (rgb(227, 227, 227)
).
В 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
.
Но во вкладке computed в Firefox паддинги равны 0 8px
. В чем тут дело?
Дело в том, что браузер использует flow-relative паддинги (логические свойства CSS – вы про них вообще слышали?).
Безусловно, для frontend разработчика было бы лучше, если бы это переопределение было явно обозначено в DevTools (свойство padding
должно быть серым и перечеркнутым).
На данный момент логические свойства для color input использует только Firefox, но в будущем все может измениться. Давайте помнить про эту тонкость.
Размеры
Значение width
для цветового инпута в Chrome и Edge составляет 44px
, а в Firefox – 64px
.
Свойство height
во всех браузерах равно 23px
.
В итоге мы наблюдаем такие box model в разных браузерах:
- 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 размеры элемента.
Шрифты
Шрифты используются разные, но нас волнует только размер, который, к счастью, везде один – 13.33(33)px
.
Фон
В Edge color input имеет свойство background-image
с градиентным значением. В Chrome и Firefox цвет фона равен ButtonFace
(еще одно устаревшее значение CSS2). По идее это rgb(240, 240, 240)
, но Chrome вычисляет его как rgb(221, 221, 221)
.
Однако визуально у инпута в Chrome градиентный фон. Colorpicker показывает, что градиент идет сверху вниз от #f8f8f8
до #ddd
.
В Edge тоже есть странный эффект. Изменение background-color
приводит к изменению background-image
, background-origin
, border-color
или border-style
.
Состояния color input
Установить для элемента псевдоклассы в Chrome и Firefox можно, нажав на кнопку :hov на панели стилей. В Edge для тех же целей служит кнопка :a.
Внимание! В Firefox к состояниям, установленным таким способом, применяются только пользовательские стили без стилей браузера.
:disabled
Атрибут disabled
можно добавить к color input вручную в инспекторе.
В Chrome немного изменился background-color
– rgb(235, 235, 228)
против стандартного rgb(221, 221, 221)
.
Но визуально это практически не заметно.
В Firefox меняется только курсор.
Edge справился лучше всех – он изменяет и фон, и рамку.
:focus
В Chrome у псевдокласса :focus
появляется заметный синий (rgb(77, 144, 254)
) контур.
В Firefox DevTools бесполезен, но сфокусировавшись на инпуте с помощью Tab
, мы увидим синюю рамку и пунктирный прямоугольник внутри.
Объяснение этому можно найти в файле forms.css. Пунктирная рамка появляется у псевдоэлемента ::-moz-focus-inner
, который почему не отображается в Shadow DOM. При фокусировке добавляется псевдокласс (:moz-focusring
) – старая версия нового стандарта :focus-visible
, который сейчас поддерживается лишь частично в Chrome.
А синяя рамка, похоже, задается на уровне ОС.
В Edge очень похожее поведение: псевдокласс :focus
в DevTools не работает, а при реальной фокусировке появляется пунктирный прямоугольник.
:hover
Chrome не имеет никаких особых стилей для hover-состояния color input.
В Firefox все сложнее. Для псевдокласса :hover
появляется новое правило:
При наведении курсора фон color input становится светло-синим, а рамка – синей. Первая мысль: -moz-buttonhoverface
– это и есть светло-синий. Однако в вычисленных стилях браузера фон не изменяется относительно нормального состояния. Так что вероятно этот эффект также задается ОС.
В Edge псевдокласс :hover
устанавливает для color input светло-синий фон (rgb(166, 244, 255)
) и синюю рамку (rgb(38, 160, 218)
). Точные значения цветов можно найти во вкладке computed.
:active
Псевдокласс :active
в Chrome не имеет каких-то особенных стилей. Но если кликнуть по инпуту, едва заметный градиент фона изменится на противоположный.
В Firefox :active
сам по себе тоже не вызывает никаких изменений. Но если добавить к нему :hover
, появится новый набор правил, который устанавливает инлайновые паддинги, новый border-style
и уже знакомый ButtonFace
для background-color
.
На практике единственное совпадение – это горизонтальный сдвиг внутреннего контейнера. Цвет фона становится более светлым, чем в состоянии :hover
, а граница – синей. Эти изменения, вероятно, происходят на уровне ОС.
В Edge стили для :active
те же, что и для :hover
. Но если эти псевдоклассы объединить, картина изменится. Становятся темнее фон (rgb(52, 180, 227)
) и рамка (rgb(0, 137, 180)
).
Swatch wrapper
Эта обертка есть только в Chrome, поэтому для получения кроссбраузерного результата мы должны убедиться, что она не влияет на внутренний элемент.
У swatch wrapper нет маргинов и рамок:
Однако присутствуют паддинги (4px 2px
), которые нужно будет обнулить:
Оба размера равны 100%
, так что с ними можно не возиться:
Свойство box-sizing
имеет значение border-box
.
Все это означает, что padding-box, border-box и margin-box обертки равны и идентичны размерам content-box самого color input (44 x 23
). А content-box имеет размеры (40 x 15
).
Фон прозрачный:
Следует обратить внимание на свойство display
, равное flex
.
- Что происходит, когда вы создаете flex-контейнер?
- Еще больше о Flexbox-лейаутах в больших разноцветных гифках
- 5 техник работы с flexbox, о которых стоит знать веб-разработчику
Swatch
Этот элемент Shadow DOM доступен для стилизации в Chrome и Firefox.
Свойства box-sizing
равно content-box
в Chrome и border-box
в Firefox, так что его придется унифицировать.
Размер шрифта наследуется от самого элемента color input.
Маргины обнулены:
Интересно, что стили Firefox устанавливают для инлайновых маргинов значение auto
, которое все равно вычисляется как нулевое. (Почему так – увидим чуть позже)
Стиль и толщина границы одинаковы (solid 1px
), отличается только цвет:
rgb(119, 119, 119)
в Chrome;grey
(rgb(128, 128, 128)
) в Firefox.
Помните, что вычисленная толщина границы в Firefox (по крайней мере, в Windows) зависит от параметров масштабирования ОС.
Паддинги и там, и там обнулены:
Box model выглядит вполне предсказуемо – swatch занимает весь content-box своего родителя (swatch wrapper в Chrome и сам color input в Firefox):
В Firefox оба размера равны 100%
, именно поэтому значение auto
для горизонтальных маргинов превращается в 0
.
А в Chrome размеры элемента определяются flex-моделью.
Проблемы доступности
Современные frontend технологии стремятся к обеспечению доступности веба для людей с ограниченными возможностями.
В Firefox на Windows поле для ввода цвета имеет огромные проблемы с доступностью. Вы можете сфокусироваться на нем (Tab
) и даже открыть диалог выбора (Enter
), но перемещаться по нему с помощью клавиатуры нельзя. К счастью, привычная комбинация для выхода (Alt + F4
) работает.
В тикете этого бага можно найти обходной маневр. Если переключиться на другое окно, а затем обратно на текущее (Alt + Tab
) диалоговое окно станет доступно.
В Safari дела обстоят еще хуже. Не работает даже фокусировка, если не включен VoiceOver.
Кошмар перфекциониста
Столь глубокое погружение в мелкие особенности конкретного элемента может показаться излишним. Однако это хорошее упражнение для понимания межбраузерных различий.
Жизнь frontend developer не так трудна и интересна, как лет 10 назад, но и сейчас браузеры продолжают радовать нас несогласованностью.
Увы, даже если вам удастся привести color input к единому виду, проблемы доступности никуда не денутся :( Возможно, пора подтолкнуть разработчиков к их решению.
Комментарии