Главная » Уроки » Создаем многоуровневое горизонтальное меню с эффектом анимации на CSS3

Создаем многоуровневое горизонтальное меню с эффектом анимации на CSS3

Создаем многоуровневое горизонтальное меню с эффектом анимации на CSS3

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

Сегодня мы научимся создавать многоуровневое, горизонтальное меню с интересным эффектом анимации для выпадающих подпунктов, исключительно средствами CSS3. В уроке представлены структура построения меню и выпадающих списков, все стили оформления, включая визуальный эффект, для создания которого применяются псевдо-элементы с пользовательскими атрибутами.

Примечание: Следует помнить, что еще не все браузеры одинаково хорошо поддерживают функции CSS3.  Например, в Internet Explorer данное меню будет выглядеть несколько иначе 🙁
 

Многоуровневое горизонтальное меню навигации

Пример посмотрели, теперь давайте посмотрим на весь расклад, начнем с разметки html каркаса нашего меню.

HTML

Здесь ничего не обычного, для меню мы будем использовать типовую разметку в виде неупорядоченного списка. Вот как выглядит отрывок кода разметки html основных пунктов меню с выпадающими подпунктами применительно к нашей версии:
 

<nav id="menu-wrap">
<ul id="menu">
	<li><a href="#">Главная</a></li>
	<li><a href="#">Категории</a>
		<ul>
			<li><a href="#">HTML/CSS</a></li>
			<li><a href="#">Графика</a></li>
			<li><a href="#">Разработка</a></li>
			<li><a href="#">Веб дизайн</a></li>
		</ul>
	</li>
	<li><a href="#">Статьи</a></li>
	<li><a href="#">О Сайте</a></li>
	<li><a href="#">Контакты</a></li>
</ul>
</nav>

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

 

CSS3

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

Сбрасываем стили для списка ul по умолчанию:

#menu, #menu ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

Маркер для списка в нашем случае ненужен, значит list-style выставляем значение none.
 
Устанавливаем базовые стили для основной панели #menu списка ul. Выставляем ширину панели, добавляем функции градиента, закругленные углы и тень для нижней границы:

 

CSS3 стили меню

 

#menu {
	width: 960px;
	margin: 60px auto;
	border: 1px solid #222;
	background-color: #111;
	background-image: -moz-linear-gradient(#444, #111); 
	background-image: -webkit-gradient(linear, left top, left bottom, from(#444), to(#111));	
	background-image: -webkit-linear-gradient(#444, #111);	
	background-image: -o-linear-gradient(#444, #111);
	background-image: -ms-linear-gradient(#444, #111);
	background-image: linear-gradient(#444, #111);
	-moz-border-radius: 6px;
	-webkit-border-radius: 6px;
	border-radius: 6px;
	-moz-box-shadow: 0 1px 1px #777, 0 1px 0 #666 inset;
	-webkit-box-shadow: 0 1px 1px #777, 0 1px 0 #666 inset;
	box-shadow: 0 1px 1px #777, 0 1px 0 #666 inset;
	}

 
При верстке макета меню никак не обойтись без плавающих элементов: HTML элементов со свойствами float:left и float:right которые обычно выпадают из основного потока и выходят за границы родительского элемента, и в результате этого родительский элемент схлопывается. Для того, чтобы предотвратить схлопывание необходима очистка потока (Clear Float). Для этого используем компактный метод очистки потока стилями при помощи псевдоклассов :before и :after.
 

#menu:before,
#menu:after {
	content: "";
	display: table;
}
#menu:after {
	clear: both;
}
#menu {
	zoom:1; /* Хак для IE 6 и 7 */
}

 

Элементы списка

 

Элементы списка меню

 
Обратите внимание на #menu li:hover > a селектор. Это, пожалуй, один из самых важных элементов построения и оформления этого выпадающего меню

Вот как это работает: Выбираем «a» элемент, который является дочерним «li» ,«li» элемент должен быть в основном потоке «# menu». Устанавливаем необходимые нам свойства для этих элементов, расположение, параметры текста, свет ссылок и т.д.:
 

#menu li {
	float: left;
	border-right: 1px solid #222;
        -webkit-box-shadow: 1px 0 0 #444;
        -moz-box-shadow: 1px 0 0 #444;
	box-shadow: 1px 0 0 #444;
	position: relative;
}
#menu a {
	float: left;
	padding: 12px 30px;
	color: #999;
	text-transform: uppercase;
	font: bold 12px Arial, Helvetica;
	text-decoration: none;
	text-shadow: 0 1px 0 #000;
}
#menu li:hover > a {
	color: #fafafa;
}
*html #menu li a:hover { /* Для IE6 */
	color: #fafafa;
}

 

