CSS оформление select

15-01-2011

Есть наверное куча плагинов предоставляющие возможность изменения обычных select на необычные, или такие которые хотя бы отображались бы во всех браузерах одинаково. Но нам же это не интересно :) , сейчас попробуем сделать из обычного селекта необычный т.е. будет выглядеть примерно так:

select css

В демке представлено 4 селекта смотрим.



Вконтакте извините я спер у вас оформление и цвета селекта :) .

Возьмем обычный select с несколькими option примерно вот:

<select id="ourselect1">
           <option value="eee">Значение 19</option>
           <option value="222">Значение 18</option>
           <option value="444">Значение 17</option>
           <option value="123">Значение 16</option>
           <option value="122">Значение 15</option>
           <option value="113">Значение 14</option>
           <option value="124">Значение 13</option>
</select>

Обернем его в div с классом “sel_wrap”, в начале которого выстроим структуру нашего селекта дивами. Если представить это все дело на картинке то получится следующая картина:

select-structure

А код получится следующим:

<div class="sel_wrap">
    <div class="sel_imul">
        <div class="sel_selected">
            <div class="selected-text">Значение 19</div><div class="sel_arraw"></div>
        </div>
        <div class="sel_options">
            <div class="sel_option" value="eee">Значение 19</div>
            <div class="sel_option" value="222">Значение 18</div>
            <div class="sel_option" value="444">Значение 17</div>
            <div class="sel_option" value="123">Значение 16</div>
            <div class="sel_option" value="122">Значение 15</div>
            <div class="sel_option" value="113">Значение 14</div>
            <div class="sel_option" value="124">Значение 13</div>
        </div>
    </div>
    <select id="ourselect1">
        <option value="eee">Значение 19</option>
        <option value="222">Значение 18</option>
        <option value="444">Значение 17</option>
        <option value="123">Значение 16</option>
        <option value="122">Значение 15</option>
        <option value="113">Значение 14</option>
        <option value="124">Значение 13</option>
    </select>
</div>

Далее приступим к стилям. Естественно скрываем наш обычный селект, а структуру эмилирующую селект стилизуем как нам хочется:

.sel_wrap{
    background:#efefef;
    margin-bottom:5px;
    padding:7px;
}
.sel_wrap select{
    display:none;
}
.sel_imul{
    width:300px;
}
.sel_imul .sel_selected{
    background:#fff;
    border:1px solid #bbb;
    padding:3px 6px;
    font-size:14px;
    font-family:Times;
    cursor:pointer;
    position:relative;
}
.sel_imul.act .sel_selected{
    background:#efefef;
}
.sel_selected .sel_arraw{
    height:100%;
    width:20px;
    background:url('http://bit.ly/gudLNa') 50% 50% no-repeat;
    position:absolute;
    top:0px;
    right:0px;
}
.sel_imul:hover .sel_selected .sel_arraw{
    background-color:#e0e0e0;
    border-left:1px solid #bbb;
}
.sel_imul.act .sel_selected .sel_arraw{
    background-color:#e0e0e0;
    border-left:1px solid #bbb;
}
.sel_imul .sel_options{
    background:#fff;
    border:1px solid #dbdbdb;
    border-top:none;
    overflow:auto;
    position:absolute;
    width:298px;
    display:none;
    z-index:10;
}
.sel_options .sel_option{
    padding:3px 4px;
    font-size:14px;
    font-family:Times;
    border:1px solid #fff;
    border-right:none;
    border-left:none;
}
.sel_options .sel_option:hover{
    border-color:#dbdbdb;
    cursor:pointer;
}
.sel_options .sel_option.sel_ed{
    background:#dbdbdb;
    border-color:#dbdbdb;
}

/*second variant*/
.sec .sel_imul{
    width:200px;
}
.sec .sel_imul .sel_selected{
    border:1px solid #C0CAD5;
}
.sel_imul.act .sel_selected{
    background:#fff;
}
.sec .sel_imul:hover .sel_selected .sel_arraw{
    background-color:#e1e8ed;
    border-left:1px solid #d2dbe0;
}
.sec .sel_imul.act .sel_selected .sel_arraw{
    background-color:#e1e8ed;
    border-left:1px solid #d2dbe0;
}
.sec .sel_imul .sel_options{
    background:#fff;
    border:1px solid #d2dbe0;
    width:198px;
}
.sec.overf .sel_imul .sel_options{
    height:100px;
}
.sec .sel_options .sel_option:hover, .sec .sel_options .sel_option.sel_ed{
    background:#587da1;
    border:1px solid #2a5883;
    color:#fff;
    cursor:pointer;
}
.sec .sel_imul .sel_selected .sel_arraw{
    background-image:url('http://vkontakte.ru/images/darr_dd_out.gif');
}

