CSS-трюк: двойные бордюры-разделители вертикального меню
Когда при верстке требуется создать меню с разделителем, я использую замечательную технику, которую когда-то давно предложил Юрий “akella” Артюх.
Недавно я столкнулся с очень похожей, но более сложной задачей - мне нужно было сверстать вертикальное меню, разделителем которого является двойная линия, состоящая из двух разных цветов (синий и белый):

Возможные способы решения задачи:
- использовать изображение;
- использовать только CSS.
В решении необходимо предусмотреть, что:
- высота пункта списка может меняться, т.е. текст может быть в несколько строк;
- часть текста может быть за пределами тега ссылки.
Проблемы при использовании изображения
Объясню, почему решение в виде использования изображения в качестве бордюра не подходит в данном случае.
Структура HTML-кода нашего меню максимально проста:
1 2 3 4 5 6 7 8 9 | <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>, тогда возникают следующие проблемы:
-
Если в меню появится многострочный пункт, тогда меню станет некрасивым (не хватает одинакового отступа слева у текста в каждой строке):

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

Решение с помощью CSS
Мое решение с использованием чистого CSS позволяет избежать вышеописанных проблем.
CSS-код будет выглядеть нижеследующим образом. Основные для нашей задачи стили я прокомментирую:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 - это виртуальный выделенный сервер), который, по сравнению с обычным виртуальным хостингом, имеет большие преимущества в плане ресурсов и программной части.
Отличное решение! Менюшка получается очень красивой.
“Море решение с использованием чистого CSS ” - опечаточка по Фрейду :) Пора в отпуск )))
Попробуй сипользовать display:inline-block, тогда переносов не будет. + для списка можно было попробовать list-style-image.
Так тож ниче, но придется возиться с первым или последним элементом, если вокруг списка не будет бордера.
Спасибо большое … техника супер!!!
Однозначно пост в закладки. Не обходиться верстка не одного сайта без заглядывание на твой сайт за полезной инфой.
Решение хорошее, но описанная вначале проблема надумана - можно же просто дать LI фон, содержащий и бордюр, и маркер одновременно. Либо, сделать <a> блочным, дать ему фон-буллет и паддинг слева.
Спасибо, исправил.
Не подходит. Тогда опять получится без отступа, если текст будет в несколько строк и одновременно часть текста будет находится вне ссылки.
Не придется. Этот бордюр лишь для красоты, он ни на что не влияет.
Спасибо! ;0)
Ничего не надумано. Все из собственного опыта.
Нельзя т.к. высота LI может меняться.
Я на этот счет вообще-то написал в статье.
Спасибо за хороший совет Dimox. Как же всё элементарно просто :)
Прикольно… Можно так же сделать для горизонтального меню… Я давно хотел поискать нечто подобное, но так и не собрался с мыслями…
Симпатичненько получается, респект!
Круто вообще! Офигенное решение!
Я и не предполагал что этого ни кто не знает, использую такую методику в верстке сколько себя помню :)
1) а что мешает меняться высоте LI? Например, задаем фон в видедвух полос сверху и иконки. Иконка сверху и остается, хоть 10 строк напиши. Другое дело ,если изменять расстояние от текста до верхнего края.. тогда полный швах :)
2) сорри, не заметил. но тексту можно дать паддинг ;-)
в любом случае спасибо!
Тоже делал такое меню, статья помогла.
Интересное решение. Спасибо.
Читал статью давно, щас верстал и вспомнил трюк, оч. пригодился. Решил поблагодарить, собственно к чему плавно и перехожу: Спасибо!!!
За что я и уважаю этот блог - просто, коротко, полезно :)
Пожалуйста! И тебе очередное спасибо за приятный комментарий ;0)
Думаю правильнее будет использовать селекторы :first-child и :last-child (если вы не поклонник ИЕ6)
li:first-child {
border-top: none;
}
li:last-child {
border-bottom: none;
}
Нельзя так сделать, потому что IE вплоть до 8-й версии не поддерживает :last-child.
Действительно, почему то был уверен что если поддерживает first-child то и last-child тоже, оказалось ошибался. Спасибо за информацию :)
Большое спасибо!!!! Даже при том что я только 3-й день учу html, у меня уже вышла такая менюшка!!!)))) ВаУ!!!!!
минус:
если необходимо будет сделать фон для li не прозрачным по всей ширине, то ваш трюк не проходит
плюс:
интересное решение :)
я пользовался обрамляющим div’ом, чтобы он “съедал” первый и последний бордер
Спасибо будем пробовать проверять. Недавно только начал заниматься html+css интересно будет попробовать… а горизонтально возможно их сделать?
По аналогии можно и горизонтальное сделать.
Иногда придирчивые заказчики требуют чтобы маркер тоже был ссылкой или чтобы он менялся при наведении. Я всё же придерживаюсь вариантов когда маркер является фоном ссылки. Проблему с переносом, так же как и описано, решаю с помощью display:block, с если есть ещё текст так никто не мешает заключить его в span например.
тогда можно
2
3
4
5
6
7
8
9
display:block
}
li a {
background: url(bullet.gif) 4px 8px no-repeat;
}
li a:hover {
background: url(bullet2.gif) 4px 8px no-repeat;
}
хороший трюк
переделал под себя и получилось офигенно
Огромное спасибо за статью! Действительно проблема решается просто и красиво :), а самое главное кроссбраузерно…