IkSelect — идеальный плагин для стилизации селектов. Пишем свой select-список, используя jQuery и CSS Красивый select jquery
Стилизация selectСтилизация select на чистом CSS без использования сторонних библиотек или JavaScript кода. А также бонус: рассмотрим как стилизовать select option при помощи JavaScript и jQuery Стилизация select
Структура будет стандартной
Слон Бегемот ЖирафЧтобы в select отображаемая строка была одна используем атрибут size со значением 1.
Стилизация для нашего селекта
-webkit-appearance : none ; -moz-appearance : none ; -ms-appearance : none ; appearance : none ; background : url ("path/img.png" ) no-repeat right center ; outline : 0 ;Получаем
Слон Бегемот Жираф
В примере выше мы прописали четыре строчки ccs свойства appearance с вендорными префиксами, чтобы свойство работало одинаково во всех браузерах . Что это за свойство читайте ниже.
Вся сложность заключалась лишь в замене стандартной стрелки в прямоугольнике, вместо которой мы реализовали background. Таким образом можно вставить любую картинку. Необходимо лишь подогнать размер при помощи свойства background-size
Appearance CSSРеализовать нашу задачу помогло css3 свойство appearance
Данное свойство позволяет изменить вид элемента на: button, checkbox, radio, field, icon и многое другое. В нашем случае мы вообще скрыли элемент, используя none и добавили картинку с помощью background
Стилизация select optionДля того чтобы стилизовать select option нам потребуется JavaScript
Выбрать HTML JavaScript PHP .select { display : block ; max-width : 215px ; width : 100% ; position : relative ; } .new-select { border : 1px solid #ced4da ; padding : 10px 15px ; cursor : pointer ; position : relative ; } .new-select__list { border : 1px solid #ced4da ; cursor : pointer ; position : absolute ; top : 45px ; left : 0 ; width : 100% ; } .new-select__list.on { display : block ; } .new-select__item span { display : block ; padding : 10px 15px ; } .new-select__item span :hover { color : #12b223 ; } .new-select :after { content : "" ; display : block ; width : 25px ; height : 25px ; position : absolute ; right : 9px ; top : 9px ; background : url("path-to-image") no-repeat right center / cover ; opacity : 0.6 ; -webkit-transition : all .27s ease-in-out ; -o-transition : all .27s ease-in-out ; transition : all .27s ease-in-out ; -webkit-transform : rotate (0deg ); -ms-transform : rotate (0deg ); -o-transform : rotate (0deg ); transform : rotate (0deg ); } .new-select.on :after { -webkit-transform : rotate (180deg ); -ms-transform : rotate (180deg ); -o-transform : rotate (180deg ); transform : rotate (180deg ); }Перед JavaScript-кодом должен быть подключен jQuery
$ (" .select " ). each (function () { const _this = $ (this ), selectOption = _this . find (" option " ), selectOptionLength = selectOption . length , selectedOption = selectOption . filter (" :selected " ), duration = 450 ; // длительность анимации _this . hide (); _this . wrap (" " ); $ (" " , { class : " new-select " , text : _this . children (" option:disabled " ). text () }). insertAfter (_this ); const selectHead = _this . next (" .new-select " ); $ (" " , { class : " new-select__list " }). insertAfter (selectHead ); const selectList = selectHead . next (" .new-select__list " ); for (let i = 1 ; i < selectOptionLength ; i ++ ) { $ (" " , { class : " new-select__item " , html : $ (" " , { text : selectOption . eq (i ). text () }) }) . attr (" data-value " , selectOption . eq (i ). val ()) . appendTo (selectList ); } const selectItem = selectList . find (" .new-select__item " ); selectList . slideUp (0 ); selectHead . on (" click " , function () { if ( ! $ (this ). hasClass (" on " ) ) { $ (this ). addClass (" on " ); selectList . slideDown (duration ); selectItem . on (" click " , function () { let chooseItem = $ (this ). data (" value " ); $ (" select " ). val (chooseItem ). attr (" selected " , " selected " ); selectHead . text ( $ (this ). find (" span " ). text () ); selectList . slideUp (duration ); selectHead . removeClass (" on " ); }); } else { $ (this ). removeClass (" on " ); selectList . slideUp (duration ); } }); });В последнее время дизайнеры стали все чаще рисовать HTML формы в стилистике HTML 2.0, эта тенденция длится уже несколько лет и чем дальше тем более привычным становятся красивые поля ввода данных и select’ы с закругленными краями и тенями. Можно только порадоваться, ведь все замечательно и CSS3 уже используется где только можно, позволяя придавать красивый вид формам, полям и селектам. Увы не всегда все так радужно…
Не смотря на то, что все современные браузеры поддерживают HTML5 и CSS3, ими пользуются далеко не все, и как гласит статистика половина пользователей всего интернета по прежнему работают в браузерах старых версий, многие из которых не поддерживают в полной мере или вообще CSS3. По этому стилизовать выпадающий список (Select), часто приходится старыми добрыми средствами, а именно jQuery (js) и картинками PNG или GIF. Об одном из таких способов я хочу рассказать.
Приведенный ниже скрипт был случайно найден мною на страницах рунета, к сожалению адреса я не запомнил и имени его автора. По этому просто передаю ему большой респект.
Просмотр кода JS
(function($){ $.fn.extend({ customStyle1: function(options) { if(!$.browser.msie || ($.browser.msie&&$.browser.version>6)){ return this.each(function() { var currentSelected = $(this).find(":selected"); $(this).after(""+currentSelected.text()+"").css({position:"absolute", opacity:0,fontSize:$(this).next().css("font-size")}); var selectBoxSpan = $(this).next(); var selectBoxWidth = parseInt($(this).width()) - parseInt(selectBoxSpan.css("padding-left")) -parseInt(selectBoxSpan.css("padding-right")); var selectBoxSpanInner = selectBoxSpan.find(":first-child"); selectBoxSpan.css({display:"inline-block"}); selectBoxSpanInner.css({width:selectBoxWidth, display:"inline-block"}); var selectBoxHeight = parseInt(selectBoxSpan.height()) + parseInt(selectBoxSpan.css("padding-top")) + parseInt(selectBoxSpan.css("padding-bottom")); $(this).height(selectBoxHeight).change(function(){ selectBoxSpanInner.text($("option:selected",this).text()).parent().addClass("changed"); }); }); } } }); })(jQuery); |
Вызов скрипта для стилизации «селекста».
Просмотр кода JS
$(document).ready(function() { $(".select1").customStyle1(); }); |
HTML код «селекта» который будет стилизован
Просмотр кода HTML
Опция 1 Опция 2 Опция 3 Опция 4 Опция 5 Опция 6 |
Стиль который будет применен к селекту
Просмотр кода CSS
.select1 { width : 410px ; height : 32px ; color : #909090 ; font : 12px Arial, Tahoma, Helvetica, Verdana; text-align : left ; background : url (images/sel1.png) no-repeat ; /*изображение для оформления селекта*/ line-height : 30px ; white-space : nowrap ; /* запрещаем перенос */ padding : 0 22px 0 12px ; /* отступ справа с учетом стрелочки */ border : 0 ; zoom: 1 ; /* для IE6 */ margin : 3px 0 5px 0 ; } |
Заменив фоновое изображение вы можете стилизовать select как вам угодно и работать данный пример будет в большинстве браузеров, даже в самых старых).
Часто наталкиваюсь на крупные сайты где используется похожий принцип стилизации объектов форм, из чего можно сделать вывод, что пока еще большинство веб-мастеров склонны к применению таких не очень простых решений, ради поддержки пользователей со старыми браузерами.
Внимание! Дальнейшее развитие и поддержка плагина остановлены в связи с тем, что теперь он является частью .
Одна из самых неприятных (и я бы даже сказал ужасных) вещей в веб-разработке — это верстка html-форм. К сожалению, не существует единого стандарта отображения элементов форм, независимо от браузера и операционной системы, так же, как и нет возможности произвольно оформить некоторые из этих элементов, используя каскадные таблицы стилей.
Не поддаются полной стилизации следующие элементы html-форм:
- раскрывающийся список ;
- флажок ;
- переключатель .
- поле для отправки файла .
Как уже понятно из заголовка поста, здесь речь пойдет только про селекты.
Существует немало готовых решений в виде jQuery-плагинов для стилизации раскрывающихся списков. Но я (ввиду того, что ни один из плагинов меня не устроил по тем или иным причинам) решил пойти путем изобретения своего колеса и написал собственный плагин, которым и делюсь в данной статье.
Сразу хочу заметить, что данный плагин не подходит для всех возможных случаев применения селектов (читайте недостатки).
Демонстрация работы плагинаНа вы можете посмотреть пример стилизации селектов с помощью моего плагина. Их оформление я сделал без использования изображений.
Достоинства- При отключенном JavaScript отображаются стандартные селекты.
- Небольшой размер скрипта, примерно 4 килобайта.
- Работает в IE6+ и всех современных десктопных браузерах.
- Выводится внутристрочно.
- Легко поддается оформлению через CSS.
- Позволяет задать максимальную высоту для выпадающего списка (CSS-свойством max-height).
- Автоматически подстраивает ширину, если она не указана.
- Поддерживает прокрутку колесом мыши.
- Имеет «умное позиционирование», т.е. не уходит за видимую часть страницы при открытии списка.
- Умеет «ловить» нажатие клавиши Tab и переключаться стрелками на клавиатуре.
- Поддерживает атрибут «disabled».
- Работает и с динамически добавляемыми/изменяемыми селектами.
- Не поддерживает атрибут multiple , т.е. не позволяет выбирать несколько пунктов (мультиселект).
- Не поддерживает группировку элементов списка (тег ).
- Не поддерживает переключение стрелками на клавиатуре, когда список раскрыт кликом мыши.
Плагин недоступен, т.к. он уже не актуален.
jQuery-плагин «SelectBox Styler»Версия: 1.0.1 | Загрузок: 11103 | Размер: 7 Кб | Последнее обновление: 07.10.2012
Обновления 22.09.2012 Переделал скрипт в плагин (в том числе сделал минимизированный вариант), а также добавил поддержку динамического добавления/изменения селектов. 07.10.2012 Исправлено поведение скрипта при использовании метода onchange у тега . Подключение плагинаЕсли на сайте еще не подключен jQuery, то добавьте следующую строку перед тегом :
Сразу после jQuery подключите файл со скриптом:
(function($) { $(function() { $("select").selectbox(); }) })(jQuery)
Этот код поместите перед тегом после вышеуказанных файлов.
При динамическом изменении селектов необходимо запустить триггер refresh , например:
(function($) { $(function() { $("button").click(function() { $("select").find("option:nth-child(5)").attr("selected", true); $("select").trigger("refresh"); }) }) })(jQuery)
HTML-код после выполнения плагинаЕго структура выглядит следующим образом:
-- Выберите --
- -- Выберите --
- Пункт 1
- Пункт 2
- Пункт 3
Чтобы оформить селекты с помощью CSS, используйте следующие классы:
.selectbox | родительский контейнер для всего селекта |
.selectbox .select | селект в свернутом состоянии |
.selectbox.focused .select | фокус на селекте, когда нажата клавиша Tab |
.selectbox .select .text | вложенный тег для свернутого селекта на случай вставки фонового изображения по технике «раздвижных дверей» |
.selectbox .trigger | правая часть свернутого селекта (условный переключатель) |
.selectbox .trigger .arrow | вложенный тег для переключателя (стрелка) |
.selectbox .dropdown | обертка для выпадающего списка |
.selectbox .dropdown ul | выпадающий список |
.selectbox li | пункт (опция) селекта |
.selectbox li.selected | выбранный пункт селекта |
.selectbox li.disabled | отключенный (недоступный для выбора) пункт селекта |
Создание подобного скрипта — довольно кропотливое занятие, поскольку приходится учитывать множество различных моментов. Очень надеюсь, что никаких серьезных багов не вылезет. Но, если что, сообщайте в комментариях.
Кто серьёзно занимается вёрсткой страниц, знает, что возможности стилизации select в CSS крайне сильно ограничены. Но очень часто в дизайн стандартный select не вписывается вообще никак, поэтому приходится делать стилизацию select через JavaScript . Фактически, в этой статье мы с Вами создадим свой собственный select с помощью JavaScript .
Есть масса готовых плагинов, в том числе и на jQuery , которые позволяют всё это сделать. Но если Вам не нужно что-то сверхсложное, то проще сделать всё самому с нуля на чистом JavaScript .
Первым делом, давайте создадим HTML-структуру нашего будущего select :
Элемент 1
Элемент 2
Элемент 3
Элемент 1
Элемент 2
Элемент 3
Как видите, тега select тут и близко нет. Теперь мы можем как угодно стилизовать наш собственный select с помощью CSS :
Select {
background-color: #0ee;
border-radius: 10px;
padding: 10px 0;
width: 200px;
}
.select p {
cursor: pointer;
margin: 0;
padding: 5px 20px;
}
.select p.active {
background-color: #ee0;
}
Безусловно, Вы здесь можете сделать всё, что пожелаете. И, наконец, надо превратить внешний вид в функциональность select , то есть выбор и подстветка только одного элемента из нескольких, а также последующая отправка вместе с формой. Для этого мы воспользуемся JavaScript :
Function select(element) {
var value = element.getAttribute("data-value"); // Считываем значение выбранного элемента
var nodes = element.parentNode.childNodes; // Получаем все остальные элементы
for (var i = 0; i < nodes.length; i++) {
/* Отфильтровываем посторонние элементы text и input */
if (nodes[i] instanceof HTMLParagraphElement) {
/* Добавляем active у выбранного элемента, стирая данный класс у всех остальных */
if (value == nodes[i].getAttribute("data-value")) nodes[i].className = "active";
else nodes[i].className = "";
}
}
document.getElementById("my_select").value = value; // Устанавливаем в hidden-поле выбранное значение
}
Ключевым моментом реализации функциональности select является hidden-поле , в которое записывается значение из нашего select . И именно это значение будет отправлено при отправке формы.
Вот таким нехитрым образом делается абсолютно любая стилизация select на JavaScript . Если использовать jQuery , то код будет ещё проще.
Безусловно, стандартный select обладает большей функциональностью. Например, он реагирует на tab , также можно в нём перебирать элементы стрелками на клавиатуре. Но всё это Вы так же можете реализовать при необходимости на JavaScript .
И последняя рекомендация. В коде был использован тег noscript , и это было неслучайно. Поскольку не у всех JavaScript включён, и чтобы форма была вообще рабочей для таких пользователей, нужно вывести хотя бы стандартный select . А все, у кого JavaScript включён, увидят наш красивый select .
В данной статье мы рассмотрим создание плагина jQuery, суть которого в замещение элемента select красиво оформленным неупорядоченным списком (ul) .
Одним из важнейших способов эффективной организации jQuery кода служит превращение его частей в плагины. Такие превращения несут в себя ряд преимуществ: код становится проще модифицировать и сопровождать, руководство повторяющими задачами упрощается. Также увеличивается скорость разработки, так как организация плагина способствует повторному использованию кода.
Поэтому мы и продемонстрируем сегодня процесс конвертирования кода в плагин. Код мы возьмем из этого руководства jQuery& CSS3 замещаем элемент select и превратим его в готовый к использованию jQuery плагин.
Основная идеяНаписать jQuery плагин совсем не сложно. Для этого нужно расширить объект $.fn своей собственной функцией. Гораздо сложнее должным образом структурировать свой код, чтобы плагин можно было легко вставить и использовать (без зависимостей).
Вот, несколько проблем, которые нам надо решить при конвертировании кода руководства в jQuery плагин:
1. Пользователю нужно дать возможность решать, какая разметка будет генерироваться для dropdown (выпадающего списка). К примеру, код руководства сильно зависит от наличия data- атрибутов, которые содержат разметку HTML. Это слишком специфично, чтобы подключать в плагин, поэтому данную реализацию нужно исключить.
2. Из-за способа вызова плагина код нужно переписать, чтобы он использовал объект this , который передается плагину, вместо жестко заданного селектора. Это также позволяет конвертировать не один, а несколько элементов select одновременно;
3. Код JavaScript и CSS нужно поместить в разные файлы, чтобы их было проще подключать и редактировать.
КодКак вы помните из руководства, наш jQuery код сканирует элементы option тега select и создает неупорядоченный список. Одновременно с этим он также ищет ряд data- атрибутов в тегах option , которые содержат URL на изображение и описание для использования в элементах списка.
Это слишком специфично для плагина. Пользователям нужно дать возможность переписать эту функциональность. Для решения этой проблемы можно позволить пользователям передавать плагину функцию в качестве параметра, которая и будет генерировать разметку. Если такой параметр не передается, будем обращаться к тому, который стоит по умолчанию, и который просто берет текст элемента option и превращает его в пункт списка.
Превратим вышесказанное в код:
Функция render берет элемент option (который находится в select) и возвращает элемент li , который подключается плагином к выпадающему списку. Это решает описанную выше проблему № 1.
Прежде чем обратиться к проблеме № 2, давайте посмотрим, как плагин будет вызываться:
$(document).ready(function(){ $("select").tzSelect(); });
В приведенном выше коде вы можете видеть, что плагин применяется к каждому элементу select . Получить доступ к этим элементам можно при помощи объекта this , который передается плагину.
Return this.each(function(){ // ключевое слово "this" это текущий элемент select var select = $(this); // selectBoxContainer - блок обертка для ul var selectBoxContainer = $("
- ",{className:"dropDown"});
var selectBox = selectBoxContainer.find(".selectBox");
// Цикл по тегам option оригинального тега select
if(options.className){
dropDown.addClass(options.className);
}
select.find("option").each(function(i){
var option = $(this);
if(i==select.attr("selectedIndex")){
selectBox.html(option.text());
}
// Так как у нас jQuery 1.4.3 то получить доступ к атрибуту
// HTML5 data можно при помощи метода data())
if(option.data("skip")){
return true;
}
// создаем выпадающий список, согласно атрибутам HTML5
// data-icon и data-html-text
var li = options.render(option);
li.click(function(){
selectBox.html(option.text());
dropDown.trigger("hide");
// При клике отражаем изменения на оригинальное
// элементе select
select.val(option.val());
return false;
});
dropDown.append(li);
});
selectBoxContainer.append(dropDown.hide());
select.hide().after(selectBoxContainer);
// Связываем события show и hide
// с выпадающим меню dropDown:
dropDown.bind("show",function(){
if(dropDown.is(":animated")){
return false;
}
selectBox.addClass("expanded");
dropDown.slideDown();
}).bind("hide",function(){
if(dropDown.is(":animated")){
return false;
}
selectBox.removeClass("expanded");
dropDown.slideUp();
}).bind("toggle",function(){
if(selectBox.hasClass("expanded")){
dropDown.trigger("hide");
}
else dropDown.trigger("show");
});
selectBox.click(function(){
dropDown.trigger("toggle");
return false;
});
// Если произошел клик где-нибудь на странице при
// открытом выпадающем списке, то скрываем его:
$(document).click(function(){
dropDown.trigger("hide");
});
});
- ",{
html: option.text()
});
},
className: ""
},options);
return this.each(function(){
// ключевое слово "this" это текущий элемент select
var select = $(this);
// selectBoxContainer - блок обертка для ul
var selectBoxContainer = $("",{
width: select.outerWidth(),
className: "tzSelect",
html: ""
});
// dropDown - выпадающее меню
var dropDown = $("
- ",{className:"dropDown"});
var selectBox = selectBoxContainer.find(".selectBox");
// Цикл по тегам option оригинального тега select
if(options.className){
dropDown.addClass(options.className);
}
select.find("option").each(function(i){
var option = $(this);
if(i==select.attr("selectedIndex")){
selectBox.html(option.text());
}
// Так как у нас jQuery 1.4.3 то получить доступ к атрибуту
// HTML5 data можно при помощи метода data())
if(option.data("skip")){
return true;
}
// создаем выпадающий список, согласно атрибутам HTML5
// data-icon и data-html-text
var li = options.render(option);
li.click(function(){
selectBox.html(option.text());
dropDown.trigger("hide");
// При клике отражаем изменения на оригинальное
// элементе select
select.val(option.val());
return false;
});
dropDown.append(li);
});
selectBoxContainer.append(dropDown.hide());
select.hide().after(selectBoxContainer);
// Связываем события show и hide
// с выпадающим меню dropDown:
dropDown.bind("show",function(){
if(dropDown.is(":animated")){
return false;
}
selectBox.addClass("expanded");
dropDown.slideDown();
}).bind("hide",function(){
if(dropDown.is(":animated")){
return false;
}
selectBox.removeClass("expanded");
dropDown.slideUp();
}).bind("toggle",function(){
if(selectBox.hasClass("expanded")){
dropDown.trigger("hide");
}
else dropDown.trigger("show");
});
selectBox.click(function(){
dropDown.trigger("toggle");
return false;
});
// Если произошел клик где-нибудь на странице при
// открытом выпадающем списке, то скрываем его:
$(document).click(function(){
dropDown.trigger("hide");
});
});
}
})(jQuery);
- ",{
html: ""+
option.data("html-text")+""
});
},
className: "hasDetails"
});
// вызываем версию по умолчанию
$("select.regularSelect").tzSelect();
});
Вы можете использовать этот плагин, бросив папку tzSelect в корневую директорию и включив jquery.tzSelect.css и jquery.tzSelect.js в свои HTML документы.
Проблему № 3 решаем, поместив этот плагин в отдельный файл. Однако, как я упоминал ранее, мы сознательно не включили код, который содержит data- атрибуты, чтобы сделать плагин более мобильным. Чтобы компенсировать это, нужно при вызове плагина передавать пользовательскую функцию render , как вы можете увидеть ниже (этот код также используется в демо).
$(document).ready(function(){ $("select.makeMeFancy").tzSelect({ render: function(option){ return $("
- ",{
html: ""+
option.data("html-text")+""
});
},
className: "hasDetails"
});
// вызываем версию по умолчанию
$("select.regularSelect").tzSelect();
});
Показанный выше фрагмент почти идентичен коду руководства, который мы сегодня конвертируем. Единственное заметное отличие – мы присваиваем $(this) переменной select (строка5), раньше же это был $("select.makeMeFancy") (жёстко запрограммированный селектор), что значительно сужало область действия кода.
Другое изменение – вместо непосредственного генерирования выпадающего списка (dropdown), мы вызываем функцию render, которую мы передали как параметр (строка51).
Собрав все воедино, мы получим полный исходный код плагина:
(function($){ $.fn.tzSelect = function(options){ options = $.extend({ render: function(option){ return $("