.sec.round .sel_imul .sel_selected{
    -webkit-border-radius:5px;
}
.sec.round .sel_imul .sel_selected .sel_arraw{
    -webkit-border-radius:0 5px 5px 0;
}
.sec.round .sel_imul .sel_options{
    -webkit-border-radius:0 0 5px 5px;
}
/*green*/
.sec.green .sel_imul .sel_selected{
    border-color:#FFAD99;
}
.sec.green .sel_imul:hover .sel_selected .sel_arraw,
.sec.green .sel_imul.act .sel_selected .sel_arraw{
    background-color:#FFD6CC;
    border-left:1px solid #FFAD99;
}
.sec.green .sel_options .sel_option:hover,
.sec.green .sel_options .sel_option.sel_ed{
    background:#FF9980;
    border:1px solid #FF704D;
    color:#fff;
    cursor:pointer;
}

Здесь уже стили предусматривающие работу javascript’а, и несколько типов селектов.

Дальше приступим к javascript‘у. Во первых сделаем так чтобы при клике на див эмулирующий select, открывался или закрывался список option’ов:

$('.sel_imul').live('click', function() {

    $('.sel_imul').removeClass('act');
    $(this).addClass('act');

    if ($(this).children('.sel_options').is(':visible')) {

        $('.sel_options').hide();

    }
    else {

        $('.sel_options').hide();
        $(this).children('.sel_options').show();

    }

});

Теперь пишем событие которое будт менять значение обычного, скрытого, селекта и значение у эмулирующего селекта:

$('.sel_option').live('click', function() {

    //меняем значение на выбранное
    var tektext = $(this).html();
    $(this).parent('.sel_options').parent('.sel_imul').children('.sel_selected').children('.selected-text').html(tektext);

    //активируем текущий
    $(this).parent('.sel_options').children('.sel_option').removeClass('sel_ed');
    $(this).addClass('sel_ed');

    //устанавливаем значение для селекта
    var tekval = $(this).attr('value');
    tekval = typeof(tekval) != 'undefined' ? tekval : tektext;
    $(this).parent('.sel_options').parent('.sel_imul').parent('.sel_wrap').children('select').children('option').removeAttr('selected').each(function() {
        if ($(this).val() == tekval) {
            $(this).attr('selected', 'select');
        }
    });
});

Ну еще напишем меленький код который будет закрывать селект при холостом клике, blur так зказать:

var selenter = false;
$('.sel_imul').live('mouseenter', function() {
    selenter = true;
});
$('.sel_imul').live('mouseleave', function() {
    selenter = false;
});
$(document).click(function() {
    if (!selenter) {
        $('.sel_options').hide();
        $('.sel_imul').removeClass('act');
    }
});

Напишем функцию которая будет превращать из обычного селекта такой т.е. писать за нас код, назовем его reselect():

function reselect(select, addclass) {

    addclass = typeof(addclass) != 'undefined' ? addclass : '';

    $(select).wrap('<div class="sel_wrap ' + addclass + '"/>');

    var sel_options = '';
    $(select).children('option').each(function() {
        sel_options = sel_options + '<div class="sel_option" value="' + $(this).val() + '">' + $(this).html() + '</div>';

    });

    var sel_imul = '<div class="sel_imul">\
                <div class="sel_selected">\
                    <div class="selected-text">' + $(select).children('option').first().html() + '</div>\
                    <div class="sel_arraw"></div>\
                </div>\
                <div class="sel_options">' + sel_options + '</div>\
            </div>';

    $(select).before(sel_imul);

}

Здесь что то нормально не удается показать функцию, можете посмотреть ее в демке

Andrey1.17.2011 09:01
Спасибо! Действительно интересная вещь. Расставил все по полкам.
Антон1.24.2011 01:01
$(select).wrap(''); - в это йтроке у меня выдает ошибку. Пишет: "Предпологается наличие объекта"
    admin1.24.2011 01:01
    функцию вот так вызывать надо... reselect('#ourselect2', 'sec'); как в демке, смотрел? ourselect2 - ид селекта sec - дополнительный класс который будет добавлен после создания
      Антон1.24.2011 02:01
      Я сначала не понял, что нужно еще библиотеку jQuery подключать. Теперь все работает. Только вот события привязаннае к select ( ) не работают. Это можно как-то решить?
    admin1.24.2011 02:01
    да скорей всего, можешь код скинуть? или ссылку чтоб посмотреть ото так не понятно...
