Customize select option in css

и | CSS

Далее полигон для испытаний (в течении месяца после написания статьи перестало работать то, что раньше работало в Mozilla Firefox).

Стили, применяемые к

  

Убрать у стрелку

Псевдоэлементы ( ::before , ::after и др.) у

  

Стили, применяемые к

  
  

Стиль выбранного пункта

 option:checked 

Стиль hover-пункта, на который наведен курсор мыши

 option:hover 

Разный стиль у и

 select:invalid:not(:focus) < color: gray; >select:invalid:focus < color: transparent; >select:focus option 

Изображения в
Тег не поддерживается, так как его нельзя вставить в атрибут

 

Свойство background-image для

  
  

Вместо картинок можно использовать символы emoji или подключить файл со своим шрифтом, подменяющим символы на рисунки

 

Источник

Стилизация Select-Option (почти) без JavaScript

Стилизация некоторых стандартных элементов — довольно нетривиальная задача.

Разумеется, хороший специалист может стилизовать что угодно, однако всё упирается в сложность этого действия.

Для стилизации радиокнопок и чекбоксов потребуется совсем немного времени — идея стилизации label со скрытыми input не нова, и давно и повсеместно используется.

Для стилизации остального — есть JavaScript.

Сегодня я хочу рассказать Вам о том, как можно относительно просто стилизовать выпадающие списки, с минимальным кодом JavaScript (от 0 до 26 строк) и минимальной дополнительной разметкой HTML.

Easy selects withoud JavaScript (almost)

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

И вот, когда я уже почти закончил писать очередную жуткую конструкцию, призванную заменить несчастный Select, у меня возник вопрос:

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

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

Выпадающие списки состоят из 2 основных элементов:

Основной функционал выпадающего списка — отправка информации о выбранном(ых) пункте(ах) на сервер.

Для полноты картины, вот список атрибутов элементов (чтобы можно было оценить, сколько из них будут реализованы):

  1. Select — disabled , form , multiple , name , required , size
  2. Option — disabled , label , selected , value

Уже было написано немало слов, поэтому — ближе к коду:

 

Описание 0 пункта

Итак, чем же хорош этот код? (всё, без чего можно обойтись при объяснении, убрано специально)

Давайте отметим, какие пункты из функционала Select и Option автоматически стали возможны, за счёт использования input + label:

Чтобы реализовать пункт Select.multiple (множественный выбор) — достаточно сделать так:

 

Мы всего-навсего меняем тип input’ов с Radio на Checkbox, и получаем практически полный аналог multiple.

Разница в том, что для множественного выбора не нужно зажимать ctrl (ну а если кто-то хочет полностью имитировать функционал — JavaScript в помощь).

  • Select.size — какой зададите размер, такой и будет. Необходимо будет просто добавить контейнер.
  • Select.disabled — для контейнера нужно добавить pointer-events: none , чтобы отменить реакцию на любые действия пользователя (наведение, клики и т.д.), ну и можно сделать его чуть прозрачным.

Нужно также добавить автозаполнение заголовка для выпадающего меню с единственным выбором, а также возникнет проблема при сбросе формы (кнопка Reset), т.к. заголовок не сбросится. Но и это — вполне решаемо (с помощью JavaScript).

Немного реализации (выпадающее меню с единичным выбором):

И ещё немного (не выпадающее меню с множественным выбором):

Бонус: не знаю, зачем я это сделал, но… выпадающее меню с единичным выбором и работающим на CSS сбросом заголовка:

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

При стилизации выпадающих списков вида:

которым с помощью JavaScript навешивают весь необходимый функционал.

Поскольку изначально списки никак не взаимодействуют с формами, из-за этого возникают проблемы.

Мало того, что необходимо реализовать весь основной функционал:

  • переключение пунктов и их взаимодействие
  • состояния (checked, disabled)
  • привязка к форме и отправка данных на сервер
  • инициализация исходных данных (автозаполнение)
  • сброс формы (при нажатии на кнопку «reset» список нужно вернуть в состояние при инициализации)

Фактически, если в JavaScript что-то ломается, не важно, из-за чего — скрипт не догрузился, возник баг, внесли правки — при возникновении любой проблемы выпадающий список превращается в… что-то, выглядящее как выпадающий список, но не работающее.
Вообще. Никак.

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

Для сервера это будет выглядеть ещё «веселее» — пришла форма, в которой не хватает части данных. Хорошо, что такую ситуацию заранее предусмотрели при разработке… Ведь предусмотрели, правда?

Плюсы получившегося решения:

  • Весь основной функционал (смотри выше), кроме сброса заголовка ВСЕГДА будет работать. Даже если у человека вообще отключён JavaScript (хоть это и стало практически неактуально). Единственное, что может пойти не так — нельзя будет открыть список. Но и в этом случае отправится значение по умолчанию, плюс смену состояний — список открыт/закрыт — можно реализовать прямо в коде html (защита от проблем с файлом JS), или вообще открывать по наведению.
  • Данного функционала достаточно для большинства подобных списков. Да, возникнут проблемы у людей, использующих дополнительный функционал (об этом ниже). Но в случае со списком на ulli для работы и вовсе требуется библиотека, и много что может пойти не так.

