Выпадающее меню средствами только CSS

Вместо краткого введения

Довольно часто мне требуется ставить на сайты вертикальное меню. И, иногда, заказчики просят сделать так, чтобы подменю раскрывалось не как подпункт, а раскрывалось отдельным блоком правее основного меню, его подменю еще правее и так далее…

Я долго искал решения в интернете, но почему то вертикальные выпадающие меню не такие уж популярные, чего не скажешь о горизонтальных, который хоть «пятой точкой» ешь.

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

Что мне больше всего нравится именно в этой реализации, так это то, что она не требует ни каких JS скриптов. Все реализуется на чистом CSS. Это конечно влечет за собой некоторые недостатки, самый мой нелюбимый из которых это то, что если навести на последний видимый на экране пункт меню, то подменю выпадает уже за экран. Это конечно не смертельно, ведь можно прокрутить экран колесиком, но часть потенциальных клиентов от этого все равно будет теряться. Лечится это подключением JS, но это уже совсем другая история…

К делу

Шаг №1. Сверстать обычное вертикальное меню.

HTML макет у нас будет абсолютно стандартным (ну по крайней мере большинство делает вертикальное меню именно так). А именно, это будет маркированный список, в  каждом пункте которого может быть еще один маркированный список и так далее:

Так выглядит HTML:

<html>
    <head>
        <title>Пример</title>
    </head>
    <body>
        <ul id="sample-menu"><li ><a href="#">Пункт 1</a></li>
            <li><a href="#">Пункт 2</a>
                <ul>
                    <li><a href="#">Подпункт1</a></li>
                    <li><a href="#">Подпункт2</a></li>
                </ul>
            </li>
            <li><a href="#">Пункт 3</a>
                <ul>
                    <li><a href="#">Подпункт1</a></li>
                    <li><a href="#">Подпункт2</a>
                        <ul>
                            <li><a href="#">Под-подпункт1</a></li>
                            <li><a href="#">Под-подпункт2</a></li>
                            <li><a href="#">Под-подпункт3</a></li>
                            <li><a href="#">Под-подпункт4</a></li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul>
    </body>
</html>

А вот так CSS:

#sample-menu {
  margin: 0 0 35px 0;
  padding: 0;
  list-style: none;
  background: #fff;
  width: 200px;
}

#sample-menu li {
  min-height: 25px;
  border-bottom: 1px solid #aaa;
  background: #fff;
  padding: 0;
  margin: 0;
}

#sample-menu li ul {
  padding: 0;
  margin: 0 0 0 10px;
}

#sample-menu a {
  color: #000;
  text-decoration: none;
  display: block;
  padding: 7px 5px;
}

#sample-menu a:hover {
  background-color: #e6e6e6;
}

Получается как то так:

Шаг2. Допилить стили

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

Для этого мы немного дополним уже написанные CSS стили, а так же добавим несколько новых:

#sample-menu {
  margin: 0 0 35px 0;
  padding: 0;
  list-style: none;
  background: #fff;
  width: 200px;
}

#sample-menu li {
  min-height: 25px;
  border-bottom: 1px solid #aaa;
  position: relative;
  background: #fff;
}

#sample-menu a {
  color: #000;
  text-decoration: none;
  display: block;
  padding: 7px 5px;
}

#sample-menu a:hover {
  background-color: #e6e6e6;
}

#sample-menu ul {
  z-index: 10;
}

#sample-menu li ul {
  font-size: 8pt;
  display: none;
  position: absolute;
  top: 10px;
  left: 190px;
  width: 200px;
  background: #fff;
  border: 1px solid #aaa;
  padding: 0;
  margin: 0;
}

#sample-menu li ul.open,
#sample-menu li:hover ul.open {
  display: block;
  position: relative;
  top: 0;
  left: 0;
  margin-left: 10px;
}

#sample-menu li:hover ul {
  display: inherit;
  z-index: 30;
}

#sample-menu li ul li {
  padding: 0 10px;
  border-bottom: 1px solid #aaa;
}

#sample-menu li:hover ul ul {
  display: none;
}

#sample-menu li:hover ul li:hover ul {
  display: inherit;
}

#sample-menu li ul.open li:hover ul {
  z-index: 50;
}

В итоге мы получаем вертикальное меню, приемлемого качества:

Напоследок хочу заметить, что этот CSS написан для 3-х уровневого вертикального меню. Если в вашем меню более глубокая вложенность, то вам нужно будет дополнить CSS по примеру 3х последних строк моего CSS, т.к. если забыть расставить z-index’ы, то ваши пользователи могут столкнуться с неприятной проблемой, когда раскрытое подменю будет перекрывать собой выпадающее.

Теги: CSS, CSS/html, HTML, vertical menu, Web-programing

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