Назначение стилей, работающих в разных браузерах, для диапазона ввода через CSS

В этой статье мы поделимся с вами информацией об инструменте под названием range.css, который предназначен для определения стилей <input type="range">. Это одна из тех сложных вещей, для которых требуется совмещение обычных стандартизированных селекторов и свойств и нестандартных и префиксных селекторов и свойств.

Назначение стилей для ввода данных через диапазон значительно улучшилось с момента выпуска IE10. Теперь можно генерировать диапазоны ввода, совместимые с различными браузерами (слайдеры), используя только CSS. В этой статье мы возьмем базовый ввод данных через диапазон:

Скриншот диапазона ввода, Mac Chrome 38

и превратим его в это:

Диапазон ввода с пользовательскими стилями

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

Применение основных стилей CSS

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

input[type=range] {
  -webkit-appearance: none; /* Скрываем слайдер, чтобы иметь возможность создать пользовательский слайдер. */
  width: 100%; /* Для Firefox нужна отдельная ширина. */
}

input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
}

input[type=range]:focus {
  outline: none; /* Удаляем синюю рамку. Для доступности на различных платформах вам нужно применить кое-какой трюк со стилями. */
}

input[type=range]::-ms-track {
  width: 100%;
  cursor: pointer;
  background: transparent; /* Скрываем слайдер, чтобы иметь возможность добавить собственные стили */
  border-color: transparent;
  color: transparent;
}

Это дает нам невидимый диапазон ввода или диапазон без стилей для всех браузеров. Теперь мы можем применить наши собственные стили.

Стили Thumb

Виджет, в котором вы можете щелчком или перетягиванием ползунка задать диапазон, называется thumb. Для него можно задать стили, как для обычного HTML-элемента:

/* Специальные стили для WebKit/Blink */
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
  margin-top: -14px; /* Вы должны определить отступ в Chrome, но в Firefox и IE это делается автоматически */
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; /* Add cool effects to your sliders! */
}

/* Все то же самое для Firefox */
input[type=range]::-moz-range-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
}

/* Все то же самое для IE */
input[type=range]::-ms-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
}

Обратите внимание, что мы повторяем код, так как это необходимо, потому что мы не можем отделить эти типы селекторов запятыми. Браузеры сбрасывает весь селектор, если не понимает какую-то его часть.

В результате мы получаем следующее:

Стили Thumb

Стили с невидимой шкалой диапазона для ввода (WebKit / Blink) или без стилей (Firefox и IE)

Стили шкалы

Полоса, вдоль которой перемещается thumb, называется трек (шкала). Для него также задаются стили, как для обычного HTML-элемента.

Замечание по IE: Internet Explorer версии 10 и выше использует несколько иной подход к диапазону ввода. В IE вы можете указывать совершенно разные стили для верхней (справа от thumb) и нижней (слева от thumb) областей трека.

Еще одна вещь, которую вам следует иметь в виду, это то, что вы можете применить к треку эффекты фокуса, которые изменяют его стиль, когда пользователь взаимодействует с диапазоном:

input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #3071a9;
  border-radius: 1.3px;
  border: 0.2px solid #010101;
}

input[type=range]:focus::-webkit-slider-runnable-track {
  background: #367ebd;
}

input[type=range]::-moz-range-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #3071a9;
  border-radius: 1.3px;
  border: 0.2px solid #010101;
}

input[type=range]::-ms-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  background: transparent;
  border-color: transparent;
  border-width: 16px 0;
  color: transparent;
}
input[type=range]::-ms-fill-lower {
  background: #2a6495;
  border: 0.2px solid #010101;
  border-radius: 2.6px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]:focus::-ms-fill-lower {
  background: #3071a9;
}
input[type=range]::-ms-fill-upper {
  background: #3071a9;
  border: 0.2px solid #010101;
  border-radius: 2.6px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]:focus::-ms-fill-upper {
  background: #367ebd;
}

