Выпадающее меню на CSS без javascript
Пришло
время рассказать как сделать выпадающее меню на CSS без применения
javascript, да еще чтобы оно работало и правильно отображалось во всех
браузерах. Задача не из простых, но нет ничего невозможного.
Единственные недостатки выпадающего меню без JS в том, что нужно
заранее знать, сколько будет вложенных уровней. Я опишу пример с пятью
уровнями, что должно хватить практически для любого сайта.
Вертикальное выпадающее меню на CSS без применения Javascript.
Меню будет построено на ненумерованных списках, вложенных друг в
друга. Напишем сразу HTML код нашего выпадающего меню (чтобы не
громоздить огромный листинг я сделал выпадающим только второй пункт):
<div class="cssmenu">
<ul>
<li><a href="#">Уровень 1 п 1</a></li>
<li><a href="#">Уровень 1 п 2</a>
<ul>
<li><a href="#">Уровень 2 п 1</a></li>
<li><a href="#">Уровень 2 п 2</a>
<ul>
<li><a href="#">Уровень 3 п 1</a></li>
<li><a href="#">Уровень 3 п 2</a>
<ul>
<li><a href="#">Уровень 4 п 1</a></li>
<li><a href="#">Уровень 4 п 2</a>
<ul>
<li><a href="#">Уровень 5 п 1</a></li>
<li><a href="#">Уровень 5 п 2</a></li>
<li><a href="#">Уровень 5 п 3</a></li>
</ul>
</li>
<li><a href="#">Уровень 4 п 3</a></li>
</ul>
</li>
<li><a href="#">Уровень 3 п 3</a></li>
</ul>
</li>
<li><a href="#">Уровень 2 п 3</a></li>
</ul>
</li>
<li><a href="#">Уровень 1 п 3</a></li>
</ul>
</div>
Чтобы было проще работать со списками, я поместил наше меню в контейнер DIV.
Теперь нам нужно обнулить стили для списков, навести красоту, чтобы
пункты были похожи на кнопки и скрыть вложенные пункты меню. Для этого
напишем стиль:
<style type="text/css">
.cssmenu ul {
/* убираем отступы */
padding: 0;
margin: 0;
/* убираем точки */
list-style: none;
/* задаем ширину */
width: 150px;
/* присвоим относительное позиционирование*/
position:relative;
}
/* зададим стиль для элементов списка */
/* Чтобы меню корректно отображалось в IE */
.cssmenu li {
float: left;
}
/* зададим стиль для анкора в списке */
.cssmenu li a, .cssmenu li a:visited {
/* обязательно блочное отображение */
display: block;
/* ширина строки на 1 пиксель меньше */
width: 149px;
/* зададим высоту строки */
height:25px;
line-height:25px;
/* сделаем отступ в 5 пикселей */
text-indent:5px;
/* сделаем рамку в 1 пиксель */
border: 1px solid #ffffff;
/* уберем одну горизонтальную рамку, чтобы не удваивались */
border-width:0 1px 1px 1px;
/* цвета фона и текста */
color: #FAFAD2;
background-color: #4682B4;
}
/* меняем цвета при наведении */
.cssmenu li a:hover {
color: #4682B4;
background-color: #FAFAD2;
}
/* скрываем вложенные пункты меню */
.cssmenu li ul {
visibility: hidden;
position: absolute;
left: 149px;
top: 0px;
}
</style>
Если Вы читали мою статью о том как сделать простое CSS меню,
Вы наверняка заметили некоторые отличия. Во-первых рамку я сделал с
помощью свойства border, для чего оно и предназначено; Во-вторых, чтобы
сделать отступ, я не стал пользоваться свойством padding, а указал
высоту строки и отступ справа сделал с помощью свойства text-indent.
Почему именно так? Да только для того, чтобы ширина пункта меню была
одинаковой во всех браузерах.
Давайте взглянем, что у нас получилось:
Теперь наша задача заключается в том, чтобы при наведении мышки на
пункт меню, выпадал дочерний список. Для Firefox, Opera, Safari b IE7
эта задача решается предельно просто. Добавляем в стиль следущее:
/* отображаем вложенное меню при наведении мыши */
.cssmenu li:hover {
position: relative;
}
.cssmenu li:hover > ul {
visibility: visible;
}
/* выделяем родительские пункты, при наведении на дочерние */
.cssmenu li:hover > a {
color:#4682B4;
background:#FAFAD2;
}
Поясню, что сделано. Я воспользовался псевдо-классом hover для
элемента LI и указал для него относительное позиционирование, а для
дочернего списка visibility:visible, что собственно и отображает
выпадающее меню. Надо заметить, что если написать .cssmenu li:hover ul
(без знака >), то будут отображены все вложенные
уровни меню, что нам совершенно не нужно. Также я выделил все
родительские ссылки, чтобы было видно весь путь до текущего пункта меню.
Вот что получилось в итоге (должно работать в браузерах Firefox, Opera, Safari и IE7):
Internet Explorer младше 7-ой версии не понимает псевдокласс hover
для элемента LI, поэтому меню и не работает. Заставить меню работать в
этих браузерах можно с помощью javascript, но я обещал, что javascript
не будет использоваться вообще. Поэтому придется прописать отображение
и скрытие вложенных пунктов вручную:
/* Для IE младше 7-ой версии вручную обработаем каждый уровень */
/* скрываем третий и последующие уровни, когда курсор наведен на первый уровень */
.cssmenu ul a:hover ul ul {
visibility:hidden;
}
/* скрываем четвертый и последующие уровни, когда курсор наведен на второй уровень */
.cssmenu ul a:hover ul a:hover ul ul {
visibility:hidden;
}
/* скрываем пятый уровень, когда курсор наведен на третий уровень */
.cssmenu ul a:hover ul a:hover ul a:hover ul ul{
visibility:hidden;
}
/* показываем второй уровень, при наведении на первый */
.cssmenu ul a:hover ul {
visibility:visible;
}
/* показываем третий уровень, при наведении на второй */
.cssmenu ul a:hover ul a:hover ul{
visibility:visible;
}
/* показываем четвертый уровень, при наведении на третий */
.cssmenu ul a:hover ul a:hover ul a:hover ul {
visibility:visible;
}
/* показываем пятый уровень, при наведении на четвертый */
.cssmenu ul a:hover ul a:hover ul a:hover ul a:hover ul {
visibility:visible;
}
Но ведь вложенные пункты меню у нас находятся не внутри тега
<a>, а после него, а значит дочерние пункты меню отображены не
будут. Значит нам нужно поместить дочерние списки внутрь тега
<a>. Чтобы решить эту задачу с отображением выпадающего меню в
браузерах Internet Explorer младше 7-ой версии, нам придется прибегнуть
к условным коментариям и таблицам. Там где должно быть дочернее меню,
вместо закрывающего тега </a> мы напишем вот что:
<!--[if IE
7]><!--></a><!--<![endif]--><!--[if lte IE
6]><table><tr><td><![endif]-->
А после дочернего списка добавим следующий код:
<!--[if lte IE 6]></td></tr></table></a><![endif]-->
У нас должен получиться следующий HTML код:
<div class="cssmenu">
<ul>
<li><a href="#">Уровень 1 п 1</a></li>
<li><a href="#">Уровень 1 п 2<!--[if IE
7]><!--></a><!--<![endif]--><!--[if lte IE
6]><table><tr><td><![endif]-->
<ul>
<li><a href="#">Уровень 2 п 1</a></li>
<li><a
href="#">Уровень 2 п 2<!--[if IE
7]><!--></a><!--<![endif]--><!--[if lte IE
6]><table><tr><td><![endif]-->
<ul>
<li><a href="#">Уровень 3 п 1</a></li>
<li><a href="#">Уровень 3 п 2<!--[if IE
7]><!--></a><!--<![endif]--><!--[if lte IE
6]><table><tr><td><![endif]-->
<ul>
<li><a href="#">Уровень 4 п 1</a></li>
<li><a href="#">Уровень 4 п 2<!--[if IE
7]><!--></a><!--<![endif]--><!--[if lte IE
6]><table><tr><td><![endif]-->
<ul>
<li><a href="#">Уровень 5 п 1</a></li>
<li><a href="#">Уровень 5 п 2</a></li>
<li><a href="#">Уровень 5 п 3</a></li>
</ul>
<!--[if lte IE
6]></td></tr></table></a><![endif]-->
</li>
<li><a href="#">Уровень 4 п 3</a></li>
</ul>
<!--[if lte IE
6]></td></tr></table></a><![endif]-->
</li>
<li><a href="#">Уровень 3 п 3</a></li>
</ul>
<!--[if lte IE
6]></td></tr></table></a><![endif]-->
</li>
<li><a href="#">Уровень 2 п 3</a></li>
</ul>
<!--[if lte IE 6]></td></tr></table></a><![endif]-->
</li>
<li><a href="#">Уровень 1 п 3</a></li>
</ul>
</div>
Остается только добавить стиль для таблицы и для ссылок при наведении:
.cssmenu table {
position:absolute;
border-collapse:collapse;
top:0;
left:0;
z-index:100;
font-size:1em;
}
/* напишем стиль ссылок при наведении для IE младше 7-ого */
* html .cssmenu a:hover {
color:#4682B4;
background:#FAFAD2;
/* обязательно нужно указать относительное позиционирование */
position:relative;
}
К сожалению визуальный редактор моего сайта не позволяет написать
код такой конструкции и дописывает в него ненужные теги. Поэтому я
выложил страничку с реализованным выпадающем меню отдельно. Смотрим
пример вертикального меню на CSS, который работает во всех браузерах
без применения javascript: Вертикальное меню на CSS без Javascript.
Это меню работает и абсолютно одинаково отображается в браузерах FF,
Opera, IE7, IE6, Safari. Для эксплорера младше 6-ого, возможно придется
по-химичить со стилем, чтобы правильно отобразить ширину пункта. Я
специально не стал исправлять отображение в IE 5.5, в надежде на то,
что им уже мало кто пользуется.
|