Создаем выпадающее меню CSS

В сегодняшней статье я хотел бы рассказать, как создать на CSS2.1 и HTML выпадающее меню. Также я покажу один небольшой трюк, при помощи которого можно будет добавлять иконку «+» к элементам навигации в том случае, если в них скрыто выпадающее меню. Для этого мы воспользуемся псевдоэлементом :only-child.

Исходный код
Демо

Для начала мы создадим базовую структуру навигационного меню, состоящего из шести пунктов:

<nav>
			    <ul>
			        <li><a href="#">Home</a></li>
			        <li><a href="#">WordPress</a></li>
			        <li><a href="#">Graphic Design</a></li>
			        <li><a href="#">Inspiration</a></li>
			        <li><a href="#">Contact</a></li>
			        <li><a href="#">About</a></li>
			    </ul>
			</nav>

Далее нам нужно добавить базовые CSS-стили для HTML горизонтального меню. Я оставил комментарии к каждому блоку кода:

/* задаем цвет фона для контейнера nav. */
			nav {
			    margin: 100px 0;
			    background-color: #E64A19;
			}
			
			/* убираем отступы и поля, а также list-style для "ul", 
			 * и добавляем "position:relative" */
			nav ul {
			    padding:0;
			    margin:0;
			    list-style: none;
			    position: relative;
			    }
			
			/* применяем inline-block позиционирование к элементам навигации */
			nav ul li {
			    margin: 0px -7px 0 0;
			    display:inline-block;
			    background-color: #E64A19;
			    }
			
			/* стилизуем ссылки */
			nav a {
			    display:block;
			    padding:0 10px;
			    color:#FFF;
			    font-size:20px;
			    line-height: 60px;
			    text-decoration:none;
			}
			
			/* изменяем цвет фона при наведении курсора */
			nav a:hover {
			    background-color: #000000;
		}

После применения стилей у нас должно получиться нечто вроде этого:

Чтобы добавить выпадающий список к какому-либо из элементов HTML меню, нам нужно добавить <ul> внутрь элемента <li> для пункта, в котором нужно скрыть выпадающий список:

<nav>
			    <ul>
			        <li><a href="#">Home</a></li>
			        <li><a href="#">WordPress</a>
			
			            <!-- первый уровень выпадающего списка -->
			            <ul>
			                <li><a href="#">Themes</a></li>
			                <li><a href="#">Plugins</a></li>
			                <li><a href="#">Tutorials</a></li>
			            </ul>
			
			        </li>
			        <li><a href="#">Graphic Design</a></li>
			        <li><a href="#">Inspiration</a></li>
			        <li><a href="#">Contact</a></li>
			        <li><a href="#">About</a></li>
			    </ul>
		</nav>

Мы добавили новый неупорядоченный список с тремя пунктами списка внутрь второго элемента <li>, который отвечает за пункт меню WordPress. Обратите внимание на то, что мы добавили <ul> после анкорного тега (<a>).

Теперь добавим CSS-стили, чтобы выпадающий список был скрыт по умолчанию, и появлялся, когда посетитель наводит курсор мыши на соответствующий родительский элемент HTML меню для сайта. После приведенного выше CSS-кода добавьте следующий фрагмент:

/* скрываем выпадающие списки по умолчанию
			 * и задаем абсолютное позиционирование */
			nav ul ul {
			    display: none;
			    position: absolute;
			    top: 100%;
			}
			
			/* отображаем выпадающий список при наведении */
			nav ul li:hover > ul {
			    display:inherit;
			}
			
			/* первый уровень выпадающего списка */
			nav ul ul li {
			    min-width:170px;
			    float:none;
			    display:list-item;
			    position: relative;
			}

Если до этого момента вы все делали правильно, то при наведении курсора на пункт меню «WordPress» должны увидеть выпадающий список с тремя другими пунктами («Themes», «Plugins», «Tutorials»):

Чтобы добавить выпадающие списки, состоящие из нескольких уровней, этот процесс нужно повторить. Определяем пункт меню, из которого нужно сделать выпадающий список, и добавляем новый <ul> между тегами <li></li>.

Взгляните на приведенный ниже HTML-код, в котором мы добавляем второй уровень выпадающего списка к пункту меню «Tutorial», который находится внутри пункта «WordPress»:

<nav>
			    <ul>
			        <li><a href="#">Home</a></li>
			        <li><a href="#">WordPress</a>
			
			            <!-- первый уровень выпадающего списка -->
			            <ul>
			                <li><a href="#">Themes</a></li>
			                <li><a href="#">Plugins</a></li>
			                <li><a href="#">Tutorials</a>
			
			                    <!-- второй уровень выпадающего списка -->
			                    <ul>
			                        <li><a href="#">Stuff</a></li>
			                        <li><a href="#">Things</a></li>
			                        <li><a href="#">Other Stuff</a></li>
			                    </ul>
			                    <!—конец второго уровня выпадающего списка -->
			
			                </li>
			            </ul>
			            <!—конец первого уровня выпадающего списка -->
			
			        </li>
			        <li><a href="#">Graphic Design</a></li>
			        <li><a href="#">Inspiration</a></li>
			        <li><a href="#">Contact</a></li>
			        <li><a href="#">About</a></li>
			    </ul>
		</nav>

