Создание универсальных графических кнопок с помощью CSS

Вольный перевод статьи «Creating bulletproof graphic link buttons with CSS» (мои комментарии — курсивом).

Проблема в CSS, с которой я боролся в последнее время, — как создать универсальную графическую кнопку. Имеется в виду кнопка с использованием изображения, которая расширяется и сужается в зависимости от количества текста, который она содержит. Такая методика будет очень полезна для CMS-сайтов, которые позволяют клиенту изменять текст, отображаемый на кнопках, а также для многоязычных сайтов.

Эта кнопка должна:

  • Автоматически растягиваться горизонтально, чтобы вместить любое количество текста.
  • Растягиваться горизонтально и вертикально, если объем текста увеличен или если текст разделен на несколько строк.
  • Иметь размер в разумных пределах.
  • Позволять изменять углы на круглые или другие неквадратные.
  • Иметь всю площадь кнопки кликабельной.
  • Быть удобочитаемой при отключенных изображениях.

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

Стоит отметить, что описанную ниже методику не следует использовать бессмысленно, заменяя реальные кнопки формы.

Реальная кнопка формы (обычно <input type="submit">), работает одинаково хорошо без CSS и JavaScript. Однако, оформленная ссылка для сабмита формы может использовать JavaScript. А последний, как известно, не всегда бывает доступным, поэтому нужно принимать сие обстоятельство во внимание.

Проблемы, как это обычно бывает при работе с CSS, исходят от Internet Explorer. Первая заключается в том, что IE неправильно определяет ширину блочных элементов внутри «плавающих» элементов (имеющих свойство «float»), которым не задана ширина.

Когда для «плавающего» элемента не указана ширина, браузер должен скорректировать ширину элемента с учетом его содержания. В случае с нашей кнопкой-ссылкой данное свойство как раз бы пригодилось, поскольку это заставит ссылку автоматически корректировать ширину в зависимости от количества текста, который она содержит. К сожалению, Internet Explorer не будет должным образом отображать следующую комбинацию HTML и CSS.

<div class="cb">
 <div class="bt"><div></div></div>
 <div class="i1"><div class="i2"><a href="#" class="i3">A box</a></div></div>
 <div class="bb"><div></div></div>
</div>

Когда «плавающему» блоку div.cb не задана ширина, он будет растянут с учетом его содержания. Ширина зависит от содержимого элемента div.i1, и эта часть прекрасно работает. Проблема заключена в элементах div.bt и div.bb, которые не растягиваются на ту же ширину, что и div.i1. Ее можно было бы обойти, задав ширину элементу div.cb, но нам нужно получить растягивающуюся кнопку, поэтому пришлось искать другое решение.

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

Действительно, мне тоже не раз приходилось сталкиваться с этим багом в Internet Explorer (до 7-й версии), когда при изменении размера окна браузера появляется отступ в 1px, что сразу же бросается в глаза. Наблюдается это как раз в случаях с абсолютным позиционированием.

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

<a class="button" href="#">
 <span>
 <span>
 <span>
 <span>Кнопка-ссылка на CSS!</span>
 </span>
 </span>
 </span>
</a>

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

И конечно нам нужно немного CSS, чтобы сделать наши кнопки привлекательными:

button { /* верхний левый угол, верхняя граница */
 float: left;
 color: #DDD; /* цвет текста */
 background: #333 url(button.gif) no-repeat; /* цвет фона при отключенных изображениях */
 font: 1.2em/1.0 Georgia,serif;
 text-decoration: none;
}
.button * {display:block;}
.button span { /* верхний правый угол */
 padding: 6px 0 0;
 background: url(corners.gif) no-repeat right top;
}
.button span span { /* нижний левый угол, левая и нижняя границы */
 padding: 0 0 0 6px;
 background: url(button.gif) no-repeat left bottom;
}
.button span span span { /* нижний правый угол */
 padding: 0 0 6px;
 background: url(corners.gif) no-repeat right bottom;
}
.button span span span span { /* правая граница */
 padding: 3px 12px 3px 6px; /* отступы от текста */
 background: url(button.gif) no-repeat right center;
}
.button:hover,
.button:focus,
.button:active { /* подсказка для клавиатуры */
 outline: 2px solid #ff0; /* не поддерживается в IE/Win */
 color: #FFF;
}

