Создание слайдера который выглядит одинаково во всех браузерах

alexei16/02/2022 - 09:14
Создание слайдера который выглядит одинаково во всех браузерах

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

Анатомия диапазонного элемента ввода

Диапазонный элемента ввода состоит из двух основных частей:

  1. Дорожка - часть слайдера, по которой ходит ползунок. Или другими словами, длинный элемент, представляющий значения диапазона, которые можно выбрать.
  2. Ползунок - элемент на дорожке, который пользователь может перемещать, чтобы выбрать различные значения диапазона.
Диапазонный элемент ввода состоит из дорожки и ползунка
Диапазонный элемент ввода состоит из дорожки и ползунка

Часто диапазонный элемент ввода также называют "слайдером", и в этой статье мы будем использовать эти термины взаимозаменяемо.

Браузерные различия

Чтобы продемонстрировать, зачем нам вообще нужен учебник по стилизации диапазонного элемента ввода, мы рассмотрим некоторые скриншоты внешнего вида диапазонного элемента ввода по умолчанию и то, как он отображается в четырех основных браузерах (Chrome, Firefox, Safari и Edge).

Примечание: Скриншоты были сделаны в сентябре 2021 года и могут отличаться от текущего состояния по мере обновления браузеров.

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

Диапазонный элемент ввода по умолчанию в Chrome
Диапазонный элемент ввода по умолчанию в Chrome

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

Диапазонный элемент ввода по умолчанию в Firefox
Диапазонный элемент ввода по умолчанию в Firefox

Слайдер Safari ближе всего по внешнему виду к версии в Firefox, но, опять же, у него есть свои отличия. Здесь у дорожки есть эффект тени, а высота и ширина ползунка меньше, чем у версий в Chrome и Firefox. Если присмотреться, то вы также заметите, что ползунок не центрирован на дорожке, что придает ему неаккуратный вид.

Диапазонный элемент ввода по умолчанию в Safari
Диапазонный элемент ввода по умолчанию в Safari

И последний, но не менее важный – это Edge, который теперь, когда Microsoft разрабатывает свой браузер на базе Chromium, намного лучше соответствует трем другим браузерам, чем его предшественник. Тем не менее, элемент по-прежнему отображается иначе, чем в других браузерах. Версия элемента в Edge очень похожа на версию в Chrome, за исключением того, что она имеет темно-серый цвет фона для ползунка и левой стороны дорожки перед ползунком.

Диапазонный элемент ввода по умолчанию в Edge
Диапазонный элемент ввода по умолчанию в Edge

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

Сброс стилей элемента (Базовые стили)

Поскольку различия в браузерах велики, нам нужно начать с чистого листа. Обнулив стили по умолчанию, применяемые в каждым браузере, мы сможем начать работать над созданием более единообразного вида элемента. Мы будем использовать селектор input[type="range"], и применяемые здесь стили будут действовать как сброс CSS для элемента ввода.

Чтобы воздействовать на базовые стили, нам потребуются четыре свойства:

  1. -webkit-appearance: none;

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

  2. background: transparent;

    Это удаляет фон по умолчанию.

  3. cursor: pointer;
  4. width

    Устанавливает общую ширину элемента ввода.


input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: pointer;
  width: 15rem;
}

Стилизация дорожки слайдера

При стилизации дорожки (и ползунка), чтобы применить нужные стили к соответствующим элементам, нам придется ориентироваться на префиксы свойств для разных браузеров. В дальнейшем любой псевдоэлемент с префиксом -webkit будет относиться к браузерам Chrome, Safari, Opera и Edge (на основе Chromium). Все, что имеет префикс -moz относится к Firefox.

Ниже приведены псевдоэлементы, которые мы будем использовать для выбора дорожки:

  • ::-webkit-slider-runnable-track

    Относится к дорожке в браузерах Chrome, Safari и Edge Chromium.

  • ::-moz-range-track

    Относится к дорожке в Firefox.


