Появлению этой методики способствовала воистину монстрообразная вёрстка элементов страницы на нашем проекте. Подумать только, для отображения одной кнопки требовалось до семи тегов на один элемент.
Выглядело это примерно так:
html
Видно, что запутаться в таком коде проще простого, тем паче, что вариантов кнопок на проекте накопилось не менее 30. Попытка создать такую кнопку на серверной стороне вызывала негодование у коллег «пехапистов».
Поэтому моей негласной задачей стало максимальное упрощение кода.
Первоначально появилась мысль сделать все кнопки вообще без использования изображений, как это было описано в одной из статей хабра.
К сожалению, в этом случае добиться кроссбраузерности несколько сложнее, и ещё мне как пользователю не нравятся CSS-шные тени (как верстальщик я их обожаю).
Решение, которое полностью меня устроило, нашлось в использовании псевдоэлементов :before и :after.
Первым шагом стала систематизация. Все кнопки были отсортированы на группы по размерам, изображениям и основному фону.
Чтобы было совсем хорошо, вся кнопочная графика была объединена в один спрайт.
В итоге это дало приличную экономию в общем объёме изображений и количестве http-запросов.
Надо сказать, что мне очень повезло с коллективом, общими усилиями которого мы со временем отказались отнекрофилии поддержки нашего сайта в Internet Explorer 6.
Спустя две недели от вышеуказанного знаменательного события на свет появился совершенно замечательный, на мой взгляд, вариант вёрстки кнопок:
html
css
Суть метода необычайно проста, чего можно не заметить при беглом его рассмотрении. К любому элементу, у которого в названии класса встречается слово «neobtn», мы добавляем базовые «кнопочные» свойства. Затем свойства элемента уточняются добавлением модификаторов (в нашем примере это «-thick»).
Модифицировать элемент можно сколь угодно, не забывая оставаться в рамках разумного.
Для Internet Explorer 7 код почти такой же, только вместо псевдоэлементов используется метод insertAdjacentHTML для создания нужных нам HTML-элементов, а вместо отступов используется абсолютное позиционирование.
css
Этот CSS-код имеет смысл вынести в отдельный файл, подключать его только для пользователей Internet Explorer 7 через условные комментарии, что бы при случае безболезненно от него избавиться:
Небольшие доработки метода позволяют декорировать кнопку типа submit:
html
css
А при желании вставить произвольное изображение в кнопку, требуется добавить ещё один элемент и сделать желаемую картинку его фоном:
html
css
Вся прелесть этого метода в использовании селектора «звёздочка», что позволяет делать кнопку из любого тега, не опасаясь, что вместо «neobtn-thick-create» вы напишите «trololoNEOBTN-THICK-CREATElo».
Единственная важная проблема в данном случае: придумать первое слово в названии класса так, чтобы оно не являлось частью названия классов других элементов. Например, не стоит использовать очевидные слова типа «button» или «btn». Именно по этой причине в примерах названия классов начинаются с «neobtn».
Добавление новых кнопок также не представляет большого труда:
У метода есть и негативные стороны:
Теоретически можно было бы писать имена классов и модификаторов раздельно:
но в этом случае возникла бы некая избыточность и тавтология.
В итоге, у меня получилось нечто среднее между передовыми и «классическими» технологиями html-вёрстки.
Указанным методом можно создавать также выпадающие списки, декорировать поля вода и, наверное, ещё много чего.
Пример
Та же статья на моём сайте.
Update #1: Подробнее об универсальном селекторе
Update #2: Если вы переживаете из-за селекторов «звёздочка» перед селекторами атрибутов, можно запросто от них избавиться. Вёрстка кнопок при этом не пострадает.
Выглядело это примерно так:
html
<div class="large_button"><br> <span class="buttons submit_v2-button clickable"><br> <i class="left left2"></i><br> <i class="body"><br> <b>В архив</b><br> <i class="end"><br> <i></i><br> </i><br> </i><br> </span><br></div>
Видно, что запутаться в таком коде проще простого, тем паче, что вариантов кнопок на проекте накопилось не менее 30. Попытка создать такую кнопку на серверной стороне вызывала негодование у коллег «пехапистов».
Поэтому моей негласной задачей стало максимальное упрощение кода.
Первоначально появилась мысль сделать все кнопки вообще без использования изображений, как это было описано в одной из статей хабра.
К сожалению, в этом случае добиться кроссбраузерности несколько сложнее, и ещё мне как пользователю не нравятся CSS-шные тени (как верстальщик я их обожаю).
Решение, которое полностью меня устроило, нашлось в использовании псевдоэлементов :before и :after.
Первым шагом стала систематизация. Все кнопки были отсортированы на группы по размерам, изображениям и основному фону.
Чтобы было совсем хорошо, вся кнопочная графика была объединена в один спрайт.
В итоге это дало приличную экономию в общем объёме изображений и количестве http-запросов.
Надо сказать, что мне очень повезло с коллективом, общими усилиями которого мы со временем отказались от
Спустя две недели от вышеуказанного знаменательного события на свет появился совершенно замечательный, на мой взгляд, вариант вёрстки кнопок:
html
<div class="neobtn-thick">Текст кнопки</div>
css
/* общие свойства для всех кнопок */
*[class*=neobtn]{
text-shadow: 0 1px 0 #ddd;
cursor: pointer;
background-color: transparent;
display: inline-block;
background-image: url(../images/buttons/buttons.png);
white-space: nowrap;
}
*[class*=neobtn]:before{
background-image: url(../images/buttons/buttons.png);
content: '';
float: left;
}
*[class*=neobtn]:after{
background-image: url(../images/buttons/buttons.png);
content: '';
float: right;
}
/* Персонализация. Создаём кнопку с высотой 46px */
*[class*=neobtn-thick]{
height: 46px;
margin: 0 25px 0 45px;
line-height: 45px;
font-size: 24px;
background-position: 0 -153px;
}
*[class*=neobtn-thick]:before{
height: 46px;
width: 45px;
background-position: 0 -245px;
margin: 0 0 0 -45px;
}
*[class*=neobtn-thick]:after{
height: 46px;
width: 25px;
margin: 0 -25px 0 0;
background-position: 0 -199px;
}
/* Добавляем модификации внешнего вида */
*[class*=neobtn-thick-create]:before{background-position: 0 -291px;}
*[class*=neobtn-thick-go]:before{background-position: 0 -429px;}
*[class*=neobtn-thick-down]:before{background-position: 0 -567px;}
Суть метода необычайно проста, чего можно не заметить при беглом его рассмотрении. К любому элементу, у которого в названии класса встречается слово «neobtn», мы добавляем базовые «кнопочные» свойства. Затем свойства элемента уточняются добавлением модификаторов (в нашем примере это «-thick»).
Модифицировать элемент можно сколь угодно, не забывая оставаться в рамках разумного.
Для Internet Explorer 7 код почти такой же, только вместо псевдоэлементов используется метод insertAdjacentHTML для создания нужных нам HTML-элементов, а вместо отступов используется абсолютное позиционирование.
css
*[class*=neobtn]{
zoom: expression(runtimeStyle.zoom = 1,
insertAdjacentHTML('afterBegin','<div class="before"></div><div class="after"></div>'));
position: relative;
display: inline;
}
.before,
.after{
background-image: url(../images/buttons/buttons.png);
top: 0;
position: absolute;
}
/* BUTTONS */
/* 46px */
*[class*=neobtn-thick] .before{
height: 46px;
width: 45px;
background-position: 0 -245px;
left: -45px;
}
*[class*=neobtn-thick] .after{
height: 46px;
width: 25px;
right: -25px;
background-position: 0 -199px;
}
*[class*=neobtn-thick-create] .before{
background-position: 0 -291px;
}
*[class*=neobtn-thick-go] .before{
background-position: 0 -429px;
}
*[class*=neobtn-thick-down] .before{
background-position: 0 -567px;
}
Этот CSS-код имеет смысл вынести в отдельный файл, подключать его только для пользователей Internet Explorer 7 через условные комментарии, что бы при случае безболезненно от него избавиться:
<!--[if IE 7]><link rel="stylesheet" type="text/css" media="screen" href="/css/buttons_ie.css" /><![endif]-->
Небольшие доработки метода позволяют декорировать кнопку типа submit:
html
<div class="neobtn-thick"><input type="submit" value="Войти" /></div>
css
*[class*=neobtn-thick] input[type=submit]{<br> margin: 0 -17px 0 -37px;<br> padding: 0 12px 0 33px;<br> height: 46px;<br> font-size: 100%;<br> font-family: Arial;<br> text-shadow: 0 1px 0 #ddd;<br> color: #222;<br>}
А при желании вставить произвольное изображение в кнопку, требуется добавить ещё один элемент и сделать желаемую картинку его фоном:
html
<div class="neobtn-thick"><span class="delete"></span>Удалить</div><br><br>
css
.delete {<br> background url(url);<br> width: 00px;<br> height: 00px;<br> display: inline-block;<br>}<br>
Вся прелесть этого метода в использовании селектора «звёздочка», что позволяет делать кнопку из любого тега, не опасаясь, что вместо «neobtn-thick-create» вы напишите «trololoNEOBTN-THICK-CREATElo».
Единственная важная проблема в данном случае: придумать первое слово в названии класса так, чтобы оно не являлось частью названия классов других элементов. Например, не стоит использовать очевидные слова типа «button» или «btn». Именно по этой причине в примерах названия классов начинаются с «neobtn».
Добавление новых кнопок также не представляет большого труда:
- Рисуем новые изображения в общем спрайте
- Добавляем в css соответствующие правила
- PROFIT!
У метода есть и негативные стороны:
- Использование селектора «звёздочка» по идее несколько замедляет процесс отрисовки страницы. Однако стоит заметить, что сколь бы то значимой задержки мне так и не удалось добиться. Количество кнопок на странице не превышает одного-двух десятков, а с учётом сокращения количества тегов, разница в скорости нивелируется.
- При масштабировании в режиме «только текст» — всё развалится.
Теоретически можно было бы писать имена классов и модификаторов раздельно:
<div class="button button-thick button-thick-create">Создать</div><br>
но в этом случае возникла бы некая избыточность и тавтология.
В итоге, у меня получилось нечто среднее между передовыми и «классическими» технологиями html-вёрстки.
Указанным методом можно создавать также выпадающие списки, декорировать поля вода и, наверное, ещё много чего.
Пример
Та же статья на моём сайте.
Update #1: Подробнее об универсальном селекторе
Update #2: Если вы переживаете из-за селекторов «звёздочка» перед селекторами атрибутов, можно запросто от них избавиться. Вёрстка кнопок при этом не пострадает.