Создаем динамические кнопочки-ссылки с помощью CSS
Чем привлекательны CSS - тем, что они часто, при создании тех или иных эффектов, позволяют заменить JavaScript. Вот и на этот раз каскадные таблицы стилей помогут нам сконструировать красивые динамические кнопочки.
Информацию, изложенную ниже, можно рассматривать как альтернативу способу создания универсальных графических кнопок и данный способ отчасти решает те же задачи.
Такие кнопки-ссылки:
- Растягиваются горизонтально в зависимости от длины текста.
- Могут иметь углы нужной формы, выполненной в рисунке.
- Делают всю площадь кликабельной.
- Остаются удобочитаемыми при отключении изображений.
Особенность кнопки заключается в ее динамике, т.е. меняется ее графическое представление в разных состояниях:
- по умолчанию;
- при наведении курсора;
- при нажатии на кнопку.
Динамическая кнопка с двойным эффектом
Создадим кнопку на CSS, которая имеет только 2 состояния: “по умолчанию” и “при наведении курсора“.
Наша кнопка основана на использовании тега a со вложенным в него тегом span, каждый из которых использует различные слои фонового изображения. Для получения возможности растяжки фона при увеличении размера кнопки по горизонтали задействуем так называемую технику “раздвижных дверей”. Вот так выглядит кнопка-ссылка в части HTML-кода:
- <a href="#" class="button"><span>Динамическая кнопочка</span></a>
Как видите, код максимально прост. Далее нам нужно создать изображения кнопки в обоих состояниях. Для этого я воспользовался программой “Crystal Button“. Вот что у меня получилось:
ДефолтнаяПри наведении мыши

Оба состояния кнопки мы поместим в одно изображение (для каждого из тегов a и span) и для смены с нормального состояния в “hover” будем смещать фоновое изображение по вертикали, CSS легко нам в этом поможет (о плюсах совмещения изображений в одно рассказано в статье “Оптимизация: используем одно изображение вместо двух”). Часть изображения, которая будет растягиваться в зависимости от текста, сделаем, к примеру, длиной в 350 пикселей (в зависимости от предполагаемой длины кнопок можно подобрать необходимую длину этой части). Высота нашей кнопки составляет 33 пикселя.
Для получения нужного эффекта раньше я прибегал к помощи JavaScript, CSS при этом вообще не использовался. HTML-код был следующим:
- <a href="#" name="cat" onmouseover="document.cat.src='button_hover.gif';" onmouseout="document.cat.src='button.gif';"><img src="button.gif" alt="Кнопочка" border="0"></a>
Соответственно, если у посетителя сайта отключен JavaScript, никакого эффекта наших красивых динамических кнопок он не увидит. Каскадные таблицы стилей помогут нам избавиться от этого недостатка.
Попробуем сделать точно такую же кнопку, используя CSS вместо JavaScript.
Код, которым оформим кнопочки “по умолчанию”:
- a.button {
- display: block;
- float: left; /* чтобы кнопка не растягивалась на всю ширину родительского блока, а ограничивалась текстом */
- font: bold 12px arial, sans-serif;
- color: #555;
- text-decoration: none;
- background: url(button_r.gif) top right no-repeat;
- padding-right: 25px; /* отступ для "раздвижных дверей" */
- outline: none; /* убираем точечную обводку в FireFox, которая появляется при клике */
- }
- a.button span {
- display: block;
- line-height: 13px;
- background: url(button_l.gif) no-repeat;
- padding: 7px 0 13px 23px;
- }
Необходимо учитывать, что высота строки и вертикальные отступы, заданные для span, в сумме должны с точностью равняться высоте изображения (в нашем примере - 33px). Если бы изображение не имело тени, то можно было бы просто указать высоту строки, равной 33px, тогда текст сразу поместился бы вертикально посередине.
Сейчас добавим эффект, который появляется при наведении курса мыши на кнопку:
- a.button:hover {
- background-position: 100% -33px;
- }
- a.button:hover span {
- background-position: 0% -33px;
- color: #222;
- }
Готово! Вот что у нас получилось.
Динамическая кнопка с тройным эффектом
Мы пойдем еще дальше и добавим для нашей кнопки-ссылки еще один эффект, который проявляется при нажатии на кнопку. Соответственно для наших изображений мы добавляем еще одно состояние.
spana

