Стилизация элемента select на чистом CSS
Поиск

Стилизация элемента select на чистом CSS

Nikel, 27.03.2019

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

Так выглядит код обычного выпадающего селекта.

И так он выглядит на практике в браузере.

Но данный элемент может принимать и совершенно другой вид, если в числе его параметров присутствует атрибут size, он указывает нам на число элементов в списке.

Теперь этот select выглядит как список. В данном варианте выбирать можно сразу несколько пунктов списка.

Т.е. перед нами стоит задача кастомизировать две эти разновидности селекта.

Хочу пояснить, все же, в чем сложность стилизации рассматриваемого html-элемента. Посмотрите на приведенные мной примеры. То, как они выглядят, во многом зависит от используемой вами операционной системы. Браузер слабо влияет на их отображение. Вот почему стилизовать селекты такая сложная задача.

Итак, с этим мы разобрались. Осталось упомянуть, что всё рассматриваемое в данной статье исключительно для десктопа (компьютера). На смартфонах select выглядит совершенно иначе, необходимости изменять его внешний вид особой нет.Вот, например, как выглядит этот элемент в операционной системе Android (представлены соответственно селекты списка множественного выбора и простой селект).

Стилизация select списка множественного выбора

Итак, первым в нашем списке будет стилизация select с параметром multiple. Это не выпадающий список, а, как его называют, список множественного выбора.

Выглядит он  довольно убого, какими был этот элемент на заре интернета, таким осталися и сейчас. Что же можно улучшить в его отображении?Если мы подумаем над этим вопросом, ответ дать не сложно :

  • во-первых отступы, потому что стандартные крайне малы,
  • во-вторых, хочется заменить стандартный синий цвет выделенного пункта.
  • Помимо этого, хотелось бы, чтобы присутствовал optgroup label — заголовок группы и более-менее одинаково отображался.

Как я уже упомянула, изменить цвет подсветки пунктов селекта с помощью стилей нельзя напрямую, но есть одна хитрость, благодаря которой изменить цвет все же можно. Для этого достаточно вспомнить   свойство filter (которое содержит в себе целую группу так называемых css-фильтров), позволяющее применять различные эффекты к элементам, это размытие, обесцвечивание, сияние, гравюра, инвертирование цветов и т.п. Подробнее про них я писала в статье про обесцвечивание картинки. Из всего этого набора нас будет интересовать hue-rotate. Данное свойство задает оттенок в зависимости от величины угла цветового круга.

Задавая для пункта селекта этот фильтр можно добиться необходимого цвета подсветки. Формально цвет его остался прежним, задаваемым стандартно, а hue-rotate уже в свою очередь изменит отображение цвета на то, которое нам нужно.

Приведу пример рабочего кода для стилизации селекта.

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

Добиваемся мы этого с помощью свойства overflow: hidden. Для блока-контейнера и селекта указываем одинаковую ширину, а все что выходит за границы, родительского элемента отсекается благодаря этому свойству. Чтобы этот фокус сработал для select должен быть указан box-sizing: content-box. Тогда ширина вычисляется по стандартам CSS и не включает в себя отступы, границы и полосу прокрутки.

В option мы как раз и указываем цвет пункта списка, применяя hue-rotate — 125deg (когда мы изменяем эту величину, изменяется цвет).

Пункты списка на Chrome  смещены вправо, чтобы в Firefox отступы были на таком же расстоянии от края применяем небольшой хак, который работает только в нем.

Посмотрите, как себя ведут списки в браузерах Firefox и Chrome. Отличаются отступы каждого пункта, а также немного шрифт. Особенность Хрома — когда селект не в фокусе, выбранный пункт подсвечен серым, а не тем цветом, что мы задали. В Opere, Яндекс.Браузере и тому подобных браузерах, построенных на базе Хромиума select будет выглядеть также как и в Google Chrome, так как движок у них одинаковый.

Chrome focus

Chrome — не в фокусе

Firefox

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

Как я уже писала в предыдущих статьях, если старые версии Explorer имели хоть какой-то ограниченный набор своих фильтров, то более новые версии IE10, IE11 отказались от него и, при этом, не поддерживают и фильтры по стандартам, как другие браузеры. Поэтому сделать для них select так же выглядящий не представляется возможным. Цвет пункта будет стандартно-синим.

