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

Стилизация выпадающих списков Select без использования Select!

Стандартный выпадающий список выглядит страшно, но это пол проблемы.. Все стандартные формы выглядят страшно. Но этот не поддается стилизации! Максимум что там можно — это сделать статичную картинку/стрелку ну и фон залить, а option красивый только в телефоне.

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

Суть работы списков:

У нас есть блоки div с Заголовком, Значением, Стрелкой/Кнопкой и Скрытый блок с checkbox (Он кстати тоже кастомный, инструкция тут. Можно и обычные использовать).

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

Особенности:
  • Скролл при большом количестве пунктов
  • Закрытие при клике вне блока
  • Снятие сразу всех выбранных галочек
  • Четыре варианта вывода значений
  • Не большая анимация
  • В данном случаи адаптивный
  • Возможность выбрать несколько значений
  • Одиночный выбор и сразу закрытие
  • Проверяет нажатые checkbox при загрузке
  • Работает с фильтрами

В общем прикольная штука. В идеале на чистый js переписать скрипт, но работает и ладно.

Стилизация выпадающих списков Select без использования Select!

Обертка HTML

Стиль может быть любой, главное чтобы были все необходимые блоки.

Стили CSS

Стилизация на любителя.. в данном случаи выпадающий список выглядит так.

                                        		    
                                                        /* Выпадающий список */
.form-select{
	position: relative;
	max-height: 56px;
    padding: 16px 48px 16px 24px;
	display: flex;
    align-items: center;
    justify-content: space-between;
	background: #fff;
	border-radius: 16px;
    -ms-user-select: none;
    -moz-user-select: none;
    -khtml-user-select: none;
    -webkit-user-select: none;
    -webkit-transition: all 0.2s  ease-in-out;
    -o-transition: all 0.2s  ease-in-out;
    transition: all 0.2s  ease-in-out;
}
.form-select:hover{
	box-shadow:inset 0 0 0 1px #DEDEDE;
}
.form-select.active{
	box-shadow:inset 0 0 0 2px #2CAE70;
}
.form-select__name{
	font-weight: 500;
	font-size: 14px;
	line-height: 20px;
	color: #0F1111;
	white-space: nowrap;
}
.form-select__value{
	font-size: 14px;
	line-height: 20px;
	font-weight: 500;
	text-align: right;
	color: #A3A4A5;
	white-space: nowrap;
	overflow: hidden;
	max-width: 60%;
	position: relative;
}
.form-select__value b{
	font-weight: 500;
	color: #0F1111;
}
.form-select__value b ~ span{
	margin-left:8px;
}
.form-select__value span{
	color: #2CAE70;
}
.form-select__arrow{
    position: absolute;
    top: 0;
	left:0;
	width:100%;
	height:100%;
	cursor:pointer;
}
.form-select__arrow:after{
	content:"";
    position: absolute;
    top: 50%;
    margin-top: -10px;
    right: 12px;
	background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none'%3e%3cpath fill='%230F1111' fill-rule='evenodd' d='M9.41 3.786a.833.833 0 0 1 1.18 0l3.124 3.125a.833.833 0 1 1-1.178 1.178L10 5.554 7.464 8.089a.833.833 0 0 1-1.178-1.178L9.41 3.786ZM6.287 11.91a.833.833 0 0 1 1.178 0L10 14.447l2.536-2.536a.833.833 0 0 1 1.178 1.178l-3.125 3.125a.833.833 0 0 1-1.178 0L6.286 13.09a.833.833 0 0 1 0-1.178Z' clip-rule='evenodd'/%3e%3c/svg%3e");
	width: 20px;
    height: 20px;
    -webkit-transition: all 0.2s ease-in-out;
    -o-transition: all 0.2s ease-in-out;
    transition: all 0.2s ease-in-out;
}
.form-select__arrow:hover:after{
	background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none'%3e%3cpath fill='%232CAE70' fill-rule='evenodd' d='M9.41 3.786a.833.833 0 0 1 1.18 0l3.124 3.125a.833.833 0 1 1-1.178 1.178L10 5.554 7.464 8.089a.833.833 0 0 1-1.178-1.178L9.41 3.786ZM6.287 11.91a.833.833 0 0 1 1.178 0L10 14.447l2.536-2.536a.833.833 0 0 1 1.178 1.178l-3.125 3.125a.833.833 0 0 1-1.178 0L6.286 13.09a.833.833 0 0 1 0-1.178Z' clip-rule='evenodd'/%3e%3c/svg%3e");
}
.form-select.active .form-select__arrow:after{
	background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none'%3e%3cpath fill='%232CAE70' fill-rule='evenodd' d='M9.41 3.786a.833.833 0 0 1 1.18 0l3.124 3.125a.833.833 0 1 1-1.178 1.178L10 5.554 7.464 8.089a.833.833 0 0 1-1.178-1.178L9.41 3.786ZM6.287 11.91a.833.833 0 0 1 1.178 0L10 14.447l2.536-2.536a.833.833 0 0 1 1.178 1.178l-3.125 3.125a.833.833 0 0 1-1.178 0L6.286 13.09a.833.833 0 0 1 0-1.178Z' clip-rule='evenodd'/%3e%3c/svg%3e");
	-webkit-transform:rotate(180deg);
	    -ms-transform:rotate(180deg);
	        transform:rotate(180deg);
}
.form-select__option{
    width:100%;
    position: absolute;
	top: 64px;
	left:0;
    background: #fff;
	border-radius: 16px;
	z-index: 10;
	display:none;
	padding: 8px 4px 8px 24px;
	max-height:272px;
    overflow: auto;
	-ms-overflow-style: auto;
	scrollbar-color: rgba(117, 119, 119, 0.2) transparent;
	scrollbar-width: thin;
	scrollbar-gutter: stable;
}
.form-select__option::-webkit-scrollbar-thumb {
	background-color: rgba(117, 119, 119, 0.2);
	border-radius: 2px;
	box-shadow: inset 0 0 0 4px #fff;
}
.form-select__option::-webkit-scrollbar-track {
	background-color: transparent;
}
.form-select__option::-webkit-scrollbar-corner {
	background-color: transparent;
}
.form-select__option::-webkit-scrollbar {
	width: 12px;
	height: 12px;
}