Антон1.24.2011 02:01
Я пока только тестирую. Вот составил примитивный пример: ... function no01() { alert('11') } .... Значение 19 Значение 18 Значение 17 Значение 16 Значение 15 Значение 14 Значение 13 Но т.к. элемент селект скрыт и вместо место него вставлен код с div-ами, события onclick на элементе select не происходит
    admin1.24.2011 02:01
    там уже есть метод обрабатывающий это допиши тут в конец то что тебе нжно
    $('.sel_option').live('click', function() {
    
    //какой то код
    
    
    //здесь пиши ))
    });
Антон1.24.2011 02:01
Отлично. Работает. Буду разбираться. Большое спасибо автору.
Антон1.26.2011 08:01
У меня в форме теги "" заключены внутрь тегов "". Чтобы добраться до них я поступаю так: " $(select).children('optgroup').children('option').each(function() {} " и это прекрасно работает в IE но не работает в FireFox. Как правильно обратиться к optgroup?
    Антон1.26.2011 08:01
    теги OPTION заключены внутрь тегов OPTGROUP
    admin1.26.2011 08:01
    а что ты с ними хочешь сделать?... просто я не предусмотрел группировку оптионов в селекте можт придется дописывать
Константин2.14.2011 01:02
А мне нужно много селектов на одну страницу. Как реализовать? А то выбранные значения сбрасываются, в первом же селекте все оптионы других селектов.
    admin2.14.2011 03:02
    нужно селекам просто разные идентификаторы прописать, ну и соответственно вызывать функцию reselect() столько раз сколько нужно селектов на страницу..:
    reselect('#ourselect1');
    reselect('#ourselect2', 'sec');
    reselect('#ourselect3', 'sec overf');
    
    второй параметр, как я уже говорил не обязательный, он задает дополнительный класс
Константин2.14.2011 01:02
Ну а так очень нравится способ стилизации :)
noo3.3.2011 07:03
а как сделать что бы при выборе значения селекта над формой выводилось его описание (пояснение выбранного), для каждого значения свое
    admin3.3.2011 06:03
    нужно дописать метод выбора значения... делаешь все что хочешь с значением селекта
Максим9.7.2011 07:09
Привет, у меня почему-то передает все время только первое значение, какое бы другое значение я не выбрал
    dzantiev9.7.2011 07:09
    Значит вы события не правильно прописали, либо там ошибка какая то. Можете ссылку дать?
Максим9.7.2011 07:09
У меня было повешено событие клик на див с значением оно перекрывалось live вот статтья http://blog.fxposter.org/2010/06/16/jquery-live-method/ Спасибо за отзывчивость
Максим9.7.2011 08:09
Нет, не разобрался, но работает, сейчас разбираюсь.
yan10.1.2011 03:10
Спасибо за пример. А как сделать, чтобы просто выбор из списка приводил к смене картинки внутри div
    dzantiev10.1.2011 03:10
    нужно добавить свой код в на событие выбора option
    $('.sel_option').live('click', function() { 
     //сюда 
    });
    
