Резиновая кнопка
Задача
Для формы сделать резиновую (тянущуюся) кнопку по ширине с особым оформлением (с обычным оформлением уверен у тебя проблем не возникает).
Требования:
- ширина кнопки зависит от текста в ней
- использование тега <input> (чтобы сохранить логичность кода. Как сделать с <button>, пока не нашел решения)
- кликабильность всей поверхности кнопки
- отсутствие javascript (еще одна причина использовать <input>)
- ну и конечно же кроссбраузерность и следование стандартам
На кой это нужно?
На сайте может быть много форм, а на крупных сайтах — очень много. Каждая форма как правило имеет кнопку. И бывает так, что в разных формах текст в кнопке должен быть разным: ok, сохранить, задать вопрос менеджеру и т.п. Чтобы не плодить для каждой формы отдельный фон для кнопки, лучше сделать одну универсальную кнопку. Это не только съекономит трафик за счет сокращения картинок, но и сделает верстку более гибкой (не нужно будет каждой новой кнопке с отличающимся текстом рисовать новый фон и добавлять классы).
Решение
Воспользуемся следующим приемом:
<div class="button"> <input type="submit" value="" />текст кнопки <span></span> </div>
.button { color: #fff; /* цвет текста кнопки */ height: 23px; /* высота кнопки */ padding: 5px 6px 0 6px; /* внутренние отступы кнопки */ background: url(path-to/button.png) no-repeat; /* длинная картинка - левая часть фона кнопки */ font-size: 11px; /* размер шрифта кнопки */ float: left; /* чтобы ширина блока зависела от содержимого */ position: relative; overflow: hidden; } .button span { background: url(path-to/button-r.png); /* фон правой части кнопки */ height: 27px; width: 6px; display: block; position: absolute; z-index: 1; /* обязательно указываем z-слой, чтобы input был выше */ top: 0; right: 0; overflow: hidden; } .button input { position: absolute; /* абсолютно размещаем input поверх остальных элементов */ top: 0; left: 0; width: 200%; /* input должен занимать всю область по высоте и ширине, чтобы вся кнопка была кликабильной (200% для ие6, чотбынавреняка растянулся на всю ширину, ибо при 100% растягивался не полностью) */ height: 100%; opacity: 0; /* делаем кнопку полностью прозрачной, чтобы она не искажала задуманный дизайн, но была функционирующей */ filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); /* прозрачность для ие6-7 */ cursor: pointer; border: none; z-index: 2; /* z-слой должен быть больше, чем у других частей кнопки */ } * html .button { height: 27px; /* учитываем блочную модель ие6 */ } .button span { right: -1px; /* тут правильней было б использовать expression для лечения смещений в 1px в ие6 */ }
Заметки
- В боевых условиях вместо хаков для IE6 следует использовать условные комментарии
- для уменьшения количества отдельных картинок, можно воспользоваться техникой спрайтов — склеить картинки в одну:
Недостаток
В таком виде не подходит прием, если углы кнопки должны быть прозрачными.
Решение 2
update by nadiam84 Некоторые манипуляции в HTML + CSS дают возможность сделать кнопку с прозрачными углами, за счет того, что углы не будут накладываться на фон:
<div class="button"> <div> <input type="submit" value="текст кнопки" /> <span></span> </div> </div>
.button { float: left; /* чтобы ширина кнопки зависела от контента. по идее должен подойти и display: inline-block */ margin: 50px; } .button div { position: relative; color: #fff; height: 27px; background: url(path-to/button.png) no-repeat; /* левые углы фона с прозрачными участками */ font-size: 11px; } * html .button div { /* хак для ие6 чтобы с шириной кнопки проблем не было */ width: 10px; } .button span { /* правое скругление кнопки выносим за пределы кнопки */ background: url(path-to/button-r.png); height: 27px; width: 6px; display: block; position: absolute; z-index: 1; top: 0; right: -6px; overflow: hidden; } .button input { height: 100%; cursor: pointer; margin: 0 -6px 0 0; /* чтобы кликабильным была правая часть кнопки, вынесенная за ее пределы */ padding: 2px 6px 5px 6px; overflow: visible; /* убираем необнуляемые внутренние отступы для ie6-7 */ border: none; position: relative; z-index: 2; background: none; }
Демо пример. Проверено:
- IE 6-7
- Firefox 3.6
- Opera 10.5
- Chrome 7
Преимущества:
- возможность использования прозрачных углов;
- код чуть более семантичен, чем в предыдущем примере (текст кнопки, теперь действительно текст кнопки).
Недостатки:
- для реализации одной кнопки требуется 4 элемента! Можно span заменить псевдоэлементом (before), но это не намного улучшит ситуацию;
- раздутый CSS код.
Решение 3 — CSS3
update by Евгений Рыжков Пришло время CSS3 и незачем больше заниматься фигней с этими костылями из кучи HTML и CSS! Юзаем border-radius в сочетании с каким-нибудь PIE для IE и будет всем счастье.
<input type="submit" value="текст кнопки" />
input { height: 27px; cursor: pointer; padding: 2px 6px 5px 6px; overflow: visible; border: none; background: url(img/button-repeat.png) repeat-x; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
Для IE:
input { behavior: url(path-to/PIE.htc); }
Демо пример. Проверено:
- IE 6-8
- Firefox 3.6
- Opera 10.5
- Chrome 7
Преимущества тут даже не стоит перечислять: достаточно сравнить HTML и CSS коды этого варианта с предыдущими. Да пребудет с нами HTML5 и CSS3!