Главная CSS-верстка

CSS-трюк: двойные бордюры-разделители вертикального меню

Когда при верстке требуется создать меню с разделителем, я использую замечательную технику, которую когда-то давно предложил Юрий «akella» Артюх.

Недавно я столкнулся с очень похожей, но более сложной задачей — мне нужно было сверстать вертикальное меню, разделителем которого является двойная линия, состоящая из двух разных цветов (синий и белый):

Вертикальное меню с двойным разделителем-бордюром

Возможные способы решения задачи:

  • использовать изображение;
  • использовать только CSS.

В решении необходимо предусмотреть, что:

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

Проблемы при использовании изображения

Объясню, почему решение в виде использования изображения в качестве бордюра не подходит в данном случае.

Структура HTML-кода нашего меню максимально проста:

<ul>
	<li><a href="#">Главная</a></li>
	<li><a href="#">О компании</a></li>
	<li><a href="#">Статьи</a></li>
	<li><a href="#">Отзывы</a></li>
	<li><a href="#">Фотографии</a></li>
	<li><a href="#">Вопросы</a></li>
	<li><a href="#">Контакты</a></li>
</ul>

По идее, используя технику Юры Артюха, можно было бы разделитель сделать изображением и поставить его фоном к элементу <li>. Но дело в том, что в списке у каждого пункта еще используется изображение-маркер, и если это изображение ставить фоном тега <a>, тогда возникают следующие проблемы:

  1. Если в меню появится многострочный пункт, тогда меню станет некрасивым (не хватает одинакового отступа слева у текста в каждой строке):

    Некрасивое меню

  2. Первую проблему можно было бы решить, сделав ссылку блочный элементом (a {display:block}), однако при этом возникнет другая проблема — если после ссылки добавить текст, то он перенесется на новую строку, а этого также необходимо избежать:

    Некрасивое меню

Решение с помощью CSS

Мое решение с использованием чистого CSS позволяет избежать вышеописанных проблем.

CSS-код будет выглядеть нижеследующим образом. Основные для нашей задачи стили я прокомментирую:

ul {
	width: 150px;
	padding: 0 6px;
	background: #F2F7FD url(bg.gif) 0 100% repeat-x;
  border: 1px solid #C0D7FB;
  font-weight: bold;

	overflow: hidden; /* необходимо для того, чтобы
	спрятать верхний бордюр у первого пункта и
	нижний бордюр у последнего пункта */
}
li {
	list-style: none;
  background: url(bullet.gif) 4px 8px no-repeat;
	padding: 5px 0 8px 22px;

  border-top: 1px solid #C0D7FB; /* синяя линия */
  border-bottom: 1px solid #FFF; /* белая линия */
  margin: -1px 0 -2px; /* "нахлестываем" на предыдущий и следующий пункт,
	в результате чего и достигается нужный эффект */
	height: 1%; /* для устранения бага в IE6 и IE7 */
}

Для наглядности вы можете посмотреть на живой пример.

Вот, собственно, и все. Решение кроссбраузерное, надеюсь, кому-нибудь пригодится.

* * *

Для качественного сайта с большой аудиторией лучше использовать VPS хостинг (VPS или VDS — это виртуальный выделенный сервер), который, по сравнению с обычным виртуальным хостингом, имеет большие преимущества в плане ресурсов и программной части.

Комментарии (28)

  1. Отличное решение! Менюшка получается очень красивой.

  2. Однозначно пост в закладки. Не обходиться верстка не одного сайта без заглядывание на твой сайт за полезной инфой.

  3. «Море решение с использованием чистого CSS «- опечаточка по Фрейду :) Пора в отпуск)))
    Попробуй сипользовать display: inline-block, тогда переносов не будет. + для списка можно было попробовать list-style-image.
    Так тож ниче, но придется возиться с первым или последним элементом, если вокруг списка не будет бордера.

    • «Море решение с использованием чистого CSS «- опечаточка по Фрейду :) Пора в отпуск)))

      Спасибо, исправил.

      Попробуй сипользовать display: inline-block

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

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

      Не придется. Этот бордюр лишь для красоты, он ни на что не влияет.

  4. Спасибо большое … техника супер!!!

  5. Решение хорошее, но описанная вначале проблема надумана — можно же просто дать LI фон, содержащий и бордюр, и маркер одновременно. Либо, сделать блочным, дать ему фон-буллет и паддинг слева.

  6. Спасибо за хороший совет Dimox. Как же всё элементарно просто :)

  7. Прикольно… Можно так же сделать для горизонтального меню… Я давно хотел поискать нечто подобное, но так и не собрался с мыслями…

  8. Симпатичненько получается, респект!

  9. Круто вообще! Офигенное решение!

  10. Я и не предполагал что этого ни кто не знает, использую такую методику в верстке сколько себя помню :)

  11. Тоже делал такое меню, статья помогла.

  12. Интересное решение. Спасибо.

  13. Читал статью давно, щас верстал и вспомнил трюк, оч. пригодился. Решил поблагодарить, собственно к чему плавно и перехожу: Спасибо!!!
    За что я и уважаю этот блог — просто, коротко, полезно :)

  14. Думаю правильнее будет использовать селекторы: first-child и: last-child (если вы не поклонник ИЕ6)

    li: first-child {
    border-top: none;
    }
    li: last-child {
    border-bottom: none;
    }

  15. Большое спасибо!!! Даже при том что я только 3-й день учу html, у меня уже вышла такая менюшка!!!)))) ВаУ!!!

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

    плюс:
    интересное решение :)

    я пользовался обрамляющим div’ом, чтобы он «съедал» первый и последний бордер

  17. Спасибо будем пробовать проверять. Недавно только начал заниматься html+css интересно будет попробовать… а горизонтально возможно их сделать?

  18. Иногда придирчивые заказчики требуют чтобы маркер тоже был ссылкой или чтобы он менялся при наведении. Я всё же придерживаюсь вариантов когда маркер является фоном ссылки. Проблему с переносом, так же как и описано, решаю с помощью display: block, с если есть ещё текст так никто не мешает заключить его в span например.

    <li><a href="#">О компании <span>некоторый текст</span></a></li>
    

    тогда можно

    span {
    display:block
    }
    li a {
    background: url(bullet.gif) 4px 8px no-repeat;
    }
    li a:hover {
    background: url(bullet2.gif) 4px 8px no-repeat;
    }
    
  19. хороший трюк
    переделал под себя и получилось офигенно

  20. Огромное спасибо за статью! Действительно проблема решается просто и красиво :), а самое главное кроссбраузерно…