Минусы (доп. функционал, который не реализован, и добавляется JavaScript’ом / библиотеками):

  • Переключение с помощью tab
  • Управление стрелками (в стандартном select можно менять выбранный пункт кнопками вверх-вниз)
  • Озвучка скринридерами (для людей, у которых проблемы со зрением текст на странице озвучивается)
  • Не работает как нативный select на мобильных (на мобильных select довольно удобно работает сам по себе. При желании можно определять устройство и подменять на стандартный select)
  • Список не умеет выпадать вверх, если снизу край вьюпорта (JS сделает это)
  • Группировка пунктов (аналог OptGroup) (сложно, и очень редко встречается)

Как видно, ничто из вышеперечисленных минусов не является критичным для подавляющего большинства списков, и при необходимости реализуется с помощью JavaScript, а потому.

Добро пожаловать в мир, где Ваши библиотеки для стилизации Select-Option-подобных списков станут чуточку меньше, а работа с этими списками без библиотек — почти комфортной!

UPD: как оказалось, в случае с чекбоксами атрибут required работает некорректно, и его также необходимо эмулировать с помощью JavaScript (на данный момент обязательными становятся все чекбоксы, отмеченные как required, и только они)

Источник

How TO — Custom Select Box

Learn how to create custom select boxes with CSS and JavaScript.

Custom Select Box

Create a Custom Select Menu

Step 1) Add HTML:

Example

Step 2) Add CSS:

Example

/* The container must be positioned relative: */
.custom-select position: relative;
font-family: Arial;
>

.custom-select select display: none; /*hide original SELECT element: */
>

.select-selected background-color: DodgerBlue;
>

/* Style the arrow inside the select element: */
.select-selected:after position: absolute;
content: «»;
top: 14px;
right: 10px;
width: 0;
height: 0;
border: 6px solid transparent;
border-color: #fff transparent transparent transparent;
>

/* Point the arrow upwards when the select box is open (active): */
.select-selected.select-arrow-active:after border-color: transparent transparent #fff transparent;
top: 7px;
>

/* style the items (options), including the selected item: */
.select-items div,.select-selected color: #ffffff;
padding: 8px 16px;
border: 1px solid transparent;
border-color: transparent transparent rgba(0, 0, 0, 0.1) transparent;
cursor: pointer;
>

/* Style items (options): */
.select-items position: absolute;
background-color: DodgerBlue;
top: 100%;
left: 0;
right: 0;
z-index: 99;
>

/* Hide the items when the select box is closed: */
.select-hide display: none;
>

.select-items div:hover, .same-as-selected background-color: rgba(0, 0, 0, 0.1);
>

Step 3) Add JavaScript:

Example

var x, i, j, l, ll, selElmnt, a, b, c;
/* Look for any elements with the class «custom-select»: */
x = document.getElementsByClassName(«custom-select»);
l = x.length;
for (i = 0; i < l; i++) selElmnt = x[i].getElementsByTagName("select")[0];
ll = selElmnt.length;
/* For each element, create a new DIV that will act as the selected item: */
a = document.createElement(«DIV»);
a.setAttribute(«class», «select-selected»);
a.innerHTML = selElmnt.options[selElmnt.selectedIndex].innerHTML;
x[i].appendChild(a);
/* For each element, create a new DIV that will contain the option list: */
b = document.createElement(«DIV»);
b.setAttribute(«class», «select-items select-hide»);
for (j = 1; j < ll; j++) /* For each option in the original select element,
create a new DIV that will act as an option item: */
c = document.createElement(«DIV»);
c.innerHTML = selElmnt.options[j].innerHTML;
c.addEventListener(«click», function(e) /* When an item is clicked, update the original select box,
and the selected item: */
var y, i, k, s, h, sl, yl;
s = this.parentNode.parentNode.getElementsByTagName(«select»)[0];
sl = s.length;
h = this.parentNode.previousSibling;
for (i = 0; i < sl; i++) if (s.options[i].innerHTML == this.innerHTML) s.selectedIndex = i;
h.innerHTML = this.innerHTML;
y = this.parentNode.getElementsByClassName(«same-as-selected»);
yl = y.length;
for (k = 0; k < yl; k++) y[k].removeAttribute("class");
>
this.setAttribute(«class», «same-as-selected»);
break;
>
>
h.click();
>);
b.appendChild(c);
>
x[i].appendChild(b);
a.addEventListener(«click», function(e) /* When the select box is clicked, close any other select boxes,
and open/close the current select box: */
e.stopPropagation();
closeAllSelect(this);
this.nextSibling.classList.toggle(«select-hide»);
this.classList.toggle(«select-arrow-active»);
>);
>

function closeAllSelect(elmnt) /* A function that will close all select boxes in the document,
except the current select box: */
var x, y, i, xl, yl, arrNo = [];
x = document.getElementsByClassName(«select-items»);
y = document.getElementsByClassName(«select-selected»);
xl = x.length;
yl = y.length;
for (i = 0; i < yl; i++) if (elmnt == y[i]) arrNo.push(i)
> else y[i].classList.remove(«select-arrow-active»);
>
>
for (i = 0; i < xl; i++) if (arrNo.indexOf(i)) x[i].classList.add("select-hide");
>
>
>

/* If the user clicks anywhere outside the select box,
then close all select boxes: */
document.addEventListener(«click», closeAllSelect);

Источник

Читайте также:  Detect Browser in JavaScript
Оцените статью