Данный код дает нам следующее:

Стили шкалы
Трек без thumb (Chrome) или thumb без стилей (Firefox and IE)

Создание полного диапазона ввода

Теперь, когда мы создали thumb и трек, мы можем объединить эти CSS-коды и создать полный диапазон ввода.

Полный CSS-код для стиля диапазона ввода для всех браузеров

Полный CSS-код для стиля диапазона ввода для всех браузеров:

input[type=range] {
  -webkit-appearance: none;
  margin: 18px 0;
  width: 100%;
}
input[type=range]:focus {
  outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #3071a9;
  border-radius: 1.3px;
  border: 0.2px solid #010101;
}
input[type=range]::-webkit-slider-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -14px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
  background: #367ebd;
}
input[type=range]::-moz-range-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #3071a9;
  border-radius: 1.3px;
  border: 0.2px solid #010101;
}
input[type=range]::-moz-range-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
}
input[type=range]::-ms-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  animate: 0.2s;
  background: transparent;
  border-color: transparent;
  border-width: 16px 0;
  color: transparent;
}
input[type=range]::-ms-fill-lower {
  background: #2a6495;
  border: 0.2px solid #010101;
  border-radius: 2.6px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
  background: #3071a9;
  border: 0.2px solid #010101;
  border-radius: 2.6px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower {
  background: #3071a9;
}
input[type=range]:focus::-ms-fill-upper {
  background: #367ebd;
}

Завершенный диапазон ввода

Эти стили дают нам следующий диапазон ввода:

Завершенный диапазон ввода

Диапазон ввода с пользовательскими стилями

Бонус: Полный LESS стилей диапазона ввода для всех браузеров

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

Используя препроцессор, все можно сделать гораздо эффективнее. Для генерации приведенного выше CSS-кода используется включение LESS-файла:

@track-color: #424242;
@thumb-color: #555bc8;

@thumb-radius: 8px;
@thumb-height: 30px;
@thumb-width: 30px;
@thumb-shadow-size: 1px;
@thumb-shadow-blur: 1px;
@thumb-shadow-color: #111;
@thumb-border-width: 1px;
@thumb-border-color: white;

@track-width: 100%;
@track-height: 10px;
@track-shadow-size: 2px;
@track-shadow-blur: 2px;
@track-shadow-color: #222;
@track-border-width: 1px;
@track-border-color: black;

@track-radius: 5px;
@contrast: 5%;

.shadow(@shadow-size,@shadow-blur,@shadow-color) {
  box-shadow: @shadow-size @shadow-size @shadow-blur @shadow-color, 0px 0px @shadow-size lighten(@shadow-color,5%);
}

.track() {
  width: @track-width;
  height: @track-height;
  cursor: pointer;
  animate: 0.2s;
}

.thumb() {
  .shadow(@thumb-shadow-size,@thumb-shadow-blur,@thumb-shadow-color);
  border: @thumb-border-width solid @thumb-border-color;
  height: @thumb-height;
  width: @thumb-width;
  border-radius: @thumb-radius;
  background: @thumb-color;
  cursor: pointer;
}

input[type=range] {
  -webkit-appearance: none;
  margin: @thumb-height/2 0;
  width: @track-width;

  &:focus {
    outline: none;
  }

  &::-webkit-slider-runnable-track {
    .track();
    .shadow(@track-shadow-size,@track-shadow-blur,@track-shadow-color);
    background: @track-color;
    border-radius: @track-radius;
    border: @track-border-width solid @track-border-color;
  }

  &::-webkit-slider-thumb {
    .thumb();
    -webkit-appearance: none;
    margin-top: ((-@track-border-width * 2 + @track-height) / 2) - (@thumb-height / 2);
  }

  &:focus::-webkit-slider-runnable-track {
    background: lighten(@track-color, @contrast);
  }

  &::-moz-range-track {
    .track();
    .shadow(@track-shadow-size,@track-shadow-blur,@track-shadow-color);
    background: @track-color;
    border-radius: @track-radius;
     border: @track-border-width solid @track-border-color;
  }
  &::-moz-range-thumb {
     .thumb();
  }

  &::-ms-track {
    .track(); 
    background: transparent;
    border-color: transparent;
    border-width: @thumb-width 0;
    color: transparent;
  }

  &::-ms-fill-lower {
    background: darken(@track-color, @contrast);
    border: @track-border-width solid @track-border-color;
    border-radius: @track-radius*2;
    .shadow(@track-shadow-size,@track-shadow-blur,@track-shadow-color);
  }
  &::-ms-fill-upper {
    background: @track-color;
    border: @track-border-width solid @track-border-color;
    border-radius: @track-radius*2;
    .shadow(@track-shadow-size,@track-shadow-blur,@track-shadow-color);
  }
  &::-ms-thumb {
    .thumb();
  }
  &:focus::-ms-fill-lower {
    background: @track-color;
  }
  &:focus::-ms-fill-upper {
    background: lighten(@track-color, @contrast);
  }
}

Поддержка браузерами

Сам по себе диапазон ввода поддерживается следующими браузерами: Firefox 23+, Safari 4+, IOS 5 +, Chrome 6+, Opera 11+, IE 10+, Android 4.2 +. Неплохо. Данные пользовательские стили диапазона ввода будут нормально работать на этих платформах, если вы будете следовать коду, приведенному в этой статье.

Вот скриншот из демо-версии демонстрирующий работу в большом количестве текущих версий популярных браузеров:

Поддержка браузерами

HTML:

<input type="range">

CSS:

input[type=range] {
  -webkit-appearance: none;
  margin: 10px 0;
  width: 100%;
}
input[type=range]:focus {
  outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 12.8px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  background: #ac51b5;
  border-radius: 25px;
  border: 0px solid #000101;
}
input[type=range]::-webkit-slider-thumb {
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  border: 0px solid #000000;
  height: 20px;
  width: 39px;
  border-radius: 7px;
  background: #65001c;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -3.6px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
  background: #ac51b5;
}
input[type=range]::-moz-range-track {
  width: 100%;
  height: 12.8px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  background: #ac51b5;
  border-radius: 25px;
  border: 0px solid #000101;
}
input[type=range]::-moz-range-thumb {
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  border: 0px solid #000000;
  height: 20px;
  width: 39px;
  border-radius: 7px;
  background: #65001c;
  cursor: pointer;
}
input[type=range]::-ms-track {
  width: 100%;
  height: 12.8px;
  cursor: pointer;
  animate: 0.2s;
  background: transparent;
  border-color: transparent;
  border-width: 39px 0;
  color: transparent;
}
input[type=range]::-ms-fill-lower {
  background: #ac51b5;
  border: 0px solid #000101;
  border-radius: 50px;
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
  background: #ac51b5;
  border: 0px solid #000101;
  border-radius: 50px;
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
}
input[type=range]::-ms-thumb {
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  border: 0px solid #000000;
  height: 20px;
  width: 39px;
  border-radius: 7px;
  background: #65001c;
  cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower {
  background: #ac51b5;
}
input[type=range]:focus::-ms-fill-upper {
  background: #ac51b5;
}

body {
  padding: 30px;
}

Результат

Если браузер не поддерживает ввод через диапазон, вы просто получаете возможность ввести данные через текстовое поле, которое по-прежнему функционирует.

Полезный инструмент

Так как изменение стилей для диапазона ввода стало доступно для разных браузеров только в 2014 году, пока еще существует не так много инструментов для генерации современных стилей. range.css - это полезный инструмент для генерации CSS-стилей диапазона ввода.

РедакцияПеревод статьи «Styling Cross-Browser Compatible Range Inputs with CSS»