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
Bohdan7.12.2012 01:07
Здравствуйте, такой вопрос: данный скрипт передает в POST переменную всегда значение 1, вне зависимости от выбранного пункта, в чем может быть проблема?
    dzantiev7.12.2012 01:07
    либо он не срабатывает и значение скрытого селекта не меняется, либо что то не так с формой. Если можно ссылку на пример, так не ясно...
Pooh8.30.2012 08:08
Класс .act у .sel_imul убирается только по нажатию на область документа. При клике на .sel_option у .sel_imul не убирается класс .act
Fantom20679.4.2012 04:09
Здраствуйте. Обычный селект у меня имеет такую функцию onchange="document.getElementById('formx').action = this.options[this.selectedIndex].value" все прекрасно работает. Подскажите пожалуйста, как можно эту функцию преобразовать чтобы работала в нестандарном Вашем селекте? Желательно примером, в яваскрипте не силен.
Sergey10.9.2012 11:10
У меня не пашет пример...как правильно подключить???
    dzantiev10.9.2012 11:10
    посмотрите как в демо версии, точно также нужно подключать... скрипт как обычный js файл.
Дмитрий11.13.2012 01:11
Здравствуйте! Правильно ли я понял, что писать непосредственно в html надо только , а все остальное подключает скрипт? Или необходимо писать все, начиная с
    dzantiev11.13.2012 02:11
    да да все правильно поняли, писать html не нужно, только немного js и css под себя если нужно... На демо версии же видно
      Дмитрий11.13.2012 03:11
      В таком случае код отличный! Очень здорово, лучше решений не видел, добавил сайт в избранное)
Дмитрий11.13.2012 01:11
с
Алексей11.21.2012 07:11
Здравствуйте. Разбирался в Вашем примере, все было отлично, но когда попробовал повторить и запустить пример, скрипты вдруг отказались работать. Попробовал запустить неизмененный код примера на своем сервере и сторонней платформе, работать он точно так же отказался. Казалось бы, совершенно одинаковый код(убрал только 2 строки со стилями jsfiddle): http://jsfiddle.net/axelru/QBHjY/21/embedded/result/ и http://jsbin.com/isuron/1/ Но почему-то код по второй ссылке не работает. jQuery подключена. В чем может быть проблема?
    dzantiev11.21.2012 08:11
    у меня ваш пример не открывается... может быть вы не обернули скрыпты свои в
    $(document).ready(function(){ /*код*/ });
Алексей11.22.2012 01:11
Мда, действительно. Вот что значит дерьмовое знание основ jQuery. Спасибо большое.
kuzyakiev12.13.2012 02:12
Ряд вопросов которые могут возникнуть: Что если значение внутри слишком длинное? В вашем случае при таком выбранном, селект вырастает по ширине, чем сломает ряд дизайнов. Учитывает ли ваш селект события по нативному селекту. На больших сайтах этого не избежать. Например -> Выбор страны и потом штата(региона, города). Или пользователь вводит почтовый индекс, и какой то скрипт обновляет все поля адресс. Понятное дело что обновлять он будет обычные селекты.
    dzantiev12.13.2012 04:12
    да если значение длинное, то при выборе этого значения селект будет увеличиваться в высоту. Это можно при необходимости пофиксить задав принудительно высоту для .selected-text . А что по обновлению полей.. в данном скрипте это к сожалению не предусмотрено.. нужно будет дописывать.
Андрей12.16.2012 05:12
Как сделать так чтобы работало После того как применяю стиль - не работает, реагирует также как и при обычном
    Андрей12.16.2012 05:12
    - вот это охото применить
Андрей12.16.2012 05:12
option disabled = "disabled"
Владимир1.24.2013 08:01
хорошее, простое решение. большое спасибо!
Сергей1.24.2013 09:01
>> Ну еще напишем меленький код который будет закрывать селект при холостом клике, blur так зказать: $(function(){ $('body').click(function(event){ alert('clicked out select !!'); }); $('.sel_wrap').click(function(event){ return false; }); });
    Сергей1.24.2013 09:01
    в действии: http://jsfiddle.net/5Lf8T/
Denis2.10.2013 05:02
Это не select. Select должен управляться с клавиатуры.
CSS2.11.2013 02:02
А можно л иизменить высоту option?
Влад3.11.2013 12:03
Здравствуйте. Есть скрипт который при выборе элемента списка добавляет к ссылке значения, подскажите пожалуйста как объединить эти два скрипта? jqu('#dynamic_select').bind('change', function () { var url = jqu(this).val(); // get selected value if (url) { // require a URL window.location = url; // redirect } });
Spec4.22.2013 10:04
При выборе любого значения, кроме самого первого, при отправке из формы методом GET, отправляются два значения - самое первое и то, которое я выбрал. Примерно вот так, если выбрать значение 15: mysite.ru/test.html?sel=eee&sel=122
lamport8.18.2013 06:08
а у меня selectы отображаются, reselect работает, но больше ничего не происходит.
Andrew Tereshin10.14.2013 03:10
Селекты работают. Но есть одно большое но. Когда на сайте переход страниц построен на аяксе, то селекты не будут срабатывать. Если например, у меня движок Vii Engine. Если с одной страницы перейти на другую, то переход будет на аяксе. А селекты после перехода работать не будут. Они просто не нажимаются. А хотя визуально показывается нормально. Можно ли как-то исправить?
Юрий12.7.2013 10:12
Как поменять id на class ? очень нид ?
Юрий12.7.2013 10:12
после подключения у меня перестал работать вызовы ВЫБЕРИТЕ СТРАНУ...
Юрий12.7.2013 10:12
!!!-- ВЫБЕРИТЕ СТРАНУ...---!!!
Юрий12.7.2013 10:12
Код не вставляется
Юрий12.7.2013 10:12
ВЫБЕРИТЕ СТРАНУ...
Юрий12.7.2013 10:12
select id="country" class="sec overf round" onchange="showOverlays(this.value);document.getElementById('city').selectedIndex = 0;document.getElementById('rozn').selectedIndex = 0;"> option disabled selected="selected" value="1000"ВЫБЕРИТЕ СТРАНУ.../option ))) Сори за флуд!!
ОСТАВИТЬ КОММЕНТАРИЙ