Суббота, 28 Апреля 2012 10:01

Стилизация элементов управления select, checkbox, radio

Written by 
Оцени эту запись
(32 Голоса)

Как мы знаем, элементы управления типа <select>, <input type="radio">, <input type="checkbox"> нельзя стилизировать с помощью стилей css. Для этого нужно использовать Javascript.

Идея стилизации элементов управления заключается в том, чтобы на место нужного элемента управления поставить свой стилизированный блочный элемент, а сам элемент управления скрыть. 

Хочу обратить внимание на то, что у radio и checkbox есть два состояния - выбранный и не выбранный. Для этого введем еще один блок, внутри основного, который будет появляться только для выбранного состояния.

У элемента select также есть два состояния - открытое и закрытое. В закрытом состоянии видно только выбранный пункт списка вариантов, а в открытом виден весь список.

 

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

 

Итак, рассмотрим такую форму:

 

 

<form>
<input type="radio" checked="checked" /><br />
<input type="radio" /><br />
<input type="radio" /><br />
<input type="radio" /><br />
<input type="checkbox" /><br />
<select>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>1997</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
</select>
<br>
<br>
<br>
<select>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
</select>
</form>
 
 
В <head> документа нужно подключить библиотеку jQuery:
 
 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
 
 
 а также написанные нами скрипт и стили:
 
<script type="text/javascript" src="/js/elem_styling.js"></script>
 
<link rel="stylesheet" type="text/css" href="/styles/elem_styling.css">
 
 
 
 
 
Рассмотрим подробнее скрипт:
 
 
$(document).ready(function(){
$('input[type="radio"]').addClass('rad_styled');
$('.rad_styled').wrap('<div class="rad_styled_cont">');
$('input[type="radio"]:checked').parent().addClass('checked');
$('.rad_styled_cont').append('<span class="rad_styled_inner"></span>');
$('input[type="radio"]').click(function(){
$(this).parent().toggleClass('checked');
});
$('select').addClass('sel_styled');
$('.sel_styled').wrap('<div class="sel_styled_cont">');
$('.sel_styled').width($('.sel_styled_cont').width());
$('.sel_styled_cont').append('<span class="sel_styled_inner"></span>');
$('.sel_styled_cont').append('<div class="sel_styled_cont_open"></div>');
$('.sel_styled').children('option').each(function() {
$(this).parent().parent().children('.sel_styled_cont_open').append('<div class="sel_styled_opt">'+$(this).text()+'</div>');
});
$('.sel_styled_cont').click(function(){
$(this).toggleClass('open');
$(this).children('.sel_styled_cont_open').slideToggle();
$(this).children('.sel_styled_cont_open').children('.sel_styled_opt').click(function(){
$(this).parent().parent().children('.sel_styled_text').text($(this).text());
$(this).parent().parent().children('.sel_styled').val($(this).text());
});
});
$('.sel_styled').each(function() {
$(this).parent().append('<span class="sel_styled_text">'+$(this).val()+'</span>');
});
 
$('input[type="checkbox"]').addClass('che_styled');
$('.che_styled').wrap('<div class="che_styled_cont">');
$('input[type="checkbox"]:checked').parent().addClass('checked');
$('.che_styled_cont').append('<span class="che_styled_inner"></span>');
$('input[type="checkbox"]').click(function(){
$(this).parent().toggleClass('checked');
});
});
 
 

1. Стилизация  <input type="radio">

 
Находим в документе input[type="radio"] и добавляем ему класс rad_styled, далее будем работать только с ним:
 
$('input[type="radio"]').addClass('rad_styled');
 
Оборачиваем его в блок с классом rad_styled_cont
$('.rad_styled').wrap('<div class="rad_styled_cont">');
 