.form-select .null-checkbox,
.form-select .form-checkbox{
    width: 100%;
    flex-direction: row-reverse;
    justify-content: space-between;
	margin:16px 0;
	cursor:pointer;
}
.form-select .null-checkbox span,
.form-select .form-checkbox span {
	font-weight: 500;
	font-size: 16px;
	line-height: 24px;
	color: #0F1111;
    padding-left: 0;
}

/* Одиночный select */
.form-select.--one .form-checkbox{
	flex-direction: row;
}                                                    
                                                

Скрипт на Jquery

Чистый JS не знаю поэтому делаю как умею.

Если не выбрано пишет слово «Не важно»

При нажатии на «Не важно» в выпадающем списке — снимает все галочки

Класс добавляется основному родителю «.form-select»

Вывод в нескольких вариантах:
  • Тип 1 — Выбранный элемент и цифра плюс сколько то (Приморский район +5) — по умолчанию
  • Тип 2 — Вывод через запятую (один, два, три) — класс --list
  • Тип 3 — Просто выводит кол-во выбранных (+6) — класс --count
  • Тип 4 — Один выбранный чекбокс — класс --one
Сворачивается при:
  1. Клики мимо поля
  2. Нажатии на «не важно»
  3. Клике на значение при одиночном выборе. тип 4
  4. При клике на стрелку
                                        		    
                                                        	// выпадающие списки в фильтре
	function select() {
		$('.form-select').each(function () {
			var current = '#' + $(this).attr('id');
			$(this).on('click', '.form-select__arrow', function () {
				if ($(current).hasClass('active')) {
					$(current + ' .form-select__option').slideUp(200);
					$(current).removeClass('active');
				} else {
					$('.form-select').removeClass('active');
					$('.form-select__option').slideUp(200);
					$(current + ' .form-select__option').slideDown(200);
					$(current).addClass('active');
				}
			});
			$(this).on('click', '.form-checkbox', function () {
				current_option_filter();
			});

			function current_option_filter() {
				var count = $(current + ' input:checked').length;
				current_value = $(current).find('.form-select__value');
				if ($(current).hasClass('--count')) {
					// тип 3 - +5 - дописать класс --count
					if (count > 0) {
						current_value.html('+' + count + '');
					} else {
						current_value.text('Не важно');
					}
				} else {
					value_val = [];
					$(current + ' input:checked').each(function () {
						value_val.push($(this).val().split("-"));
						if (value_val.length > 0) {
							var count_arr = count - 1;
							if ($(current).hasClass('--list')) {
								// тип 2 - один, два, три 
								current_value.html('' + value_val.join(", ") + '');
							} else {
								// по умолчанию
								// тип 1 - Выбранный элемент +2 - по умолчанию
								if (count_arr > 0) {
									current_value.html('' + value_val[0] + '+' + count_arr + '');
								} else {
									current_value.html('' + value_val[0] + '');
								}
							}
						}
					});
					if (value_val.length == 0) {
						current_value.text('Не важно');
					}
				}

				// Снимаем все галочки если стоят
				if (count > 0) {
					$(current + ' .null-checkbox').removeClass('disabled');
					$(current).on('click', '.null-checkbox', function () {
						$(current + ' input:checked').prop('checked', false);
						current_value.text('Не важно');
						$(current + ' .form-select__option').slideUp(200);
						$(current).removeClass('active');
						$(current + ' .null-checkbox').addClass('disabled');
					});
				} else {
					$(current + ' .null-checkbox').addClass('disabled');
				}

			};
			current_option_filter();

			// Закрываем при клике мимо
			jQuery(function ($) {
				$(document).mouseup(function (e) {
					var div = $(".form-select");
					if (!div.is(e.target) && div.has(e.target).length === 0) {
						$(div).find('.form-select__option').slideUp(200);
						$(div).removeClass('active');
					}
				});
			});

		});
	};


// Только один отмеченный чекбокс
// Добавить класс --one
	$('.--one').on('click', 'input:checkbox', function () {
		if ($(this).is(':checked')) {
			$('.--one input:checkbox').not(this).prop('checked', false);
		}
	});

// вызов функции
	select();                                                     
                                                

Рабочий пример с Codepen

Итого

Пока используем как есть. Работает в фильтрах и кроссбраузерный. Если есть предложения по улучшению, пожалуйста в комменты.

23 Март 2023 г.
html, css, jquery

Комментарии ()

Написать комментарий

*Комментарий будет опубликован после проверки модератором

Хотите так же?
Мы сделаем лучше!

Оставьте свои контакты и мы рассчитаем предварительную стоимость проекта.
Спасибо!
Ваша заявка принята.