Создание кастомных выпадающих списков

Тренажер по CSS для пользователей с начальным уровнем подготовки.

Тренажер CSS

В этой серии заданий вы попрактикуетесь в стилизации стандартных элементов `<select>` и создании полностью кастомных выпадающих списков с использованием HTML и CSS. Задания охватывают скрытие стандартных элементов управления браузера, добавление собственных индикаторов (стрелок) с помощью псевдоэлементов и фоновых изображений, а также создание и стилизацию выпадающих списков с нуля для полного контроля над их внешним видом и поведением. Упражнения построены от простого к сложному, позволяя постепенно освоить различные техники кастомизации.

Список тем

Скрытие стандартной стрелки select

id: 37472_custom-dropdown-1

Начнем с основ. Часто при стилизации выпадающих списков первым шагом является скрытие стандартной стрелки, которую добавляет браузер. Ваша задача — изменить стиль элемента `<select>`, чтобы убрать его стандартное оформление.

CSS
.custom-select {
  /* Убираем стандартное оформление браузера */
  input1: none;
  -webkit-appearance: none;
  -moz-appearance: none;

  /* Добавляем базовые стили для наглядности */
  display: block;
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #ccc;
  background-color: #fff;
  font-size: 16px;
  line-height: 1.5;
  color: #333;
  cursor: pointer;
}
HTML
<div class="container">
  <label for="lang-select">Выберите язык:</label>
  <select class="custom-select" id="lang-select">
    <option value="ru">Русский</option>
    <option value="en">English</option>
    <option value="de">Deutsch</option>
  </select>
</div>
Для скрытия стандартного оформления элементов форм, включая стрелку у `<select>`, используется свойство `appearance` (или его аналоги с префиксами `-webkit-` и `-moz-` для лучшей кроссбраузерности). Установите для него значение `none`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку

Добавление кастомной стрелки (псевдоэлемент)

id: 37472_custom-dropdown-2

Теперь, когда стандартная стрелка скрыта, нужно добавить свою. Мы обернем `<select>` в контейнер `div` и добавим стрелку с помощью псевдоэлемента `::after` для этого контейнера. Расположите стрелку справа внутри контейнера.

CSS
.select-wrapper {
  input1: relative; /* Контейнер для позиционирования стрелки */
  width: 200px;
}

.custom-select-arrowed {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  display: block;
  width: 100%;
  padding: 8px 30px 8px 12px; /* Оставляем место справа для стрелки */
  border: 1px solid #ccc;
  background-color: #fff;
  font-size: 16px;
  line-height: 1.5;
  color: #333;
  cursor: pointer;
}

.select-wrapperinput2 {
  content: '▼';
  input3: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  color: #555;
  pointer-events: none; /* Чтобы клики проходили на select */
}
HTML
<div class="select-wrapper">
  <select class="custom-select-arrowed" id="os-select">
    <option value="win">Windows</option>
    <option value="mac">MacOS</option>
    <option value="lin">Linux</option>
  </select>
</div>
Задайте контейнеру `position: relative`. Для псевдоэлемента `::after` используйте `content` для символа стрелки (например, '▼') или создайте ее с помощью границ. Задайте `position: absolute`, расположите справа (`right`) и по центру вертикали (`top`, `transform: translateY`). Не забудьте `pointer-events: none`, чтобы клики проходили на сам select.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку

Структура для полностью кастомного списка

id: 37472_custom-dropdown-3

Стилизация `<option>` крайне ограничена. Создадим полностью кастомный выпадающий список с помощью HTML-элементов. У нас будет кнопка (или `div`, имитирующий поле выбора) и скрытый блок с опциями. Ваша задача — скрыть блок с опциями по умолчанию.

CSS
.custom-dropdown {
  position: relative;
  width: 220px;
  font-family: sans-serif;
}

.dropdown-selected {
  padding: 10px 15px;
  border: 1px solid #ccc;
  background-color: #fff;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.dropdown-arrow {
  /* Можно добавить стилизованную стрелку позже */
  border: solid black;
  border-width: 0 2px 2px 0;
  display: inline-block;
  padding: 3px;
  transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
}

.dropdown-options {
  input1: none; /* Скрываем опции по умолчанию */
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border-top: none;
  max-height: 150px;
  overflow-y: auto;
  z-index: 10;
  list-style: none;
  margin: 0;
  padding: 0;
}

.dropdown-options li {
  padding: 10px 15px;
  cursor: pointer;
}

.dropdown-options li:hover {
  background-color: #f0f0f0;
}
HTML
<div class="custom-dropdown">
  <div class="dropdown-selected" tabindex="0"> 
    <span>Выберите фрукт</span>
    <span class="dropdown-arrow"></span>
  </div>
  <ul class="dropdown-options">
    <li>Яблоко</li>
    <li>Банан</li>
    <li>Апельсин</li>
    <li>Манго</li>
  </ul>