Чтобы внешний вид селекта более менее соответствовал в Explorerе, нам придется добавить много дополнительного кода, который будет работать только в нем.

Поскольку условные комментарии отменены для последних версий, воспользуемся специальным хаком IE.

Он дает нам возможность задать правила, которые будут работать только в IE10, IE11. Что же это за правила? Основная проблема в Эксплорере — это трудности с заданием высоты option — пункта списка, никакие padding, height, line-height  не работают.

Вариант, которым мы воспользуемся — зададим большой размер шрифта для всего селекта — font-size:30px, а для option установим font-sizte:14px!important.Тогда пункты расширятся. Получится что-то вроде этого.

Как мы видим, в этом случае шрифт заголовка optiongroup "--Выберите вариант--" по-прежнему останется большим. Его можно скрыть и вывести этот же текст, используя псевдоэлемент before элемента-контейнера block.

Как же задавать стили для элемента optiongroup? Напрямую это сделать нельзя, так как IE понимает optiongroup в стилях только с версии 12. Можно пойти обходным путем и указать такое правило

Оно дает возможность стилизовать непосредственно дочерний элемент select. Казалось бы легче просто задать в этом правиле размер шрифта и на этом все, однако свойства поддерживаются выборочно, font не работает,  но  работает visibility:hidden. Укажем его, а в правило для option добавим visibility:visible, чтобы сами пункты были видимыми.

Далее спозиционируем псевдоэлемент before относительно родителя block, чтобы он точно занимал место заголовка optiongroup.

Internet Explorer обрезает select по-другому, поэтому чтобы добиться  ширины элемента и его отступов слева и справа как в остальных браузерах зададим для блока-контейнера ширину 440px, а для самого селекта — 420px.

Конечно в Эксплорере будут мелкие отличия, например при наведении мыши на отдельный пункт будет появляться подсветка, но в целом мы добились относительного сходства отображения в Firefox, Chrome и IE.

Полный код для IE будет выглядеть так (можно добавить его к вышеприведенным стилям или вынести в отдельный файл).

Стилизация select раскрывающегося списка

В отличие от предыдущего варианта списка возможности по кастомизации раскрывающегося select’а не так велики. Выпадающие элементы списка никак не поддаются стилизации за исключением цвета, фона и размера шрифта.

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

Ниже представлен код моего примера оформления select.

Если вы посмотрите на код, то увидите малознакомое (или незнакомое) свойство appearance и несколько аналогичных с вендорными префиксами (-webkit-appearance, -moz-appearance, -ms-appearance) которые предназначены для старых браузеров не поддерживающих пока это свойство по стандарту(moz-Mozilla Firefox, webkit -Chrome и т.д.).

Что же означает это свойство? Оно позволяет заставить элемент выглядеть как стандартный элемент пользовательского интерфейса. Например как кнопка, поле ввода и т.п. В нашем случае значение none отключает стандартный вид селекта и позволяет скрыть стандартную стрелочку в браузерах и заменить на свою, заданную свойством background.

Новую стрелочку выпадающего списка мы укажем с помощью следующих свойств:

  • background указывает путь к стрелочке, в качестве которой может быть обычная картинка формата png, и положение ее на select в процентном отношении по горизонтали и вертикали;
  • background-size задает размер этой фоновой картинки.

Псевдоэлемент ::-ms-expand в конце кода мы добавили для того, чтобы все работало в IE, без него злосчастная кнопка не хочет исчезать.

Этот псевдоэлемент нужен для того, чтобы с помощью стилей задавать внешний вид раскрывающей кнопки select’а в Edge/Explorer. Но, так как другими браузерами эта фишка не поддерживается, мы отключаем отображение стрелочки совсем, чтобы она также была заменена картинкой.

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

Firefox

Internet Explorer 11

Chrome

Все select’ы из статьи проверялись в IE11 и последних версиях Firefox и Chrome (FF 66, Chrome 68). На этом спасибо за внимание, до новых встреч.