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

31 мая 2010 г.

Когда при верстке требуется создать меню с разделителем, я использую замечательную технику, которую когда-то давно предложил Юрий “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>, тогда возникают следующие проблемы:

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

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

  2. Первую проблему можно было бы решить, сделав ссылку блочный элементом (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 - это виртуальный выделенный сервер), который, по сравнению с обычным виртуальным хостингом, имеет большие преимущества в плане ресурсов и программной части.

Теги: , , автор: Dimox | рубрика CSS-верстка

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

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

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

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

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

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

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

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

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

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

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

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

  7. Ничего не надумано. Все из собственного опыта.

    можно же просто дать LI фон, содержащий и бордюр, и маркер одновременно

    Нельзя т.к. высота LI может меняться.

    Либо, сделать <a> блочным, дать ему фон-буллет и паддинг слева.

    Я на этот счет вообще-то написал в статье.

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

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

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

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

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

  13. 1) а что мешает меняться высоте LI? Например, задаем фон в видедвух полос сверху и иконки. Иконка сверху и остается, хоть 10 строк напиши. Другое дело ,если изменять расстояние от текста до верхнего края.. тогда полный швах :)

    2) сорри, не заметил. но тексту можно дать паддинг ;-)

    в любом случае спасибо!

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

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

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

  17. Пожалуйста! И тебе очередное спасибо за приятный комментарий ;0)

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

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

  19. Нельзя так сделать, потому что IE вплоть до 8-й версии не поддерживает :last-child.

  20. Действительно, почему то был уверен что если поддерживает first-child то и last-child тоже, оказалось ошибался. Спасибо за информацию :)

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

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

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

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

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

  24. По аналогии можно и горизонтальное сделать.

  25. 26
    Николай
    Николай

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

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

    тогда можно

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

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

Присоединяйтесь к обсуждению!

Отправляя кoммeнтapий, вы автоматически принимаете правила кoммeнтиpoвaния на этом блоге.

Правила кoммeнтиpoвaния на блоге dimox.name:

  1. Первый кoммeнтapий всегда проходит премодерацию.
  2. В поле "URL блога" можно указывать только ссылку на главную страницу вашего блога. Ссылки на прочие веб-ресурсы (в том числе блоги/сплоги, созданные не для людей) будут удалены.
  3. Запрещается использовать в качестве имени комментатора слоганы/названия сайтов, рекламные фразы, ключевые и т.п. слова. В случае несоблюдения этого условия имя изменяется по усмотрению владельца блога. Просьба указывать нормальное имя или ник.
  4. Весьма вероятно, что короткий и неинформативный кoммeнтapий вида "Спасибо!", "Интересная статья", будет удален. Исключение составляют знакомые автору блога комментаторы.
  5. Комментарии не по теме удаляются.

Подписаться, не комментируя
  • Похожие статьи
  • Предыдущие из рубрики