Оформлення кроссбраузерных елементів input з типом range за допомогою CSS

24

Від автора: У цій статті ми познайомимося з інструментом range.css, призначеним для оформлення елемента . Даний тип елемента input є непростим у плані оформлення, тому що вимагає незвичного поєднання стандартних селекторів і властивостей з нестандартними селекторами, властивостями і вендорными префіксами.

Можливості для стилізації елемента значно покращилися з моменту виходу версії браузера IE10. Тепер стало можливим створювати кросбраузерні повзунки вибору діапазону (слайдери), використовуючи для цього тільки CSS. У цієї навчальної статті ми візьмемо стандартний елемент input типу range (Скріншот елемента input з типом range Mac Chrome 38):

Оформлення кроссбраузерных елементів input з типом range за допомогою CSS

І перетворимо його в такій елемент (Оформлення елемента input з типом range за допомогою власних стилів):

Оформлення кроссбраузерных елементів input з типом range за допомогою CSS

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

Застосування базових стилів CSS

Необхідно застосувати кілька правил CSS, щоб змінити відображення елемента input з типом range у всіх браузерах.

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;
}

В результаті ми отримаємо невидимі або нестилизованные елементи input type=»range» у всіх браузерах. Тепер ми можемо почати додавання власних стилів.

Оформлення повзунка

Невеликий графічний елемент, за яким ви можете клацнути і перетягнути вздовж смуги діапазону, називається повзунок. Він піддається оформлення також, як і звичайний 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; /* Додаємо класні ефекти для слайдера! */
}
/* Теж саме для 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;
}

Зверніть увагу на те, що повторення коду є в даному випадку необхідною, оскільки ми не можемо перерахувати ці селектори через кому. Браузери просто проігнорують весь селектор цілком, якщо не зрозуміють хоча б якусь його частину. Результат буде наступним: (Стилізований елемент input на невидимій смузі діапазону (WebKit/Blink) або неоформлене смуга діапазону (Firefox і IE))

Оформлення кроссбраузерных елементів input з типом range за допомогою CSS

Оформлення смуги діапазону

Лінія, вздовж якої пересувається повзунок, називається смугою діапазону. Вона також піддається оформлення, як і звичайний HTML елемент.

На замітку: браузер Internet Explorer 10+ застосовує трохи інший підхід до подання елементів input type=»range». В IE ви можете визначити абсолютно різні стилі для верхньої (права частина повзунка) і нижній (ліва частина повзунка) областей смуги діапазону.

А також варто відзначити, що ви можете змінити стилі для стану фокуса, коли користувач взаємодіє з повзунком вибору діапазону.

input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 8.4 px;
cursor: pointer;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3 px;
border: 0.2 px solid #010101;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #367ebd;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 8.4 px;
cursor: pointer;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3 px;
border: 0.2 px solid #010101;
}
input[type=range]::-ms-track {
width: 100%;
height: 8.4 px;
cursor: pointer;
background: transparent;
border-color: transparent;
border-width: 16px 0;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #2a6495;
border: 0.2 px solid #010101;
border-radius: 2.6 px;
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.2 px solid #010101;
border-radius: 2.6 px;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]:focus::-ms-fill-upper {
background: #367ebd;
}

Цей код дає нам наступний результат (смуга діапазону без повзунка (Chrome) або неоформлений повзунок (Firefox and IE)):

Оформлення кроссбраузерных елементів input з типом range за допомогою CSS

Створення повноцінного елемента input з типом range

Тепер, коли ми створили окремо повзунок і смугу діапазону, ми можемо скомпонувати CSS стилі разом, щоб отримати повноцінний елемент input з типом range.

Весь CSS код для оформлення елементів input з типом range у всіх браузерах

Далі наведено весь CSS код, необхідний для оформлення елементів input з типом range у всіх браузерах.

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.4 px;
cursor: pointer;
animate: 0.2 s;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3 px;
border: 0.2 px 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.4 px;
cursor: pointer;
animate: 0.2 s;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3 px;
border: 0.2 px 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.4 px;
cursor: pointer;
animate: 0.2 s;
background: transparent;
border-color: transparent;
border-width: 16px 0;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #2a6495;
border: 0.2 px solid #010101;
border-radius: 2.6 px;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
background: #3071a9;
border: 0.2 px solid #010101;
border-radius: 2.6 px;
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;
}

Повноцінний елемент input з типом range

Після застосування стилів у нас вийде наступний результат (Елемент input з типом range, створений повністю з допомогою власних стилів.):

Оформлення кроссбраузерных елементів input з типом range за допомогою CSS

Бонус: Весь LESS код для оформлення елементів input з типом range у всіх браузерах

Для створення однакових елементів input з типом range для кожного браузера потрібна велика кількість CSS коду. Використовуючи препроцесор, ми зможете значно підвищити ефективність вашої роботи. Поданий далі LESS код використовується для генерації CSS коду, який ми розглянули до цього.

@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.2 s;
}
.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: (([email protected] * 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);
}
}

Браузерна підтримка

Сам по собі елемент input type=»range» має наступну браузерну підтримку: Firefox 23+, Safari 4+, iOS 5+, Chrome 6+, Opera 11+, IE 10+, Android 4.2+. Це досить добре. Застосування власних стилів для оформлення цього елемента не повинне здебільшого змінити дану браузерну підтримку, якщо ви будете дотримуватися рекомендацій і кодом, написаним у цієї навчальної статті.

Ось скріншот демо-приклад, що ілюструє відображення елемента input з типом range в сучасних версіях різних браузерів:

Оформлення кроссбраузерных елементів input з типом range за допомогою CSS

Якщо браузер не підтримує елемент input type=»range», у вас буде просто відображатися елемент input type=»text», який буде валідним і буде працювати.

Корисний інструмент

Можливість для створення кроссбраузерных стилів для елемента input з типом range з’явилася тільки в 2014 році, тому на даний момент існує не так багато інструментів для генерації сучасних стилів. Інструмент range.css, який я створив, є дуже зручним для цих цілей.