Как оформить раскрывающийся список <select> с помощью только CSS?

Когда-то было довольно сложно оформить элемент <select> для всех браузеров.

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

Оказывается, значительная часть стилей могут создать постоянный и приемлемый блок выбора (selection box) в новых браузерах, лучшим способом сохраняясь в старых браузерах.

Есть множество элементов в блоке выбора, к которым можно применить стиль, в частности width, height, font, border, color, padding, box-shadow и background color.

Рассмотрим пример, где применен стиль:

Пример

<!DOCTYPE html>
<html>
  <head>
    <title>Заголовок документа</title>
    <style>
      .box {
      width: 120px;
      height: 30px;
      border: 1px solid #999;
      font-size: 18px;
      color: #1c87c9;
      background-color: #eee;
      border-radius: 5px;
      box-shadow: 4px 4px #ccc;
      }
    </style>
  </head>
  <body>
    <p>Обычный блок выбора:</p>
    <select>
      <option>Кофе</option>
      <option>Чай</option>
      <option>Вода</option>
      <option selected>Коктейль</option>
    </select>
    <p>Оформленный блок выбора:</p>
    <select class="box">
      <option>Кофе</option>
      <option>Чай</option>
      <option>Вода</option>
      <option selected>Коктейль</option>
    </select>
  </body>
</html>

Но стрелка выпадающего (раскрывающегося) списка не меняется. Нет никакого непосредственного способа для ее оформления, но существуют некоторые методы, которые могут быть использованы для изменения стрелки раскрывающегося списка по умолчанию. Давайте рассмотрим эти 3 метода ниже.

1) Используйте appearance: none;

Чтобы скрыть стрелку по умолчанию раскрывающегося списка <select>, установите CSS свойство appearance в значение "none", и дальше добавьте выбранную вами стрелку с помощью сокращенного свойства background.

Заметьте, что свойство appearance все еще считается экспериментальным, и вам потребуется использовать префикс -moz- (для Firefox) и -webkit- (для Chrome, Safari, Opera) для максимальной совместимости браузера.

Пример

<!DOCTYPE html>
<html>
  <head>
    <title>Заголовок документа</title>
    <style>
      select {
      width: 140px;
      height: 35px;
      padding: 5px 35px 5px 5px;
      font-size: 18px;
      border: 2px solid #ccc;
      -webkit-appearance: none;
      -moz-appearance: none;
      appearance: none;
      background: url("/uploads/media/default/0001/02/f7b4d3d2ba3fe1d8518e6e63d7740e1e73921abf.png") 96% / 15% no-repeat #eee;
      }
      select::-ms-expand { 
      display: none; /* удалите стрелку по умолчанию в IE 10 и 11 */
      }
    </style>
  </head>
  <body>
    <select>
      <option>Кофе</option>
      <option>Чай</option>
      <option>Вода</option>
      <option selected>Коктейль</option>
    </select>
  </body>
</html>

2) Используйте overflow: hidden;

Сначала вставьте элемент <select> в div контейнер с фиксированной шириной и установите overflow: hidden. Потом для элемента <select> задайте ширину на 20px больше, чем элемент <div>. Таким образом, стрелка раскрывающегося списка будет скрыта (так как для контейнера установлено overflow: hidden), и теперь уже можно будет применить фоновое изображение с правой стороны <div>.

Можно использовать этот метод, так как все браузеры эффективно поддерживают overflow: hidden.
Заметьте, что недостатком этого метода является то, что опции визуально длиннее, чем меню выбора.

Пример

<!DOCTYPE html>
<html>
  <head>
    <title>Заголовок документа</title>
    <style>
      .mystyle select {
      background: transparent;
      width: 140px;
      height: 35px;
      border: 1px solid #ccc;
      font-size: 18px;
      } 
      .mystyle {
      width: 120px;
      height: 34px;
      border: 1px solid #111;
      border-radius: 3px;
      overflow: hidden;
      background: url("/uploads/media/default/0001/02/f7b4d3d2ba3fe1d8518e6e63d7740e1e73921abf.png") 96% / 20% no-repeat #ddd;
      }
    </style>
  </head>
  <body>
    <div class="mystyle">
      <select>
        <option>Кофе</option>
        <option>Чай</option>
        <option>Вода</option>
        <option selected>Коктейль</option>
      </select>
    </div>
  </body>
</html>

3) Используйте pointer-events: none;

CSS свойство pointer-events может быть использовано для создания индивидуальных раскрывающихся списков <select>.

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

Пример

<!DOCTYPE html>
<html>
  <head>
    <title>Заголовок документа</title>
    <style>
      .mybox {
      position: relative;
      display: inline-block;
      }
      select {
      display: inline-block;
      height: 30px;
      width: 150px;
      outline: none;
      color: #74646e;
      border: 1px solid #ccc;
      border-radius: 5px;
      box-shadow: 1px 1px 2px #999;
      background: #eee;
      }
      /* Select arrow styling */
      .mybox .myarrow{
      width: 23px;
      height: 28px;
      position: absolute;
      display: inline-block;
      top: 1px;
      right: 3px;
      background: url("/uploads/media/default/0001/02/f7b4d3d2ba3fe1d8518e6e63d7740e1e73921abf.png") right / 90% no-repeat #eee;
      pointer-events: none;
      }
    </style>
  </head>
  <body>
    <div class="mybox">
      <span class="myarrow"></span>
      <select>
        <option>Кофе</option>
        <option>Чай</option>
        <option>Вода</option>
        <option selected>Коктейль</option>
      </select>
    </div>
  </body>
</html>
4) Используйте знаки препинания вместо стрелок раскрывающегося списка

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

Установите знаки с помощью свойства content и установите соответствующий font. Здесь можно установить "Consolas" и "monospace". Потом поверните знак пунктуации, используя свойство transform.

Здесь блок <select> находится внутри элемента <label>. Таким образом, мы сможем установить для него курсор, даже если свойство pointer-events установлено в "none".

Пример

<!DOCTYPE html>
<html>
  <head>
    <title>Заголовок документа</title>
    <style>
      select {
      width: 140px;
      height: 35px;
      padding: 4px;
      border-radius:4px;
      box-shadow: 2px 2px 8px #999;
      background: #eee;
      border: none;
      outline: none;
      display: inline-block;
      -webkit-appearance:none;
      -moz-appearance: none;
      appearance: none;
      cursor: pointer;
      }
      label {
      position: relative;
      }
      label:after {
      content:'<>';
      font: 11px "Consolas", monospace;
      color: #666;
      -webkit-transform: rotate(90deg);
      -moz-transform: rotate(90deg);
      -ms-transform: rotate(90deg);
      transform: rotate(90deg);
      right: 8px; 
      top:2px;
      padding: 0 0 2px;
      border-bottom: 1px solid #ddd;
      position: absolute;
      pointer-events: none;
      }
      label:before {
      content: '';
      right: 6px; 
      top:0px;
      width: 20px; 
      height: 20px;
      background: #eee;
      position: absolute;
      pointer-events: none;
      display: block;
      }
    </style>
  </head>
  <body>
    <label>
      <select>
        <option>Кофе</option>
        <option>Чай</option>
        <option>Вода</option>
        <option selected>Коктейль</option>
      </select>
    </label>
  </body>
</html>