Подпункты меню

 
С помощью CSS3 transiton мы можем анимировать изменения CSS свойств, таких как margin или opacity. Использовал эту замечательную функцию CSS3 для анимации появления подменю. Результат на лицо:
 

CSS3 Анимация меню навигации

 

#menu ul {
	margin: 20px 0 0 0;
	_margin: 0; /*IE6 only*/
	opacity: 0;
	visibility: hidden;
	position: absolute;
	top: 38px;
	left: 0;
	z-index: 1;    
	background: #444;
        background: -webkit-linear-gradient(#444, #111);
        background: -moz-linear-gradient(#444, #111);	
	background: linear-gradient(#444, #111);
        -webkit-box-shadow: 0 -1px 0 rgba(255,255,255,.3);
        -moz-box-shadow: 0 -1px 0 rgba(255,255,255,.3);
	box-shadow: 0 -1px 0 rgba(255,255,255,.3);
        -webkit-border-radius: 3px;
        -moz-border-radius: 3px;	
	border-radius: 3px;
/ * Назначаем изменения свойств CSS плавно и в течение установленного времени */
        -webkit-transition: all .2s ease-in-out;
        -moz-transition: all .2s ease-in-out;
        -o-transition: all .2s ease-in-out;
	transition: all .2s ease-in-out; 
}
#menu li:hover > ul {
	opacity: 1;
	visibility: visible;
	margin: 0;
}
#menu ul ul {
	top: 0;
	left: 150px;
	margin: 0 0 0 20px;
	_margin: 0; /*IE6 only*/
        -webkit-box-shadow: -1px 0 0 rgba(255,255,255,.3);
        -moz-box-shadow: -1px 0 0 rgba(255,255,255,.3); 
	box-shadow: -1px 0 0 rgba(255,255,255,.3);		
}
#menu ul li {
	float: none;
	display: block;
	border: 0;
	_line-height: 0; /*IE6 only*/
        -webkit-box-shadow: 0 1px 0 #111, 0 2px 0 #666;
        -moz-box-shadow: 0 1px 0 #111, 0 2px 0 #666;
	box-shadow: 0 1px 0 #111, 0 2px 0 #666;
}
#menu ul li:last-child {   
	box-shadow: none;    
}
#menu ul a {    
	padding: 10px;
	width: 130px;
	_height: 10px; /*IE6 only*/
	display: block;
	white-space: nowrap;
	float: none;
	text-transform: none;
}
#menu ul a:hover {
	background-color: #0186ba;
	background-image: linear-gradient(#04acec, #0186ba);
}

 
Первый(:first-child) и последний(:last-child) дочерние элементы списка в стиле:
 

CSS3 меню навигации

 

#menu ul li:first-child > a {
        -webkit-border-radius: 3px 3px 0 0;
        -moz-border-radius: 3px 3px 0 0;
	border-radius: 3px 3px 0 0;
}
#menu ul li:first-child > a:after {
	content: '';
	position: absolute;
	left: 40px;
	top: -6px;
	border-left: 6px solid transparent;
	border-right: 6px solid transparent;
	border-bottom: 6px solid #444;
}
#menu ul ul li:first-child a:after {
	left: -6px;
	top: 50%;
	margin-top: -6px;
	border-left: 0;	
	border-bottom: 6px solid transparent;
	border-top: 6px solid transparent;
	border-right: 6px solid #3b3b3b;
}
#menu ul li:first-child a:hover:after {
	border-bottom-color: #04acec; 
}
#menu ul ul li:first-child a:hover:after {
	border-right-color: #0299d3; 
	border-bottom-color: transparent; 	
}
#menu ul li:last-child > a {
        -webkit-border-radius: 0 0 3px 3px;
        -moz-border-radius: 0 0 3px 3px;
	border-radius: 0 0 3px 3px;
}

 
На этом пожалуй и все. Собрав воедино все элементы стилей и подключив к странице html, мы получим замечательное, горизонтальное, многоуровневое меню с привлекательным эффектом анимации для выпадающих подпунктов. Если включить немного фантазии и поэкспериментировать с параметрами стилей CSS, можно добиться потрясающих результатов, создать свой, неповторимый стиль навигационного меню.

Данный урок подготовлен по материалам: RedTeamDesign

С Уважением, Андрей .

Буду всем признателен, если поддержите проект — добавив блог в исключения AdBlock и поделитесь ссылкой на запись в своих соц-сетях:

Google Bookmarks News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Вы можете оставить отзыв, подписаться на обновленияОбновления блога по RSSRSS или Обновления блога на TwitterTwitter !

