07 сентября

Стилизация форм

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

Как же это сделать ?
Очевидным решением является использовать стандартный элемент ;)
Но обо всем по порядку.

Особнность предложенного метода в том, что пользователь работает со стандартными элементами формамы, который наложены поверх стилизованных элементов.
Это позволяет без использования дополнительных обработчиков использовать все преимущества стандартных элементов форм, что особенно актуально для отображения на мобильных устройствах.

Чекбоксы

В своих статьях я уже писал про чексоксы неоднократно, поэтому сразу преведу пример:

структура:

<div class="block">
    <div class="checkbox"><input id="checkbox" type="checkbox" /></div><label for="checkbox">Чекбокс</label>
</div> 

стили:

.checkbox{
    display:inline-block;
    width:14px;
    height:14px;
    background: url(../img/checkbox.png) no-repeat 0px -14px;
    margin-right:8px;
}
.checkbox.checked{
    background-position: 0px 0px;
}
.checkbox input{
    width:14px;
    height:14px;
    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); 
    -moz-opacity: 0;
    -khtml-opacity: 0;
    opacity: 0;
    cursor: pointer;
}
.checkbox + label{
    display:inline-block;
    vertical-align:top;
    margin-right:20px;
    cursor:pointer;
}

обработчик:

// Расчитываем чекбоксы

$('.checkbox input').each(function(){
    if ($(this).is(':checked'))
        $(this).parent().addClass('checked');
})    
$(document).on('change', '.checkbox input', function(){
    if ($(this).is(':checked'))
        $(this).parent().addClass('checked');
    else
        $(this).parent().removeClass('checked');
})  

Радио-баттоны (radio)

Стилизация radio почти аналогична стилизации чекбоксов. отличается лишь обработчик.

структура:

<div class="block radio_group">
    <div class="radio"><input type="radio" id="radio1" name="radio" /></div><label for="radio1">Радио1</label><div class="radio"><input id="radio2" name="radio" type="radio" /></div><label for="radio2">Радио2</label>
</div>

стили:

.radio input{
    width:13px;
    height:13px;
    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); 
    -moz-opacity: 0;
    -khtml-opacity: 0;
    opacity: 0;
    cursor: pointer;
}
.radio + label{
    display:inline-block;
    vertical-align:top;
    margin-right:20px;
    cursor:pointer;
}
.radio{
    display:inline-block;
    width:13px;
    height:13px;
    background: url(../img/radio.png) no-repeat 0px -13px;
    margin-right:8px;
}
.radio.checked{
    background-position: 0px 0px;
}

обработчик:

$('.radio input').each(function(){
    if ($(this).is(':checked'))
        $(this).parent().addClass('checked');
})    
$(document).on('change', '.radio input', function(){
    $(this).parents('.radio_group').find('.radio').removeClass('checked');
    $(this).parents('.radio_group').find('input:checked').parent().addClass('checked');
}) 


Селект (Select)

Подобная стилизация селекта является оптимальным вариантом для мобильных устройств, тк выбор производится с использованием обработчика устройства.
реализация очень схожа с вышеописанными:

структура:

<div class="block">
    <label>Селект</label>
    <div class="select"><div class="inputbox"></div>
        <select>
            <option>Тентовая газель</option>
            <option>Газель</option>
            <option>Камаз</option>
        </select>
    </div>
</div>

стили:

.select .inputbox{
    padding-right: 30px;
    background: #ffffff url(../img/select.png) no-repeat right center;
}

.select{
    overflow:hidden;
    height:28px;
    position:relative;
    width:250px;
}
.select select{
    width:100%;
    height:28px;
    position:absolute;
    top:0px;
    left:0px;
    z-index:2;
    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); 
    -moz-opacity: 0;
    -khtml-opacity: 0;
    opacity: 0;    
    cursor:pointer;
}
.inputbox{
    width:100%;
    font-weight: 300;
    color:#010101;        
    font-size:15px;
    padding: 0px 10px;
    
    height:28px;
    line-height:28px;
    border: 1px solid #c9c9c9;
    border-radius: 3px;
    -moz-border-radius: 3px;
    -webkit-border-radius: 3px;
    margin-bottom:10px;
    box-sizing:border-box;
}

обработчик:

$('.select select').each(function(){
    var text_val = $(this).find('option:selected').text();
    $(this).parents('.select').find('.inputbox').text(text_val)
})
$(document).on('change', '.select select', function(){
    var text_val = $(this).find('option:selected').text();
    $(this).parents('.select').find('.inputbox').text(text_val)
})


Файл (input file)

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

структура:

<div class="block">
    <label>Файл</label>
    <div class="file">
        <input type="file" />
        <div class="inputbox"><span></span></div>
        <div class="btn">Обзор...</div>
    </div>
</div>


стили:

.file{
    overflow:hidden;
    position:relative;
    width:250px;
}
.file .inputbox{
    width: 160px;
    float:left;
    border-right:0px none;
    border-radius: 3px 0px 0px 3px;
    -moz-border-radius: 3px 0px 0px 3px;
    -webkit-border-radius: 3px 0px 0px 3px;
    margin:0px;
    height: 28px;
    box-sizing:content-box;
    overflow:hidden;
}
.file .inputbox span{
    width: 500px;
    display:block;
}
.file .btn{
    float:left;
    border-radius: 0px 3px 3px 0px;
    -moz-border-radius: 0px 3px 3px 0px;
    -webkit-border-radius: 0px 3px 3px 0px;
}
.file:hover .btn{
    background:#5fdcdd;
    border-color:#5dcfcf;    
}
.file input{
    position:absolute;
    width:120%;
    height: 100%;
    top:0px;
    left:0px;
    cursor:pointer;
    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); 
    -moz-opacity: 0;
    -khtml-opacity: 0;
    opacity: 0;    
}
.btn{
    display:inline-block;
    background:#1ecdcf;
    height:27px;
    line-height: 25px;
    font-size:14px;
    border-bottom: 3px solid #1bbbbc;
    color:#ffffff;
    padding: 0 8px;
    border-radius: 4px;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    -webkit-transition: all 500ms;
    -moz-transition: all 500ms;
    -ms-transition: all 500ms;
    -o-transition: all 500ms;
    transition: all 500ms;    
    text-align: center;
    text-decoration: none;
}
.btn:hover{
    background:#5fdcdd;
    border-color:#5dcfcf;
}
.inputbox{
    width:100%;
    font-weight: 300;
    color:#010101;        
    font-size:15px;
    padding: 0px 10px;
    
    height:28px;
    line-height:28px;
    border: 1px solid #c9c9c9;
    border-radius: 3px;
    -moz-border-radius: 3px;
    -webkit-border-radius: 3px;
    margin-bottom:10px;
    box-sizing:border-box;
}


и обработчик:

// Расчитываем file
$('.file').each(function(){
    $(this).find('.inputbox span').text($(this).find('input').val());
})    
$(document).on('change', '.file input', function(){
    $(this).parents('.file').find('.inputbox span').text($(this).val());
})

 


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

Демо Скачать