</div>
Используйте свойство `display` со значением `none`, чтобы полностью скрыть блок с опциями из потока документа и сделать его невидимым.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку

Отображение кастомного списка при фокусе

id: 37472_custom-dropdown-4

Теперь нужно сделать так, чтобы список опций появлялся, когда пользователь кликает или переходит табом на элемент выбора. Мы будем использовать псевдокласс `:focus-within` на родительском контейнере `.custom-dropdown`.

CSS
.custom-dropdown {
  position: relative;
  width: 220px;
  font-family: sans-serif;
}

.dropdown-selected {
  padding: 10px 15px;
  border: 1px solid #ccc;
  background-color: #fff;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  outline: none; /* Убираем стандартный контур фокуса, если нужно */
}

.dropdown-selected:focus {
  border-color: #888;
}

.dropdown-arrow {
  border: solid black;
  border-width: 0 2px 2px 0;
  display: inline-block;
  padding: 3px;
  transform: rotate(45deg);
}

.dropdown-options {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border-top: none;
  max-height: 150px;
  overflow-y: auto;
  z-index: 10;
  list-style: none;
  margin: 0;
  padding: 0;
}

.dropdown-options li {
  padding: 10px 15px;
  cursor: pointer;
}

.dropdown-options li:hover {
  background-color: #f0f0f0;
}

/* Показываем опции при фокусе внутри контейнера */
input1 input2 {
  input3: block;
}
HTML
<div class="custom-dropdown">
  <div class="dropdown-selected" tabindex="0"> 
    <span>Выберите фрукт</span>
    <span class="dropdown-arrow"></span>
  </div>
  <ul class="dropdown-options">
    <li>Яблоко</li>
    <li>Банан</li>
    <li>Апельсин</li>
    <li>Манго</li>
  </ul>
</div>
Добавьте CSS-правило, которое выбирает `.custom-dropdown:focus-within`. Внутри этого правила выберите дочерний элемент `.dropdown-options` и измените его свойство `display` на `block` (или другое подходящее значение, например `flex`, если используется flexbox), чтобы показать список.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку

Плавное появление и поворот стрелки

id: 37472_custom-dropdown-5

Сделаем появление списка более плавным и добавим поворот стрелки при открытии. Используйте CSS-переходы (`transition`) для свойств `opacity` и `transform` у списка опций, а также для `transform` у стрелки.

CSS
.custom-dropdown {
  position: relative;
  width: 220px;
  font-family: sans-serif;
}

.dropdown-selected {
  padding: 10px 15px;
  border: 1px solid #ccc;
  background-color: #fff;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  outline: none;
}

.dropdown-selected:focus {
  border-color: #888;
}

.dropdown-arrow {
  border: solid black;
  border-width: 0 2px 2px 0;
  display: inline-block;
  padding: 3px;
  transform: rotate(45deg);
  input1: transform 0.3s ease; /* Плавный поворот стрелки */
}

.dropdown-options {
  /* display: none; */ /* Заменяем display на opacity/visibility */
  input2: 0; /* Начальная прозрачность */
  input3: hidden; /* Скрываем из доступности */
  transform: translateY(-10px); /* Небольшой сдвиг вверх */
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border-top: none;
  max-height: 150px;
  overflow-y: auto;
  z-index: 10;
  list-style: none;
  margin: 0;
  padding: 0;
  transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s; /* Плавное появление */
}

.dropdown-options li {
  padding: 10px 15px;
  cursor: pointer;
}

.dropdown-options li:hover {
  background-color: #f0f0f0;
}

.custom-dropdown:focus-within .dropdown-options {
  /* display: block; */ /* Заменяем display на opacity/visibility */
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* Поворачиваем стрелку при открытии */
.custom-dropdown:focus-within .dropdown-arrow {
  input4: rotate(-135deg);
}
HTML
<div class="custom-dropdown">
  <div class="dropdown-selected" tabindex="0"> 
    <span>Выберите фрукт</span>
    <span class="dropdown-arrow"></span>
  </div>
  <ul class="dropdown-options">
    <li>Яблоко</li>
    <li>Банан</li>
    <li>Апельсин</li>
    <li>Манго</li>
  </ul>
</div>
Для списка `.dropdown-options` задайте начальное состояние `opacity: 0;` и `visibility: hidden;` (вместо `display: none;`). При `:focus-within` меняйте `opacity` на `1` и `visibility` на `visible`. Добавьте свойство `transition` для `opacity` и `transform` (можно добавить небольшой сдвиг через `translateY`). Для стрелки `.dropdown-arrow` добавьте `transition` для `transform`. В состоянии `:focus-within` измените `transform` стрелки, чтобы она повернулась (например, `rotate(-135deg)`).
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку
НайтиКурс.Ру