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>
, тогда возникают следующие проблемы:
Если в меню появится многострочный пункт, тогда меню станет некрасивым (не хватает одинакового отступа слева у текста в каждой строке):
Первую проблему можно было бы решить, сделав ссылку блочный элементом (
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)
Отличное решение! Менюшка получается очень красивой.
Однозначно пост в закладки. Не обходиться верстка не одного сайта без заглядывание на твой сайт за полезной инфой.
Спасибо! ;0)
“Море решение с использованием чистого CSS ” – опечаточка по Фрейду :) Пора в отпуск )))
Попробуй сипользовать display:inline-block, тогда переносов не будет. + для списка можно было попробовать list-style-image.
Так тож ниче, но придется возиться с первым или последним элементом, если вокруг списка не будет бордера.
Спасибо, исправил.
Не подходит. Тогда опять получится без отступа, если текст будет в несколько строк и одновременно часть текста будет находится вне ссылки.
Не придется. Этот бордюр лишь для красоты, он ни на что не влияет.
Спасибо большое … техника супер!!!
Решение хорошее, но описанная вначале проблема надумана – можно же просто дать LI фон, содержащий и бордюр, и маркер одновременно. Либо, сделать блочным, дать ему фон-буллет и паддинг слева.
Ничего не надумано. Все из собственного опыта.
Нельзя т.к. высота LI может меняться.
Я на этот счет вообще-то написал в статье.
1) а что мешает меняться высоте LI? Например, задаем фон в видедвух полос сверху и иконки. Иконка сверху и остается, хоть 10 строк напиши. Другое дело ,если изменять расстояние от текста до верхнего края.. тогда полный швах :)
2) сорри, не заметил. но тексту можно дать паддинг ;-)
в любом случае спасибо!
Спасибо за хороший совет Dimox. Как же всё элементарно просто :)
Прикольно… Можно так же сделать для горизонтального меню… Я давно хотел поискать нечто подобное, но так и не собрался с мыслями…
Симпатичненько получается, респект!
Круто вообще! Офигенное решение!
Я и не предполагал что этого ни кто не знает, использую такую методику в верстке сколько себя помню :)
Тоже делал такое меню, статья помогла.
Интересное решение. Спасибо.
Читал статью давно, щас верстал и вспомнил трюк, оч. пригодился. Решил поблагодарить, собственно к чему плавно и перехожу: Спасибо!!!
За что я и уважаю этот блог – просто, коротко, полезно :)
Пожалуйста! И тебе очередное спасибо за приятный комментарий ;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 например.
тогда можно
хороший трюк
переделал под себя и получилось офигенно
Огромное спасибо за статью! Действительно проблема решается просто и красиво :), а самое главное кроссбраузерно…