Воспроизводим HTML Select с помощью Bootstrap
Популярные запросы: Open Graph, плагин Reading Time, тема Quebec, плагин Telegram, набор иконок Analogue
- 144 просмотра +1
- 24 января, 2026
- Обновлено: 25 января, 2026
- admin
- Время чтения: 7 минут
Необходимость в имитации HTML-элемента возникает редко, и, как правило, если речь заходит об ограничениях. Одним из наиболее проблемных в этом плане является элемент формы select.
Преамбула
В практике веб-разработчика form <select> встречается довольно часто, и стилизуется он с вполне решаемыми трудностями. При использовании CSS-фреймворка Bootstrap все вообще просто: достаточно применить к селекту класс .form-select, и он получит оформление, единообразное с другими элементами формы. И дальнейшая кастомизация не вызовет каких-либо проблем.
Кстати, напомним стандартную разметку:
<select name="codes" id="codes"> <option value="">--Please choose country code--</option> <option value="by">Belarus</option> <option value="ru">Russia</option> </select>
Другой вопрос – присутствие в элементах <option> разметки и, например, графических изображений. Здесь стандарты начинают уходить в отказ: вам доступен только неразмеченный текст. Проблема в том, что клиенту можно попробовать объяснить, почему его задача нерешаема, но понять и принять ваше объяснение он вряд ли сможет. Поэтому приходится думать.
Проблема на примере рабочего кейса
Одним из самых распространенных кейсов, связанных с нашей сегодняшней проблемой, является использование селекта для выбора телефонного кода страны. Это аспект юзабилити, позволяющий с одной стороны облегчить вашему посетителю ввод контактной информации, а с другой – обезопасить администратора проекта от получения некорректных данных.
Очевидно, что для удобства элемент <option> должен включать в себя изображение. В нашем случае – флага страны, код которой выбирает посетитель. Какие же решения приходят на ум в первую очередь?
Проблемы начинаются при тестировании, когда мы узнаем о том, что:
- Emoji на разных платформах будут отображаться по-разному.
- Из OS Windows по причинам политкорректности (политкорректности, Карл!) изображения флагов вообще исключены.
- Некоторые браузеры (например, Mozilla Firefox) имеют собственные emoji флагов.
На практике получаем следующую картину:
В сухом остатке совершенно дикая разносортица, отчитаться за которую перед заказчиком будет сложновато.
Пробные решения
Самое очевидное – использовать SVG-спрайты. Но их создание может затянуться надолго. Еще один вариант – грузить шрифт с флагами. Если вас устроит, существует проект Twemoji или гораздо более интересный Country Flag Emoji Polyfill. Для использования загрузим библиотеку и запустим функцию подмены:
<script type="module" defer>
import { polyfillCountryFlagEmojis } from "https://cdn.skypack.dev/country-flag-emoji-polyfill";
polyfillCountryFlagEmojis();
</script>
Теперь просто подключим шрифт первым:
@sans: 'Twemoji Country Flags', 'Open Sans', sans-serif;
При обнаружении флаг-кода emoji, будет скачан только тот фрагмент шрифта, который необходим для заполнения пробелов. В общем и целом, неплохо, но если продолжать базировать подход на использовании emoji, нам придется решать и другие вопросы с их помощью. Чем дальше, тем менее интересным все это будет становиться.
Решаем проблему быстро и красиво
Даже если данные селекта в форме необходимо использовать, самым правильным будет имитация form select с помощью кастомной разметки и скрипта. Это несложная задача, с которой справится даже начинающий верстальщик. Однако если у вас установлен Bootstrap, объем работ можно сократить наполовину.
Мы будем использовать класс .dropdown, который позволит нам уже со старта получить адаптивную имитацию селекта:
<div class="dropdown">
<button class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown button
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
Теперь заменим текстуальную часть на изображения флагов и подписи к ним:
<div class="dropdown">
<button id="currentcode" class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<img src="images/flags/by.svg" alt="{PHP.cot_countries.by}" />
</button>
<ul id="codeselector" class="dropdown-menu">
<li>
<a class="dropdown-item" href="#">
<img src="images/flags/by.svg" alt="{PHP.cot_countries.by}" />
<span>{PHP.cot_countries.by}</span>
</a>
</li>
<li>
<a class="dropdown-item" href="#">
<img src="images/flags/ru.svg" alt="{PHP.cot_countries.ru}" />
<span>{PHP.cot_countries.ru}</span>
</a>
</li>
</ul>
</div>
Результат показывает, что нам понадобится лишь изменить цвет обводки элемента <button>:
button#currentcode { border-color: rgb(222, 226, 230); }
jQuery-скрипт для обработки
Поскольку физически селекта больше не существует, вместо события change() мы будем обрабатывать событие click(). Код страны будем брать из атрибута data-code:
const selectElement = $('#codeselector');
selectElement.find('a').click(function(e) {
e.preventDefault();
code = $(this).attr('data-code');
pict = $(this).find('img').clone();
$('#currentcode').html(pict);
switch (code) {
case 'by':
// Something here
break;
case 'ru':
// Something here
break;
default:
// Something here
break;
}
});
Обратите внимание на использование метода .clone() – мы дублируем картинку, но не переносим ее в новый контейнер.
Еще один важный момент: в Bootstrap-стиле элемента button используется псевдоэлемент ::after. Чтобы он не удалялся при дублировании картинки, используем вложенный элемент <span>.
Готовая разметка с добавлением встроенных бутстраповских классов будет выглядеть так:
<div class="dropdown">
<button id="currentcode" class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<span><img src="images/flags/by.svg" alt="BY" /></span>
</button>
<ul id="codeselector" class="dropdown-menu">
<li>
<a class="dropdown-item d-flex gap-2" href="#" data-code="by">
<img src="images/flags/by.svg" alt="{PHP.cot_countries.by}" />
<span>{PHP.cot_countries.by}</span>
</a>
</li>
<li>
<a class="dropdown-item d-flex gap-2" href="#" data-code="ru">
<img src="images/flags/ru.svg" alt="{PHP.cot_countries.ru}" />
<span>{PHP.cot_countries.ru}</span>
</a>
</li>
</ul>
</div>
, а готовый код – следующим образом:
const selectElement = $('#codeselector');
selectElement.find('a').click(function(e) {
e.preventDefault();
code = $(this).attr('data-code');
pict = $(this).find('img').clone();
$('#currentcode > span').html(pict);
switch (code) {
case 'by':
// Something here
break;
case 'ru':
// Something here
break;
default:
// Something here
break;
}
});
Заключение
Если вам требуется кастомизация элемента формы <select> (например, добавление в нее графики), самым простым и наименее ресурсоемким способом будет его радикальная трансформация в другую разметку. Чем дольше вы будете тащить в код emoji и шрифты для замены символов, тем более неповоротливым и негибким он будет становиться.
Радикальный способ на наш взгляд гораздо привлекательнее. Переверстывание селекта несложно выполнить вручную, а если вы используете "бортовой" Bootstrap, делать вообще практически ничего не придется.
Ранее мы определяли все "за" и "против" использования элементов label в формах.
Новый комментарий
Ошибка
Выполнено