Если элемент input[type="radio" по умолчанию выбран, родительскому блоку (в который обернули) добавляем класс checked
 
$('input[type="radio"]:checked').parent().addClass('checked');
 
В него же вставляем <span> с классом rad_styled_inner, который будет показывать выбранность элемента radio, то есть будет отображаться только в случае, когда radio выбран
 
$('.rad_styled_cont').append('<span class="rad_styled_inner"></span>');
 
Далее работаем с событием click на наш элемент:
 
$('input[type="radio"]').click(function(){
$(this).parent().toggleClass('checked');
});
 
По клике на него, родительскому добавляется класс  checked.
В стилях указываем, что <span class="rad_styled_inner"></span> скрыт (display: none;), а когда у родительского rad_styled_cont есть класс checked, то внутренний rad_styled_inner имеет стиль display: block.
 
 

2. Стилизация  <input type="checkbox">

 
 
Для элемента input[type="checkbox"] все аналогично.
 
 

3. Стилизация  <select>

 
 
Рассмотрим подробнее стилизацию элемента управления select.
 
Находим в документе все элементы select, добавляем им класс sel_styled  и будем работать с ними. Сам select скрываем с помощью стилей opacity: 0.
 
$('select').addClass('sel_styled');
 
Оборачиваем в блок с классом sel_styled_cont
 
$('.sel_styled').wrap('<div class="sel_styled_cont">');
 
Селекту даем ширину, равную ширине родительского блока (чтобы удобнее было выбирать позиции списка)
$('.sel_styled').width($('.sel_styled_cont').width());
 
В только что добавленный родительский блок вставляем <span class="sel_styled_inner"></span>, который будет заменять стрелочку вниз для селекта
 
$('.sel_styled_cont').append('<span class="sel_styled_inner"></span>');
 
Также в родительский элемент вставляем блок sel_styled_cont_open, в котором будет список позиций селекта. В стилях его скрываем display: none.
 
 
$('.sel_styled_cont').append('<div class="sel_styled_cont_open"></div>');
 
В указанный блок добавляем элементы с классом sel_styled_opt, в каждом из которых будет значение позиций селекта
 
$('.sel_styled').children('option').each(function() {
$(this).parent().parent().children('.sel_styled_cont_open').append('<div class="sel_styled_opt">'+$(this).text()+'</div>');
});
 
 
В родительский элемент селекта вставляем дополнительный блок sel_styled_text, в нем будет отображаться выбранное значение (позиция) селекта.
 
$('.sel_styled_cont').append('<span class="sel_styled_text">'+$('.sel_styled').val()+'</span>');
 
 
При клике на селект, точнее на его родительский блок, мы его "открываем":
 
 - даем ему класс "open"
 - отображаем список позиций селекта sel_styled_cont_open
 
При клике на одну из позиций, sel_styled_text задем значение выбранной позиции и самому скрытому стилями селекту задаем такое же значение, чтобы с ним можно было дальше работать.
 
$('.sel_styled_cont').click(function(){
$(this).toggleClass('open');
$(this).children('.sel_styled_cont_open').slideToggle();
$(this).children('.sel_styled_cont_open').children('.sel_styled_opt').click(function(){
$(this).parent().parent().children('.sel_styled_text').text($(this).text());
$(this).parent().parent().children('.sel_styled').val($(this).text());
});
});
 
 
 

Стили выглядят так:

 
 
.rad_styled_cont, .che_styled_cont {
bordeR: 1px solid #ebebeb;
width: 9px;
height: 9px;
position: relative;
}
.rad_styled, .che_styled {opacity: 0; z-index: 999; position: relative; margin: 0px;}
.rad_styled_cont .rad_styled_inner, .che_styled_inner {width: 7px; height: 7px; background: #ebebeb; displaY: none; position: absolute; top: 1px; left: 1px; z-index: 998;}
.rad_styled_cont.checked .rad_styled_inner, .che_styled_cont.checked .che_styled_inner  {displaY: block;}
:focus {outline: none;}
.sel_styled {padding: 3px 7px 2px 10px; position: relative; margin: 0px; opacity: 0; z-index: 999; color: #999;}
.sel_styled_inner {display: block; width: 26px; height: 25px; background:url(../images/sel_ar.png) no-repeat; position: absolute; top: 0px; right: 0px; z-index: 998;}
.sel_styled_cont {position: relative; float:left; border: 1px solid #ebebeb; color: #999; font-family: Arial, Helvetica, sans-serif; font-size: 12px; float:left;}
.sel_styled_text {float:left; padding: 3px 0px 3px 10px; position: absolute; top: 1px; left: 1px;}
.sel_styled option {display: none; z-index: 998;}
.sel_styled_cont_open {position: absolute; top: 25px; left: -1px; z-index: 1000; display: none; border: 1px solid #ebebeb; background: #fff; width: 100%;}
.sel_styled_opt {padding: 3px 9px;}
 
 
Если есть желание выделить позицию списка в select, можно задать блокам sel_styled_opt  стили на hover, например изменить фон и цвет шрифта:
.sel_styled_opt:hover {background: #ccc; color: #000;}
 
 
Если есть вопросы, пишите в комментариях. С удовольствием отвечу. 
 
 
 
Обновлено 16.10.2012:
 
 
Если нужно выделение только одного radio из отдельного набора, нужно делать проверку на наличие у других radio такого же атрибута name. В таком случае скрипт в этой части будет отличаться. Частично это смотрите в комментариях. Полностью скрипт ниже:
 
 
 
$(document).ready(function(){
$('input[type="radio"]').addClass('rad_styled');
$('.rad_styled').wrap('<div class="rad_styled_cont">');
$('input[type="radio"]:checked').parent().addClass('checked');
$('.rad_styled_cont').append('<span class="rad_styled_inner"></span>');
/*$('input[type="radio"]').click(function(){
$(this).parent().toggleClass('checked');
});*/
$('input[type="radio"]').click(function(){
var name = $(this).attr('name');
$('input[type="radio"]').each(function(){
if($(this).attr('name') == name) {
$(this).parent().removeClass('checked');
}
});
 
 
$(this).parent().addClass('checked');
});
$('select').addClass('sel_styled');
$('.sel_styled').wrap('<div class="sel_styled_cont">');
$('.sel_styled').width($('.sel_styled_cont').width());
$('.sel_styled_cont').append('<span class="sel_styled_inner"></span>');
$('.sel_styled_cont').append('<div class="sel_styled_cont_open"></div>');
$('.sel_styled').children('option').each(function() {
$(this).parent().parent().children('.sel_styled_cont_open').append('<div class="sel_styled_opt">'+$(this).text()+'</div>');
});
$('.sel_styled_cont').click(function(){
$(this).toggleClass('open');
$(this).children('.sel_styled_cont_open').slideToggle();
$(this).children('.sel_styled_cont_open').children('.sel_styled_opt').click(function(){
$(this).parent().parent().children('.sel_styled_text').text($(this).text());
$(this).parent().parent().children('.sel_styled').val($(this).text());
});
});
 
$('.sel_styled_cont').append('<span class="sel_styled_text">'+$('.sel_styled').val()+'</span>');
 
$('input[type="checkbox"]').addClass('che_styled');
$('.che_styled').wrap('<div class="che_styled_cont">');
$('input[type="checkbox"]:checked').parent().addClass('checked');
$('.che_styled_cont').append('<span class="che_styled_inner"></span>');
$('input[type="checkbox"]').click(function(){
$(this).parent().toggleClass('checked');
});
});
 
 
 
 
 
 
Также можно добавить событие onChange для select. Для этого добавим выбранному option атрибут selected и зададим самому select состояние change:
 
 
$('.sel_styled_cont').click(function(){
$(this).toggleClass('open');
$(this).children('.sel_styled_cont_open').slideToggle();
$(this).children('.sel_styled_cont_open').children('.sel_styled_opt').click(function(){
$(this).parent().parent().children('.sel_styled_text').text($(this).text());
$(this).parent().parent().children('.sel_styled').val($(this).text());
opt_num = $(this).index();
$(this).parent().parent().children('.sel_styled').children('option').removeAttr('selected');
$(this).parent().parent().children('.sel_styled').children('option').eq(opt_num).attr('selected', 'selected');
$(this).parent().parent().children('.sel_styled').trigger("change");
});
});
 
 
 
Тогда можно для select задать событие onChange обычным образом:
 
 
<select onChange="Changed2()" id="select2" name="change2"> ...</select>
 
 
 

Additional Info

Комментарии  

 
0 #2 wdtime.ru 06.06.2014 23:32
Читайте также про стилизацию checkbox с помощью легкого плагина jQuery. Очень прост и в тоже время эффективен: jQuery checkbox
Цитировать
 
 
+1 #1 Игорь 05.12.2013 00:08
В опере не правильно работают select . Такое ощущение что не срабатывает стиль .sel_styled option {display: none; z-index: 998;} Как с этим быть?
Цитировать
 

Добавить комментарий


Защитный код
Обновить

верстка | CSS | верстка сайтов | HTML | верстальщик | блочная верстка | JavaScript | css верстка | профессиональная верстка сайтов