41 комментарий
  1. Сергей says:

    А как можно сделать его вертикальным?

    Ответить
    • driver says:

      Для этого существует масса других шаблонов меню. В этом же случае выстройте структуру меню по аналогии подпунктов

      Ответить
  2. Егор says:

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

    Ответить
    • driver says:

      Добрый день Егор.

      Если вас интересует, какие правила в css отвечают за вывод угловых указателей пунктов меню, то в статье, как раз в последнем куске кода прописаны все свойства для дочерних элементов списка :first-child и :last-child. Вам необходимо обратить свой не затуманенный взор на #menu ul li:first-child > a:after.

      Ответить
  3. ROman says:

    Здравствуйте, а подскажите где в стилях поменять основной фон ссылок, что-то никак не пойму.

    Ответить
  4. driver says:

    Здравствуйте.

    Основной фон пунктов меню смотрите в секции #menu, свойства background-color и background-image для линейного градиента.

    Цвет ссылок основных пунктов #menu a, изменение при наведении #menu li:hover > a

    Формирование подпунктов в секции #menu ul, свойства background-color и background-image, для фона, и color для текста ссылок

    Вроде бы все очень понятно и легко читаемый код. ))

    Удачи!

    Ответить
    • Серега says:

      Здравствуйте! Скажите пожалуйста как убрать лишнею ячейку в конце меню или по крайне мере убрать границу между последней ячейкой меню и пустой???

      Ответить
      • driver says:

        Убрать бордюр справа у последнего пункта меню, пропишите для этого пункта в списке новый класс, обзовите его, например last, что логично, пункт то у вас в меню последний: <li class="last">

        Затем в стили меню добавьте следующее:

        #menu li.last {
        border-right: 0;
        box-shadow: none;
        }

        Всё, границы после последнего пункта меню вы больше не увидите))).

        Ответить
        • Серега says:

          Все сделал как вы описали: дал class элементу < li class="last"> <a href="#" >Контакты</a></li>

          потом прописал правила: #menu li .last{ border-right:0; box-shadow:none;}

          Даже экспериментировал с правилом #menu и ставил width:auto; и после неудавшегося эксперимента возвращал все на круги своя)

          Но к моему большому сожалению не проканало ...(((

        • driver says:

          Чтобы сработало правило width:auto; необходимо выровнять меню, например по левому краю float: left;, ну, и с margin поиграть, для начала можно margin:0 auto;

          Почему у вас «не проканало» убрать бордюр у последнего пункта, просто теряюсь в догадках, в демо все канает

  5. Серега says:

    Скажите пожалуйста как убрать лишнею ячейку или границу между ячейками!

    Ответить
  6. Серега says:

    Я все перепробовал даже на исходнике делал те изменения которые вы описали выше! Попробуйте сами протестировать менюшку с изменениями в Opere and firefox-e...

    Пожалуйста поюзайте сами код, «только обязательно поюзайте» ... и напишите мне свой ответ!

    P.s. надо бы вам сюда прибобахать online chat консультатор...ха ха, чтобы можно было бы вас доставать в online реале...)))

    Ответить
    • driver says:

      Поюзал, ещё как поюзал))) Специально для вас Серёга вариант: Тынц>> смотрите в онлайн редакторе исходники, экспериментируйте до упаду)))

      И еще один без пустой «ячейки»: Тынц>>

      Ответить
  7. Роман says:

    Доброго времени суток.

    Все отлично работает, почти))

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

    подскажите где подкрутить значения для этой регулировки.

    Ответить
    • driver says:

      Даже не знаю чем вам и помочь. Не видя пациента трудно его лечить. В демо всё работает как нуна))) За формирование и вывод стрелки вверх отвечает следующий набор свойств:

      #menu ul li:first-child > a:after { content: ''; position: absolute; left: 40px; top: -6px; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 6px solid #444; }

      Ответить
  8. Алекс says:

    Спасибо за меню, пробую использовать.

    Было бы замечательно, если бы были варианты с другими цветами кроме серого. Попробую сам настроить.

    Но вот существенная переделка нужна, сам вряд ли...

    Сейчас стрелочка в меню 2-3-4 уровня показывает откуда мы пришли. Нужно наоборот — чтобы в пункте 2 уровня (или 3) был знак типа стрелки, который бы показывал что есть еще вложенные меню в данном пункте. И наоборот — если вложенных меню в данном пункте нет, чтоб не было этого знака.

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

    Как это сделать? Буду рад любой подсказке )

    Ответить
  9. Сергей says:

    Привет! Я решил попробовать вставить твое меню себе на тестовый блог: geliosmyblog.blogspot.com.

    Через гаджет «HTML/JavaScript» не вышло ну то и бог с ним... зашел в «Шаблоны-Изменить HTML», выбрал место и вставил. Грубо но по другому я не умею 🙁 нету жилы программиста. С меню ничего не делал только выставил ширину на 100%, вроде так норм вышло.

    За статью тебе спасибо!!!

    Правда область сверху и снижу меню пришлось сжать используя вот такой код:

    <div style='margin: -58px 0px -58px 0px'>.

    Через то, что не смог меню вставить в гаджет «HTML/JavaScript» туда же пришлось вставить и бегущую строку, наверное если бы ты увидел то, что я там налепил ты бы это рассказывал как анекдот своим друзьям. Вот посмейся с моего кода:

    <marquee behavior='alternate' bgcolor='' hspace='0' scrollamount='5' scrolldelay='30' title='бегуща строка' vspace='0' width='100%'> <font class='f2'> <script language='JavaScript'> //<![CDATA[ var h=(Math.random()*5); if (h <1) document.writeln(" Змінний текс № 1"); if (h > 1 && h < 2) document.writeln(" Змінний текс № 2"); if (h > 2 && h < 3) document.writeln(" Змінний текс № 3"); if (h > 3 && h < 4) document.writeln(" Змінний текс № 4"); if (h > 4 && h < 5) document.writeln(" Змінний текс № 5"); if (h > 5 && h < 6) document.writeln(" Змінний текс № 6"); //]]> </script> </font> </marquee>

    Вот сейчас решил подключить часики с интернет-ресурса: 24timezones.com, вот силка на страницу с hmtl-codom для вставки часиков: _time.php. Все легко и просто.

    Захотелось еще немножко пошаманить 🙁 но тут как всегда (ума нету считай калека) выходит не так как хочется 🙁 Решил под часиками добавить строчку отображающую дату и время все с того же ресурса вот такого плана: «11:27:01 — Субота, Січень 30, 2016». На обычной hmtl-странице оно так и вышло, но в блоге не та все просто оказалось: «11:29:27 — ������, ѳ���� 30, 2016» 🙁

    Теперь наверное весь мой труд коту под хвост пойдет!! Вставлял через гаджет «HTML/JavaScript». Пробовал через редактор сообщения вставлять тот же результат.

    Вот чистый код который я вставил в гаджет «HTML/JavaScript»:

    <script src="http://googledrive.com/host/0ByT_q0idDzMnM1F5SGpjRjRLbnM/swfobject.js" language="javascript"></script> <script src="http://googledrive.com/host/0ByT_q0idDzMnM1F5SGpjRjRLbnM/maindata.js" language="javascript"></script> <style type="text/css"> .f3 {font:12px arial,Helvetica,sans-serif;} </style> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr> <td width="200" align="center"> <div id="flash_container_tt4fe9a2726063d"></div> <script type="text/javascript"> var flashMap = new SWFObject("http://24timezones.com/timescript/clock_final.swf", "main", "175", "175", "7.0.22", "#ffffff", true) flashMap.addParam("movie", "http://24timezones.com/timescript/clock_final.swf"); flashMap.addParam("quality", "high"); flashMap.addParam("wmode", "transparent"); flashMap.addParam("flashvars", "color=cc9966&logo=1&city=1000110807"); flashMap.write("flash_container_tt4fe9a2726063d"); </script> </td> </tr> <tr> <td style="text-align: center; font-weight: bold"> <a href="http://24timezones.com/ru_clock/ukraine_time.php" target="_blank" style="text-decoration: none" title="Точний час Україна">Україна</a> </td> </tr> <tr> <td align="center"> <span class="f3"><strong> <a href="http://24timezones.com/ru_clock/ukraine_time.php" style="text-decoration: none" target="_BLANK" title="точное время Украина"></a> <span id="tzTimeSpan_ee4fe9a10a3469b"></span> <script type="text/javascript" src="http://googledrive.com/host/0ByT_q0idDzMnM1F5SGpjRjRLbnM/time_24_1_1.js"></script> <script src="http://24timezones.com/timescript/cities2_countries/gettime.js.php?city=15930&hourtype=24&showdate=1&showseconds=1&id=1000110800&elem=ee4fe9a10a3469b" language="javascript"> </script> </strong></span> </td> </tr> </table>

    P.S. Если сможешь сказать в чем проблема и как исправить я буду очень признателен за помощь!

    Ответить
  10. Алекс says:

    Привет, driver

    В ожидании ответа Меню кое-как вставил, главное все работает.

    С :first-child) и (:last-child) так и не смог разобраться, как же сделать указатель на вложенное подменю.

    Появился еще один вопрос, более неотложный. Может, ты все-таки вернешься к в эту тему и подскажешь ))

    В меню 2 или 3 уровня у меня слишком много пунктов, больше 40. В одну колонку это слишком длинно и неудобно, вылазит за низ страницы. Нужно это подменю разбить на несколько колонок. И лучше чтоб автоматически делалось только там, где много пунктов. Такое возможно?

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

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

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

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

Подписаться не комментируя

Обновления комментариев по RSS RSS комментариев к этой записи »
Рейтинг@Mail.ru