Артем10.28.2011 03:10
Доброго времени суток! Очень хороший пример и замечательное обьяснение. У меня вот какая ситуация сложилась. Я сделал взаимозависимые select с помощью ajax. Когда страница загрузилась, то все select "красивенькие", как в примере. Но вот когда я выбираю значение в select_1, то select_2 обновляеться и становиться самым обыкновенным. Я пытался дополнительно подключать reselect('#select_1'); , но к сожалению это ни к чему не приводит. Может что-нибудь подскажете?
Артем10.28.2011 04:10
Все! Разобрался! Все дело было в том, что функция, которая позволяла менять информацию в select_2, находилась в отдельном файле, который подгружался. А скрипт, который делал select "красивеньким" находился в исходном файле и вот по этому, функция reselect('#select_2'); не хотела работать в файле, который подружаеться. П.С. Написал сюда и сразу же сам разобрался :)
Владимир10.31.2011 02:10
спасибо, довольно просто и понятно, не пришлось ломать голову)
alex12.27.2011 07:12
Смотрится красиво, но только код громоздкий. Представьте, этот код нужен только для оформления selecta, а какой код нужно будет прописать для всей страницы, для каждого элемента которой придется писать свой код? Я все-таки за то, чтобы оставляли select таким, каким он и является.
    dzantiev12.27.2011 05:12
    Почему много... весь html код создается налету его можно не учитывать... а для каждого элемента нет необходимости писать стока кода.. достаточно вызывать функцию reselect
      Юрий12.27.2011 11:12
      Доброе время суток. Очень понравился Ваш вариант решения задачи с внешним видом select а, но у меня не удается его запустить. У меня ASP страница. Внутри я подключил jquery . Затем размещаю Ваш скрипт. Вызываю функцию reselect. Если поставить alert, то видно, что функция reselect отрабатывает, но ничего как бы не происходит. ПОдскажите что может быть. Очень нужна Ваша помощь.Заранее благодарен.
      dzantiev12.27.2011 11:12
      скорей всего в стилях ошибка, а то что ASP это не важно
      Юрий12.28.2011 01:12
      Спасибо что отписались. Просто если я руками пропишу нужную страктуру - т.е. заверну мой select в дивы, то стили работают. Самай функция reselect отрабатывает (если поставить алерт внутри функции - то он отработает,т.е. функция вызывается ) , но не переделывает мой select. Имеет значения какая версия jquery и обязательно ли его подключать. Не знаю с чем это может быть связано, но когда подключаю библиотеку jquery - то весь javascript, который написан после строки подключения jquery просто напросто не отрабатывает. jquery качал с офф сайта. Буду благодарен за помощь.
      dzantiev12.28.2011 05:12
      тут кто то писал что если ниже 1.4 то не работает я сам не тестил. Если можно пришлите адрес страницы на которой эта проблема, ото будет трудно разобраться...
      Юрий1.4.2012 05:01
      Спасибо за отзывчивость. Функция reselect так и не заработала. Я обернул мой select руками. Только не понимаю почему когда я локально пробую все работает, а когда заливаю на iis - то работает не корректно. Вот сайт http://91.211.117.18:8012/main.aspx?CountryID=1 и там видно, что он не корректно что-то обрабатывается, хотя он работает. Так не обьясню.Зайдете - будет видно. Спасибо
      Юрий1.4.2012 06:01
      О. Заработало. Если будет не сложно - подскажите где прописать что-то типо стиля overflow:scroll. Чтобы при раскрытии списка появлялась часть записей и скролл,а не весь список выпадал далеко вниз страницы. Огромное спасибо
      dzantiev1.4.2012 07:01
      Если вы используете стили из демо версии, достаточно добавлять класс overf
      reselect('#ourselect2', 'sec overf');
      т.е. нужно добавить класс overf к диву sel_wrap. Вот тут редактируется высота выподашки
      .sec.overf .sel_imul .sel_options{
          height:100px;
      }
      Юрий1.4.2012 09:01
      У меня reselect стандартный не заработал. Вам огромное спасибо за все. Сейчас разберусь. Еще раз спасибо
      Юрий1.19.2012 04:01
      Здравствуйте. Вы не могли бы мне подсказать, как переделать в этом selectе стандартную полосу прокрутки? Вставить вместо стандартного ползунка свою картинку. Можете мне подсказать что-то в этом вопросе?
      dzantiev1.20.2012 04:01
      так просто вставить не получиться... вот почитайте http://css-tricks.com/custom-scrollbars-in-webkit
denswor1.20.2012 11:01
спасибо за пример! использовал его уже в некоторых местах. у меня вопрос: 1. как мне сделать по выбору пункта переход по ссылке? 2. есть ли способы как-то заставить этот скрипт работать на тач-устройствах? спасибо. ps: нашел нечто похожее, но более навернутое: https://github.com/scottdarby/Stylish-Select
    alex1.30.2012 02:01
    здравствуйте, подскажите пожалуйста, как можно сделать, чтоб длинное знаечение option переносилось на следующую строку, например у вас "значение 19" а у меня - "Российский Государственнный Университет", а ширина списка такая же как у вас!
      dzantiev1.30.2012 05:01
      оно же переноситься.. может я не так понял..?
Николай3.10.2012 10:03
Как получить value выбранного элемента??
    dzantiev3.10.2012 10:03
    просто обращаешься к своему селекту как обычно...
      Николай3.10.2012 12:03
      в селекте у меня 3 элемента, добавляю на страницу скрипт:
              function sel() {
                  var objSel = document.getElementById("countrysl");
                  var selIndex = objSel.selectedIndex;
                  alert(selIndex);
              }
      
      где "countrysl" ID моего селекта, в результате какой элемент бы я не выбрал функция sel мне отдает значение 0.... Не могу понять с чем это связанно... может потому что селект у меня добавляется на страницу динамически? Спасибо.
      dzantiev3.10.2012 01:03
      так мне трудно понять.. можешь ссылку скинуть?, вообще может быть да из за этого.
Николай3.10.2012 01:03
Можно получить ваш е-mail на kolia@citynsk.ru?
Николай3.10.2012 02:03
Скинул ссылку. Сия проблема возникает в браузере chrome. Сейчас посмотрел как ведет себя ie, он вообще не отображает алерт сообщение со значением выбранного элемента
uWeb4.7.2012 05:04
Моё решение: http://unotes.ru/drop.php
ОСТАВИТЬ КОММЕНТАРИЙ