Статьи

Как создать выпадающее меню навигации с HTML5, CSS3 и JQuery

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

HTML5 привносит в спецификацию выделенный элемент <nav>, который должен использоваться в качестве контейнера для любой основной структуры навигации, такой как, например, основные вертикальные или горизонтальные навигационные меню сайта или оглавление на странице. К сожалению, IE пока не поддерживает этот новый элемент, но есть простое исправление, которое мы можем использовать, и я уверен, что вы все знаете.

Используя CSS3, мы можем покончить с тем, что потребовало бы использования нескольких фоновых изображений и, возможно, дополнительного контейнера-обертки или двух, и полагаться (почти) исключительно на некоторые из новых свойств стиля, таких как, например, закругленные углы и тени. которые доступны для поддержки браузеров. Опять же, не все браузеры (кашель, IE!) Поддерживают эти новые правила, но мы можем очень легко предоставить запасные решения для браузеров, которые не могут обрабатывать наши стили.

Кстати, Envato Market предлагает огромный выбор стильных CSS-меню , таких как PickArt , простое, чистое, элегантное решение, готовое к использованию и установке всего за 4 доллара.

PickArt на рынке Envato
PickArt на рынке Envato

Вы также можете попробовать услуги одного из экспертов в Envato Studio . Например, Lukasz Czerwinski создаст совершенно новый плагин jQuery с вашими спецификациями за $ 115 в течение семи дней с рейтингом удовлетворенности 100%. Его предложения включают выпадающие меню, интегрированные медиа-галереи с вашими социальными службами, слайдеры и многое другое.

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


Нам понадобится копия последней версии jQuery версии 1.4.2 на момент написания, а также копия текущей версии (1.1) превосходной библиотеки Modernizr , которую мы будем использовать для поддержки поддерживаемых браузеров. с CSS3 мы используем.

Создайте папку проекта для файлов, которые мы создадим где-то на вашем компьютере, и назовите ее nav , внутри этой папки создайте три новые папки; один называется js , другой называется css, а другой — резервный . Убедитесь, что копии jQuery и Modernizr сохранены в папке js .


Начните кодирование, создав следующую страницу в вашем любимом редакторе кода:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html lang=»en»>
    <head>
        <meta charset=»utf-8″>
        <title>HTML5, CSS3 and jQuery Navigation menu</title>
        <link rel=»stylesheet» href=»css/nav.css»>
        <!—[if IE]>
            <script src=»http://html5shiv.googlecode.com/svn/trunk/html5.js»></script>
        <![endif]—>
    </head>
    <body class=»no-js»>
        <nav id=»topNav»>
                <ul>
                    <li><a href=»#» title=»Nav Link 1″>Nav Link 1</a></li>
                <li>
                    <a href=»#» title=»Nav Link 1″>Nav Link 2</a>
                    <ul>
                        <li><a href=»#» title=»Sub Nav Link 1″>Sub Nav Link 1</a></li>
                        <li><a href=»#» title=»Sub Nav Link 2″>Sub Nav Link 2</a></li>
                        <li><a href=»#» title=»Sub Nav Link 3″>Sub Nav Link 3</a></li>
                        <li><a href=»#» title=»Sub Nav Link 4″>Sub Nav Link 4</a></li>
                        <li class=»last»><a href=»#» title=»Sub Nav Link 5″>Sub Nav Link 5</a></li>
                    </ul>
                </li>
                <li><a href=»#» title=»Nav Link 1″>Nav Link 3</a></li>
                <li><a href=»#» title=»Nav Link 1″>Nav Link 4</a></li>
                <li><a href=»#» title=»Nav Link 1″>Nav Link 5</a></li>
            </ul>
        </nav>
        <script src=»js/jquery.js»></script>
        <script src=»js/modernizr.js»></script>
    </body>
</html>

Сохраните это как nav.html в папке nav . Мы начнем с минимального типа документа HTML5, который позволяет нам указывать тип документа в четверти кода, который мы использовали. Мы также указываем язык по умолчанию и кодировку символов; хотя документ по-прежнему будет проверяться без этих двух вещей, рекомендуется включить их, и страница вызовет предупреждения валидатора, если язык по умолчанию не указан. Затем мы ссылаемся на таблицу стилей (мы создадим ее далее) и используем условный комментарий, предназначенный для IE, чтобы при необходимости загрузить отличный скрипт Реми Шарпа html5.js .