Осталось дописать чуток CSS для третьего состояния кнопки-ссылки:
- a.button:active {
- background-position: 100% -66px;
- }
- a.button:active span {
- background-position: 0% -66px;
- color: #222;
- padding: 8px 0 12px 23px; /* опускаем текст на 1px */
- }
Готово! Можно кликать!
Получается вполне симпатично, не правда ли? :)
По желанию, для всех трех состояний кнопки можно установить фоновый цвет, на случай, если в браузере пользователя отключен показ изображений. В таком случае достаточно классам a.button, a.button:hover и a.button:active добавить свойство background-color.
P.S. Internet Explorer, как всегда, вставляет нам “палки в колеса” - не возвращает кнопку в нормальное состояние всякий раз, когда она “отпущена”. Чтобы заставить его это делать, для тега а приходится использовать небольшой код JavaScript:
- <a href="#" class="button" onclick="this.blur(); return false;"> ... </a>
P.P.S. Созданные изложенным выше способом кнопки с легкостью можно использовать в формах для сайта, для этого лишь потребуется несколько дополнительных событий onclick.
автор: Dimox | рубрика CSS-верстка | TrackBack
В соответствии со спецификацией, в background-position нельзя сочетать ключевых слова с числовыми значениями.
“One can also use keyword values to indicate the position of the background image. Keywords cannot be combined with percentage values, or length values. The possible combinations of keywords and their interpretations are as follows:”
13 Colors and Backgrounds
Хотя помню, что сам где то так делал))
Спасибо за статью как раз пригодилась для конкретного проекта.
Спасибо за подсказку. Исправил и приму к сведению.
За статью пожалуйста. Рад, что она помогла.
Очень познавательно, однако, я столкнулся с такой проблемой:
при событии onclick выполняется код JavaScript, но не переход по ссылке. Для того чтоб всё работало, я заменил событие onclick на событие onmouseup.
На этой странице кнопка работает, но если скопировать код кнопки в отдельный докумнт, происходит описанное выше. Объясните пожалуйста, что я не так сделал?
sk0t, по сути, ни событие onclick, ни событие onmouseup нам вообще не нужны, поскольку отжима кнопки при клике просто можно не успеть увидеть - в этот момент может загружаться другая страница, все зависит от задержки между кликом по кнопке и началом загрузки данных.
В JavaScript я не силен, но полагаю, что событие onclick поможет в том случае, если кнопку использовать с дополнительным яваскрипт-кодом, и не как ссылку, а именно как кнопку к какой-нибудь форме.
А здесь кнопка работает потому, что она ссылается на эту же страницу и ничего больше не загружает.
Спасибо за разъяснение.
Только у меня ссылка вела на исполняемый файл(HTML-Autorun) и возвращение кнопки в нормальное состояние было для меня актуальным.
Тогда, видимо, вам нужно поступать, как я и говорил - использовать комбинацию onclick, которая в примере, + код ява-скрипта, который бы запускал этот файл.
Отличный сайт, Dimox!
Трудно было оставить комментарий, поскольку картинка с буквами закэшировалась, но очень хотелось похвалить!
Молодец!!!
Спасибо, Сергей, очень приятно!
Сделал для input`ов, но в ИЕ криво работает, т.е. нет при наведении подсветки, не подскажите?, вот что получилось:
использовать так:
DeadLy, ответ прост - IE версии 6.0 и ниже не воспринимает псевдо-класс :hover для всех элементов, кроме тега <a>. Для решения этой проблемы советую прочитать статью CSS:hover для любого элемента.
Dimox, спасибо, но я behavior’ом решил не заморачиватся, решил проблему вот так:
DeadLy, вот и замечательно. Только есть минус в этом варианте - HTML-код не валидный.
когда придумаю полностью валидный код - напишу сюда ))
Dimox, спасибо за статью, очень подробно и по делу! Хотел бы еще добавить вот чего: ие6 при наведении курсора загружает картинку с сервера по-новой - так называемый IE flickering bug. И дело даже не в трафике :), а в том, что на время загрузки картинки фон пропадает. Я сделал так: обернул ссылки в контейнеры (подошли li), которым в качестве фона задал ту же картинку в дефолтном положении. И хоть ие все равно ломится на сервер, мерцания уже не наблюдается.
Пожалуйста, juice.
Ну, ИЕ как всегда отличился :))). Спасибо за информацию, приму к сведению.
Здравствуйте! Огромное спасибо Вам за эту замечательную статью.
CSS только начинаю изучать. поэтому куча вопросов:
Подскажите, а как прижать кнопку в верхний левый угол?
вот мой код:
Еще раз огромное спасибо!
Виктор, я вижу, что по ссылке http://probegauto.ru/new/, которую вы давали, все в порядке. Вопрос еще актуален?
Все в норме. Оказывается в css разрешены отрицательные координаты
top: -10px решили проблему.
Спасибо.
Теперь возник еще один вопрос. Ответ на него будет интересен многим.
Если взять за вариант - изготовление css меню, то какими средствами (видимо JavaScript) подсвечивать выбранный ранее пункт меню?
Представим себе:
Выбираем кнопку меню ГЛАВНАЯ,
загружается Главная страница и кнопка меню ГЛАВНАЯ подсвечивается,
что указывает на факт нахождения именно на странице ГЛАВНАЯ.
Как этого добиться?
Немного сумбурно, но вполне понятно.
Замечательно, что разобрались.
По поводу выделения текущего пункта меню. Во-первых, сначала для него нужно создать отдельный CSS-класс. Во-вторых подставление этого класса к текущему пункту осуществляется либо вручную (если страницы статические), либо, если страницы динамические, средствами движка. Т.е. используется программирование.
С помощью JavaScript, наверное тоже такое возможно, только я не знаю как.
Т.е. вам нужно исходить из того, каким образом создаются страницы.
Поборол я проблему.
Сначала описываем еще один класс:
Теперь еще один вопрос: а как средствами CSS сделать ширину выводимой кнопки фиксированной? Чтобы размер не зависел от количества символов надписи…
Для этого в CSS есть параметр width. Пример:
Данная запись означается, что кнопка будет шириной в 100 пикселей.
Спасибо!
Результат вот здесь: http://www.probegauto.ru/new/lot_new.php?id=1847
По вышеуказанной технологии выполнено меню и кнопка НАЙТИ АВТО.
Получилось отлично!
Пожалуйста. Рад, что у вас все получилось. ;)
Спасибо за статью, нового для себя ничего не узнал, но описано очень четко, акуратно и качественно.
Sergey упоминал о том что картинки закешировалась и он не мог отослать камент - для этого придумали сочетание клавиш Ctrl + R - причем про F5 я уже вообще забыл и практически никогда не использую.
Спасибо, XAMelleOH .
<a href=http://aciddog.nm.ru/button/> чуть логичней и компактнее </a>
Очень хорошая статья! Вот только проблемка с Crystal Button… Можете подсказать, где можно скачать полностью бесплатную версию?
Ну или хотя бы кряк?
Здравствуйте. У меня не работает событие .button:active{} Пробовал запускать и в мозиле и в 7 осле и в опере. Ни в какую. С чем это может быть связано?
Не видя рабочий пример, я не могу ничего сказать.
Прошу прощения. Вот он:
.ButtonEmty
{
width:20px;
height:20px;
background-image:url(’ButtonEmty.png’);
display:block;
text-decoration: none;
}
.ButtonEmty:hover
{
background-position:-20px 0;
}
.ButtonEmty:active
{
background-position:-40px 0;
}
Не вставляется тег а =( В общем в нем прост присваивается класс ButtonEmty
Даже не знаю, в чем причина. Если класс ButtonEmty используется для тега ссылки, то по идее должно бы работать.
Пример не работает только в Сафари, т.к. он не поддерживает теги вложенные внутрь ссылки
У меня вот такая проблема. Я вставил то что вы привели выше и у меня получилось что один рисунок наехал на другой, а при наведении они исчезают. С чем это может быть связанно?
a.button {
display: block;
width: 90px;
float: left; /* чтобы кнопка не растягивалась на всю ширину родительского блока, а ограничивалась текстом */
font: bold 12px arial, sans-serif;
color: #555;
text-decoration: none;
background: url(http://eccentr1c.narod.ru/Untitled.gif) top right no-repeat;
padding-right: 25px; /* отступ для “раздвижных дверей” */
outline: none; /* убираем точечную обводку в FireFox, которая появляется при клике */
}
a.button span {
display: block;
line-height: 13px;
background: url(http://eccentr1c.narod.ru/Untitled1.gif) no-repeat;
padding: 7px 0 13px 23px;
}
Простите. Это тоже вставил. Всёравно абракадабра. http://eccentr1c.narod.ru/test2.html - тут я тестирую этот скрипт.
a.button:hover {
background-position: 100% -33px;
}
a.button:hover span {
background-position: 0% -33px;
color: #222;
}
3cc3ntr1c, потому что у вас неправильно использованы рисунки. Untitled.gif и Untitled1.gif должны быть левой и правой частью одной кнопки, а у вас это 2 разные кнопки.
А кнопки должны обе быть в одном рисунке?
В статье же все видно. Левые части всех состояний кнопок - один рисунок, правые части - другой.
А вот к примеру мне не нужно чтоб кнопки растягивались. Я создал рисунок, но в отличии от вашего они у меня сьезжают. Просто хотелось бы узнать какие именно параметры отвечают за сдвиг рисунка под соответствующуюю кнопку. А у меня получается что виден больший кусок рисунка чем мне нужен… Вообщем как-то так)
Вообщем сделал вот так. При наведении на кнопку картинка сьезжает вниз. Вот как мне сделать как у вас что-б она оставалась на месте? Какой параметр нужно крутить? Да я добавил фиксацию размера кнопок. Может это из-за этого?
a.button {
display: block;
width: 90px;
float: left; /* чтобы кнопка не растягивалась на всю ширину родительского блока, а ограничивалась текстом */
font: bold 14px Taurus, sans-serif;
color: #555;
text-decoration: none;
background: url(http://eccentr1c.narod.ru/but31.gif) top right no-repeat;
padding-right: 25px; /* отступ для “раздвижных дверей” */
outline: none; /* убираем точечную обводку в FireFox, которая появляется при клике */
}
a.button span {
display: block;
line-height: 3px;
background: url(http://eccentr1c.narod.ru/but31.gif) no-repeat;
padding: 7px 0 13px 23px;
}
a.button:hover {
background-position: 100% -30px;
}
a.button:hover span {
background-position: 0% -30px;
color: #222;
}
a.button:active {
background-position: 100% -60px;
}
a.button:active span {
background-position: 0% -60px;
color: #222;
padding: 8px 0 12px 23px; /* опускаем текст на 1px */
}
Надо тогда почитать руководство по CSS, чтобы знать какие параметры за что отвечают.
Простите за назойливость. Вы не подскжите как зафиксировать такую кнопку и для Експлорера? В Опере размер фиксируется, а в Експлорере растягивается или сужается под текст.
Для этого есть параметр width.
Да, это я знаю. И я поставил его в код. Только в Опере кнопки зафиксировались, а в Експлорере увы нет.
Dimox, отличный урок! спасибо.
от себя добавлю:
для IE помимо обработчика события onmouseup следует ещё добавить onMouseOut.
т.к. если зажать и затем разжать мышку вне зоны кнопки (click and drag), стиль active также застопорится. в данном случае, кстати, мы не переходим по ссылке и кнопка остаётся в состоянии active.
PS обработчик onclip в вышеизложенном не нуждается