Чтобы вертикальное меню HTML отображалось корректно, нужно добавить еще пару строк CSS кода:

/* второй, третий и последующие уровни 
			 * смещаем 2 и 3 уровни влево 
			 * на значение длины первого уровня.
			*/
			nav ul ul ul {
			    position: absolute;
			    top:0;
			    left:100%;
		}

Если все сделано правильно, у вас должно получиться нечто вроде этого:

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

Добавляем индикатор выпадающего списка

Перед тем, как сделать выпадающее меню в HTML до конца, разберемся с индикатором, который указывает на наличие выпадающего списка, прикрепленного к тому или иному пункту меню (знак «+»):

/* измените ' +' на любой другой символ, если нужно
	*/
			li > a:after { content:  ' +'; }
		li > a:only-child:after { content: ''; }

Для этого мы используем псевдоэлемент CSS3 (:only-child). В данном случае он проверяет, имеются ли в тегах <li> родительского элемента другие элементы. Если нет, то знак плюса просто убирается, так как по умолчанию он присутствует рядом со всеми пунктами. Видите + возле пунктов WordPress и Tutorials?

Добавляем индикатор выпадающего списка

Значит, вы все сделали правильно.

В завершение

Многие для достижения подобного эффекта используют jQuery или другие библиотеки. Я считаю, что в этой статье приведен самый простой и легкий вариант. Но выбор за вами.

А как вы сделали меню на HTML? Пожалуйста, расскажите об этом в комментариях.

Валентин Сейидовавтор-переводчик статьи «How to Create a Pure CSS Dropdown Menu»

Подписывайтесь на наши группы в социальных сетях
Подписаться
Уведомить о
11 комментариев
Новые
Старые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Серик Задорожный

Подскажите, сдела всё по инструкции, и работало.
Но когда уводишь курсор и корневого меню, всё ищезает.
А ведь невозможно нажать на дочерний пункт, не убрав мыши с корневого!

Олег

Нужно добавить свойство z-index, иначе выпадающее меню будет перекрыто элементами, находящимися ниже меню.
<pre>
* и задаем абсолютное позиционирование */
nav ul ul {
display: none;
position: absolute;
top: 100%;
z-index: 10;
}
</pre>

Adil' Akhmetkali

Сдал экзамен, спасибо

Татьяна Новикова

Большое спасибо!

Как настроить

Подскажите, что здесь необходимо изменить чтобы при наведении под меню открывалось само а не срабатывало при нажатии
@media(max-width:767px) and (min-width:100px){.navbar-default ul.nav li.dropdown ul{box-shadow:0 3px 7px rgba(0,0,0,0.3);margin-top:8px;padding:5px 0;width:100%!important}
.navbar-default ul.nav li.dropdown ul.dropdown-menu li a:hover{background-color:#fff;border-radius:0;color:#f1c40f!important}
.navbar-default ul.nav li.dropdown ul li:first-child{border-top:1px solid rgba(255,255,255,0.3)}
.navbar-default ul.nav li.dropdown ul li:last-child{border-bottom:1px solid rgba(255,255,255,0.3)}
.navbar-nav .open .dropdown-menu > li > a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:10px 5px 10px 15px}
.navbar-default ul.nav li a{color:#fff!important;font-weight:600}
.about-information img{border:5px solid #bdc3c7;border-radius:50%;display:block;height:auto;margin:0 auto 30px;max-width:70%;width:auto}
.navbar.navbar-default .navbar-brand{margin:8px 25px 8px 10px}
.navbar-default .navbar-toggle{border-color:#f1c40f}
.navbar-default .navbar-toggle .icon-bar{background-color:#f1c40f}
.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#fff}
#main_header .slide_item_block h2{font-size:28px;font-weight:800;text-transform:uppercase}
}

Михаил Мироненко

Как сделать подменю в несколько столбцов?

seoonly.ru

мерси

Никита Гавриленко

Что делать если оно не по горизонтали, а по вертикали ?

hakooplay Play
3 лет назад
Ответить на  Никита Гавриленко

Коммент старый но для потомков отвечу:
Делается точно так же. Убираешь у списка свойство list-style: none и получаешь вертикальный список. Есть только маленкий момент с отступом. Чтобы было красиво надо добавить стиль nav ul li {position: relative} Чтобы следующий absolute от li плясал а не от ul. Тогда все будет красиво

Денис Власко

А как сделать плавное выпадение ?

Сергей Егорочкин
4 лет назад
Ответить на  Денис Власко

transition: all 1s ease-out 0.5s;