В теле страницы у нас есть элемент <nav> в качестве контейнера для традиционного списка ссылок, и мы добавили в него также подменю. Элемент волшебным образом не создает для нас навигационное меню, и он не включает никаких новых элементов пункта меню или чего-либо подобного, поэтому неупорядоченный список все еще является подходящим выбором. Элемент <nav> — это просто семантический контейнер для нашего меню, которое описывает его функцию в документе, заменяя общий элемент <div>, который ничего не говорит о его назначении на странице.

В конце тела мы ссылаемся на наши файлы сценариев jQuery и Modernizr. Мы будем использовать jQuery чуть позже, когда придем, чтобы добавить поведение для меню, но Modernizr сделает все сразу, обнаружив возможности используемого браузера и добавив серию имен классов в элемент HTML, который мы можем использовать для добавления нашего CSS3, чтобы он применялся только к браузерам, которые могут их использовать. Мы также добавили имя класса no-j s в <body> страницы; мы удалим его позже, если JavaScript включен, поэтому мы также можем использовать его для добавления стилей, которые должны применяться только когда JavaScript отключен.


Теперь давайте добавим некоторые базовые стили; создайте следующую таблицу стилей:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
/* JS disabled styles */
.no-js nav li:hover ul { display:block;
 
/* base nav styles */
nav { display:block;
nav ul { padding:0;
nav li { position:relative;
nav ul:after { content:».»;
nav li a { display:block;
nav li a:focus { outline:none;
nav li:first-child a { border-left:none;
nav li.last a { border-right:none;
nav a span { display:block;
nav ul ul { display:none;
nav ul ul li { float:none;
nav ul ul a { padding:5px 10px;
nav ul ul a:hover { background-color:#555;
Save this file in the css directory as nav.css.

Далее мы можем добавить наш CSS3:

01
02
03
04
05
06
07
08
09
10
11
/* CSS3 */
.borderradius nav { -moz-border-radius:4px;
.cssgradients nav { background-image:-moz-linear-gradient(0% 22px 90deg, #222, #999);
.boxshadow.rgba nav { -moz-box-shadow:2px 2px 2px rgba(0,0,0,.75);
.cssgradients nav li:hover { background-image:-moz-linear-gradient(0% 100px 90deg, #999, #222);
.borderradius nav ul ul { -moz-border-radius-bottomleft:4px;
.boxshadow.rgba nav ul ul { background-color:rgba(0,0,0,0.8);
.rgba nav ul ul li { border-left:1px solid rgba(0,0,0,0.1);
.rgba nav ul ul a:hover { background-color:rgba(85,85,85,.9);
.borderradius.rgba nav ul ul li.last { border-left:1px solid rgba(0,0,0,0.1);
.csstransforms ul a span { -moz-transform:rotate(-180deg);-webkit-transform:rotate(-180deg);

Используя классы, добавленные Modernizr к элементу <html> , мы можем легко и безопасно добавить нужные нам стили CSS3. Мы используем стиль border-radius для придания элементу <nav> закругленных углов; Нам нужно предоставить объявления с префиксами Mozilla и Webkit, а также стандартные стили с радиусом границы для поддерживающих их браузеров, таких как Opera. Нам нужно сделать это с большинством наших стилей CSS3.

Помимо округления угла <nav> мы также даем ему градиент и тень. Стили градиента довольно сложны и различаются для браузеров на основе Mozilla и Webkit, которые являются единственными браузерами, которые в настоящее время их реализуют. Оба браузера используют свойство background-image . В Firefox мы используем -moz-linear-Gradient, чтобы добавить линейный градиент. Требуются значения, которые соответствуют начальной точке градиента (0%), точке, в которой первый цвет сливается со вторым цветом (22 пикселя), углу оси градиента (90 градусов), первому цвету (# 999) и второй цвет (# 222).

Мы можем получить один и тот же градиент в Safari или Chrome, используя -webkit-градиент, и синтаксис немного отличается; мы указываем, что это должен быть линейный градиент, а затем предоставляем две точки, которые сообщают браузеру, где градиент должен начинаться и заканчиваться. Значения в примере соответствуют левому, верхнему и правому значениям 0% и 70% для нижнего, что дает нам тот же стиль, что и в Firefox. Наконец, мы указываем цвета градиента.

Когда мы применяем тень, мы комбинируем ее с классом Modernizr для RGBA, а также с boxshadow, чтобы наша тень была прозрачной. Свойства Mozilla и webkit одинаковы, и мы также предоставляем фактическое свойство box-shadow для поддержки браузеров. Значения, которые мы указываем для этого правила, это смещение влево (2 пикселя), верхнее смещение (2 пикселя), степень размытия (2 пикселя) и, наконец, цвет тени (0,0,0). Цвет — это то, где мы используем RGBA, что позволяет нам установить непрозрачность на 75% (.75).

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

Остальные правила устанавливают различные градиенты, закругленные края, прозрачность с помощью RGBA и тени на других элементах в меню <nav> , такие как приятные нижние закругленные углы и тень на подменю, а также инвертирование градиента для привлекательного состояния при наведении , Теперь наше меню навигации должно выглядеть следующим образом в поддерживаемом браузере:

Поддерживая браузеры, мы можем заставить наши элементы выглядеть довольно горячими без использования одного изображения, что означает, что наши страницы будут загружаться намного быстрее при гораздо меньшем количестве HTTP-запросов. Однако не все браузеры будут поддерживать стили CSS3, особенно любую версию IE, поэтому нам все еще нужно определить наши резервные стили. Добавьте следующий код в таблицу стилей:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
/* fallbacks */
.no-cssgradients nav, .no-js nav { padding-bottom:4px;
.no-borderradius nav ul, .no-js nav ul { background:url(../fallback/navRight.gif) no-repeat 100% 0;
.no-borderradius nav ul ul, .no-js nav ul ul { background:none;
.no-borderradius nav li, .no-js nav li { height:44px;
.no-cssgradients nav li:hover, .no-js nav li:hover { background:url(../fallback/navOverBG.gif) repeat-x 0 0;
.no-borderradius nav li li, .no-js nav li li { height:auto;
.no-borderradius nav li:first-child, .no-js nav li:first-child { background:url(../fallback/navLeft.gif) no-repeat 0 0;
.no-borderradius nav li:first-child:hover, .no-js nav li:first-child:hover { background:url(../fallback/navOverLeft.gif) no-repeat 0 0;
.no-borderradius nav li li:first-child, .no-js nav li li:first-child { background:none;
.no-rgba nav ul ul, .no-js nav ul ul { left:1px;
.no-rgba nav ul ul a, .no-js nav ul ul a { left:3px;
.no-rgba nav ul ul a:hover { background:url(../fallback/subOverBG.png) repeat 0 0;
.no-csstransforms ul a span { height:7px;
.no-borderradius ul ul li.last { margin-bottom:10px;
.no-cssgradients.boxshadow nav { box-shadow:none;

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

Вы заметите, что мы также используем селекторы, предназначенные для нашего класса no-js ; это потому, что когда JavaScript отключен, Modernizr не будет запускаться и не будет добавлять имена классов, которые нам нужны, в документ, поэтому наши резервные копии, не относящиеся к CSS3, также становятся нашими резервными копиями не-js.


Теперь давайте добавим некоторый скрипт. Первое, что нам нужно сделать, это удалить класс no-js из тела страницы, когда JavaScript не отключен. Мы хотим сделать это как можно скорее в процессе рендеринга страницы, чтобы избежать мерцания при смене стилей. Сразу после открывающего тега body добавьте следующий код:

Все, что мы делаем, это получаем элемент <body> по имени тега и устанавливаем его свойство className в пустую строку. Обычно мы используем jQuery, чтобы сделать это для нас, но поскольку jQuery не будет загружен при выполнении этого скрипта, мы не сможем его использовать. Конечно, мы могли бы загрузить jQuery до этого, но тогда мы сильно пострадали бы от производительности. Наш сценарий состоит всего из 2 строк кода, поэтому он не вызовет значительной задержки, и, поскольку он будет выполнен до того, как браузер даже обработает разметку для элемента <nav> , флэш-содержимое не будет отображаться.

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

Сценарий относительно прост; мы обертываем наш код в замыкание и передаем объект jQuery, безопасно помещенный в пространство имен со знаком доллара, на тот случай, если при запуске кода в эксплуатацию используется другая библиотека. Затем мы кешируем ссылку на элемент <nav>, чтобы мы могли ссылаться на него, не выбирая его из документа повторно. Затем мы обрабатываем каждый элемент списка в меню.

Для каждого соответствующего элемента мы проверяем его на наличие вложенных элементов <ul> и добавляем ли он новый элемент <span> в элемент списка. Это станет индикатором нашего подменю. Когда подменю найдено, мы также присоединяем помощники событий mouseenter () и mouseleave () к элементу списка, который содержит меню. Все эти помощники показывают или скрывают подменю, перемещая его вниз или вверх соответственно. Обратите внимание на использование метода stop (), который помогает предотвратить очередность открытия и закрытия анимации, если указатель мыши многократно перемещается на элементы списка целей и отключается от них.

На данный момент мы должны быть в довольно хорошем месте в отношении большинства ситуаций; в любом браузере, поддерживающем HTML5, наше меню должно выглядеть относительно одинаково независимо от того, поддерживается CSS3 или нет, и включен ли сценарий или нет. Тем не менее, IE представляет нам проблему; когда JS включен, скрипт htmlshiv.js заставляет IE понимать элемент <nav>, и наши стили не-css3 подобраны и реализованы — все очень хорошо и хорошо (у нас все еще есть некоторые проблемы с IE7, как среди прочего наш auto -чистка : после того, как правила не поняты или не применяются, но мы скоро к этому придем).

Однако проблемы начинаются, когда IE используется с отключенными сценариями — в этой ситуации сценарий html5shiv.js не выполняется, и IE не понимает элемент <nav> . Ни один из наших селекторов, которые включают в себя nav, не будет реализован! Это не конец света, хотя; мы можем предоставить альтернативную таблицу стилей, которая используется только в том случае, если в браузере отключен JS и используется IE. Сразу после сценария, удаляющего класс no-js из элемента <body>, добавьте следующее:

1
2
3
4
5
<noscript>
<!—[if IE]>
    <link rel=»stylesheet» href=»css/ie.css»>
<![endif]—>
</noscript>

Простое решение действительно. Теперь нам нужно создать новую таблицу стилей; добавьте следующие правила в новый документ в вашем редакторе кода:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
/* ie styles for when js disabled */
ul { display:block;
ul:after { content:».»;
li { height:44px;
li.last a { border-right:none;
li:hover { background:url(../fallback/navOverBG.gif) repeat-x 0 0;
li:first-child { background:url(../fallback/navLeftIE.gif) no-repeat 0 0;
li:first-child a { border-left:none;
li:first-child:hover { background:url(../fallback/navOverLeft.gif) no-repeat 0 0;
li a { display:block;
li li { width:auto;
li li:first-child { background:none;
li li:hover { background-image:none;
ul li li a:hover { border-right:none;
ul ul { display:none;
ul li:hover ul { display:block;
li li { height:auto;
ul ul a:hover { background:url(../fallback/subOverBG.png) repeat 0 0;
ul a span { height:7px;
ul ul li { background:none;
ul ul li.last { margin-bottom:10px;
ul ul li a { padding:5px 10px;

Сохраните это в папке css как ie.css . Как видите, мы не нацелены на элемент <nav> в этой таблице стилей; некоторые из стилей, которые мы дали элементу <nav> ранее, были добавлены к элементу <ul> , и есть несколько новых стилей, которые необходимо включить специально для этого сценария. По сути, таблица стилей создает тот же эффект, что и раньше, поэтому IE8 с отключенным JS должен выглядеть так:

Нам пришлось использовать еще пару изображений для этого сценария, потому что у нас больше нет элемента <nav>, чтобы повесить фоновый повтор для основного градиента. Так что это все современные браузеры, с включенным и отключенным JS, работающие как положено — используя CS3, где это возможно, и откат изображения, где нет.

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

1
2
3
4
5
* styles to fix IE7 */
ul { display:inline-block;
ul li a span { position:absolute;
ul ul li a { border-right:none;
.content { clear:both;

Сохраните это в папке css как ie7.css и добавьте новый условный комментарий в < заголовок страницы:

1
2
3
4
<!—[if IE 7]>
    <link rel=»stylesheet» href=»css/ie.css»>
    <link rel=»stylesheet» href=»css/ie7.css»>
<![endif]—>

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