/***** Стили дорожки *****/
/***** Chrome, Safari, Opera и Edge Chromium *****/
input[type="range"]::-webkit-slider-runnable-track {
  background: #053a5f;
  height: 0.5rem;
}

/******** Firefox ********/
input[type="range"]::-moz-range-track {
  background: #053a5f;
  height: 0.5rem;
}

Единственными необходимыми свойствами для дорожки являются height и background. Тем не менее, часто также используют border-radius, чтобы закруглить края.

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

Стилизация ползунка

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

Ниже приведены псевдоэлементы, которые мы будем использовать для выбора ползунка:

  • ::-webkit-slider-thumb

    Относится к ползунку в браузерах Chrome, Safari и Edge Chromium.

  • ::-moz-range-thumb

    Относится к ползунку в Firefox.

Поскольку у браузеров Firefox и Webkit разные проблемы со стилизацией, мы рассмотрим каждую проблему отдельно и покажем, как работать с каждым из причудливых значений по умолчанию.

CHROME, SAFARI, EDGE CHROMIUM (WEBKIT)

Первый стиль, который нам нужно применить к псевдоэлементу ::-webkit-slider-thumb, - это префиксное свойство -webkit-appearance: none;. Мы уже использовали его в разделе "Сброс стилей элемента (Базовые стили)", чтобы переопределить общие стили по умолчанию, применяемые браузером, и здесь оно служит аналогичной цели, но для ползунка.

Как только стили по умолчанию будут удалены, мы сможем применить наши собственные стили. Предположим, что мы задали для ползунка свойства height, width и background-color, тогда мы увидим такую картину:

Слайдер в Chrome с пользовательскими стилями ползунка
Слайдер в Chrome с пользовательскими стилями ползунка

По умолчанию браузеры WebKit отображают ползунок не центрируя его на дорожке.

Чтобы правильно центрировать ползунок на дорожке, можно использовать следующую формулу и результат поставить в свойство margin-top:

margin-top = (высота дорожки в px / 2) – (высота ползунка в px /2)

Взяв стили, которые мы применили в предыдущих разделах, и преобразовав rem в пиксели, мы получим высоту дорожки 8 пикселей и высоту ползунка 32 пикселя. Это значит, что:

margin-top = (8/2) - (32/2) = 4 - 16 = -12px

Исходя из этого, наши доработанные стили для браузеров webkit будут выглядеть следующим образом:


/***** Стили ползунка *****/
/***** Chrome, Safari, Opera и Edge Chromium *****/
input[type="range"]::-webkit-slider-thumb {
   -webkit-appearance: none; /* Сбрасываем вид по умолчанию */
   appearance: none;
   margin-top: -12px; /* Центрируем ползунок на дорожке */
   background-color: #5cd5eb;
   height: 2rem;
   width: 1rem;    
}

Слайдер в Chrome со всеми пользовательскими стилями
Слайдер в Chrome со всеми пользовательскими стилями

FIREFOX

В Firefox для определения стилей ползунка нужно использовать псевдоэлемент ::-moz-range-thumb. К счастью, Firefox не страдает от проблемы с центрированием, как браузеры Webkit. Тем не менее, по умолчанию здесь отображается серая рамка вокруг ползунка и скругляются края.

Слайдер в Firefox с серой рамкой и скругленными краями по умолчанию
Слайдер в Firefox с серой рамкой и скругленными краями по умолчанию

Чтобы убрать серую рамку у ползунка, можно использовать свойство border: none;. Чтобы удалить скругленные края, используем свойство border-radius: 0. Теперь ползунок будет выглядеть одинаково во всех браузерах.

Исходя из сказанного, наши окончательные стили для браузера Firefox будут выглядеть следующим образом:


/***** Стили ползунка *****/
/***** Firefox *****/
input[type="range"]::-moz-range-thumb {
    border: none; /* Удаляем лишнюю рамку, которую добавляет FF */
    border-radius: 0; /* Удаляем скругление углов по умолчанию */
    background-color: #5cd5eb;
    height: 2rem;
    width: 1rem;
}