Можно посмотреть несколько готовых примеров кнопок-ссылок.

Безусловно, в приведенном решении вместо тэга span можно использовать более короткий тэг, например b, тогда и HTML-код, и CSS-код станет компактнее и симпатичнее.

Идеально вид кнопок был бы достигнут при использовании только одного фонового изображения, что и было моей первоначальной целью. Я не сумел достигнуть этой цели и вынужден прибегать к использованию двух изображений (button.gif и corners.gif). Если Вы на них посмотрите, то заметите, что их размер гораздо больше, чем любая кнопка, которая получается в итоге, так как изображения определяют максимальный размер кнопки.

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

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

Готово. Получилась удобная, растяжимая, кликабельная графическая кнопка.

* * *

Работай и зарабатывай на рынке Форекс вместе с компанией FOREX MMCIS group, надежным дилинговым центром мирового уровня. В этом Форекс брокере для вас созданы лучшие условия.

Комментарии (18)
  1. 1

    СУПЕР! СSS — вещь!

  2. 2

    Согласен. CSS позволяет создавать удивительные штуки ;).

  3. 3
    Александр

    Где можна скачать (button.gif и corners.gif) ?

  4. 5
    Александр

    Спасибо

  5. 6

    Пожалуйста. Юзайте на здоровье ;).

  6. 7
    Александр

    Вы пробовали реализовать эффект hover c этими картинками.
    Тут вот какая проблема кроется я думал сделать картинку в ней два положения обычное и при наведении и потом через background-position менять, но вот как это сделать если у нас такое количество , как отрегулировать чтобы все стало на свои места.

  7. 8

    Сходу сложно сказать, здесь нужно экспериментировать. Но, мне кажется, данный способ не совсем подходящий, т.к. используются многократно вложенные span’ы. В Вашем случае больше подходит вариант, описанный в статье «Создаем динамические кнопочки-ссылки с помощью CSS«. Вы его не пробовали?

  8. 9
    Splash

    Я вообще span’ы никогда не использую, но статья дельная!

  9. 10

    [quote post=»39″]Я вообще span’ы никогда не использую[/quote]
    что плохого в контейнере inline-типа?

    Хм, а вообще чтоб так страшно конструкция не смотрелась, если кнопки будет иметь фиксированную высоту, можно обойтись одним span’ом или любым другим inline-контейнером (em, strong, b, i и т.д.) Пример можно посмотреть в одной из моей работе http://vlg-nav.ru (верхнее меню). принцип тот же что и в этой статье, только гораздо проще сделано из-за фиксированной высоты кнопки… (для IE в отдельном файле стилей для ссылок установлено свойство float:left;)

  10. 11
    Дрон

    Отличная статья

  11. 12
    ktunes

    Спасибо!очень полезная статья.

  12. 13
    ktunes

    воспользовался вашей статьёй и с помощью кода разместил в меню сайта кнопки по горизонтали,всё отлично работает.но я уже замучался с вопрос,как эти кнопки расположить по центру страницы???
    у вас тэг стоит float:,но в нём нельзя прописать center.
    пробовал margin прописать с отсутпами прав/лево,но снова же не то…
    как можно ещё выровнять кнопки???
    p/s/ все значения ставлю после .button

    заранее спасибо!

    • 14

      Этот вопрос решается очень просто. У .button поменяйте свойство float: left на display: inline-block. После этого код кнопки поместите в <div>, которому задайте свойство text-align: center.

  13. 15
    ktunes

    Спасибо огромное!всё работает)

  14. 16
    ktunes

    может тогда ещё подскажете,как на основе выше описанного урока сделать эти кнопки,как здесь:http://shaybakova.com/lessons/menu_button/menu4.html ???

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

    заранее спасибо!

    • 17

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

  15. 18
    Vasya

    Респект, очень круто!