Примечание: Браузеры Webkit автоматически не добавляют скругление углов ползунка, поэтому, если вы хотите, чтобы в ваших стилях слайдера такое скругление присутствовало, то вместо удаления, как это сделали мы, вам нужно будет задать нужное значение border-radius как в псевдоэлементе ::-webkit-slider-thumb, так и в псевдоэлементе ::-moz-range-thumb.

Стили фокусировки

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

Согласно рекомендациям WAI-ARIA по слайдеру, фокусировку следует применять к ползунку.

Первое, что нам нужно сделать, это удалить стили фокусировки по умолчанию, чтобы можно было переопределить их с помощью пользовательских стилей. Чтобы настроить стили фокусировки ползунка, мы можем использовать псевдоэлементы ::-webkit-slider-thumb и ::-moz-range-thumb, которые мы использовали в предыдущем разделе, и объединить их с псевдоклассом :focus. Затем мы можем использовать CSS свойства outline и outline-offset, чтобы оформить все так, как мы хотим.


/***** Стили фокусировки *****/
/* Удаляем фокус по умолчанию */
input[type="range"]:focus {
  outline: none;
}

/***** Chrome, Safari, Opera и Edge Chromium *****/
input[type="range"]:focus::-webkit-slider-thumb {
  border: 1px solid #053a5f;
  outline: 3px solid #053a5f;
  outline-offset: 0.125rem;
}

/******** Firefox ********/
input[type="range"]:focus::-moz-range-thumb {
  border: 1px solid #053a5f;
  outline: 3px solid #053a5f;
  outline-offset: 0.125rem;     
}

Примечание: Если у ползунка задано свойство border-radius, то Firefox отображает внешний контур в форме ползунка, в то время как другие браузеры отображают блочный внешний контур. К сожалению, так просто исправить это не получится, и это единственное различие, которое будет присутствовать в разных браузерах. Однако, основная цель добавления этих стилей - обеспечение доступности и предоставление визуального индикатора, когда элемент находится в фокусе, - все же достигнута.

Слайдер в Chrome с пользовательскими стилями
Слайдер в Chrome с пользовательскими стилями

Сведем все вместе

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


/********** Стили диапазонного элемента ввода (слайдера) **********/
/* Сбрасываем стили по умолчанию */
input[type="range"] {
   -webkit-appearance: none;
    appearance: none;
    background: transparent;
    cursor: pointer;
    width: 15rem;
}

/* Удаляем фокусировку по умолчанию */
input[type="range"]:focus {
  outline: none;
}

/***** Стили для Chrome, Safari, Opera и Edge Chromium *****/
/* дорожка слайдера */
input[type="range"]::-webkit-slider-runnable-track {
   background-color: #053a5f;
   border-radius: 0.5rem;
   height: 0.5rem;  
}

/* ползунок слайдера */
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; /* Переопределяем вид по умолчанию */
   appearance: none;
   margin-top: -12px; /* Установим ползунок по центру дорожки */

   /* пользовательские стили */
   background-color: #5cd5eb;
   height: 2rem;
   width: 1rem;
}

input[type="range"]:focus::-webkit-slider-thumb {   
  border: 1px solid #053a5f;
  outline: 3px solid #053a5f;
  outline-offset: 0.125rem; 
}

/******** Стили для Firefox ********/
/* дорожка слайдера */
input[type="range"]::-moz-range-track {
   background-color: #053a5f;
   border-radius: 0.5rem;
   height: 0.5rem;
}

/* ползунок слайдера */
input[type="range"]::-moz-range-thumb {
   border: none; /* Удаляем лишнюю рамку, которую добавляет FF */
   border-radius: 0; /* Удаляем border-radius по умолчанию от FF */

   /* пользовательские стили */
   background-color: #5cd5eb;
   height: 2rem;
   width: 1rem;
}

input[type="range"]:focus::-moz-range-thumb {
  border: 1px solid #053a5f;
  outline: 3px solid #053a5f;
  outline-offset: 0.125rem; 
}

Заключение

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

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