Легкое анимированное меню средствами CSS и jQuery

css меню

Анимация и визуальная обратная связь – прекрасные способы помочь пользователю в навигации и взаимодействии с веб-сайтом. Наряду с тем, что традиционно Adobe Flash был «безусловным переходом» для всей анимации, в наши дни при использовании волшебных возможностей javascript можно вообще обойтись без Flash’а. Сегодня мы создадим действительно классное анимированное меню, используя только CSS и jQuery.

Перед тем, как мы приступим к практическим шагам, я Вам рекомендую просмотреть демо-результат работы.

Также скачайте исходники себе на компьютер!

Обзор

Анимированное меню для сайта, которое мы сегодня сделаем с помощью CSS и jQuery, можно увидеть внизу на скриншоте.

jQuery

Я собираюсь разбить этот учебник на пять следующих секций:

Примерный набросок

Создание ресурсов

Написание HTML

Написание CSS

Создание анимации при использовании jQuery

Шаг 1: Примерный план

Во-первых, давайте посмотрим, что нам нужно сделать.

jQuery

Итак, вот примерная идея того, что нам необходимо выполнить:

Мы разобьем страницу на 4 части, заголовок, навигацию и заголовок содержимого и остальное содержимое

Область верхнего колонтитула будет простым контейнером <div>

Область навигации будет разбита на несколько контейнеров <div>, соответствующих пунктам меню.

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

Содержимое будет простым контейнером <div>

Итак, подводим итог:

<!--секция заголовка-->
<div id="header"></div>

<!--секция навигации-->
<div id="navigation" class="container">
	<div><a href="#">home</a></div>
	<div><a href="#">about</a></div>
	<div><a href="#">services</a></div>
	<div><a href="#">solutions</a></div>
	<div><a href="#">contact</a></div>
</div>

<!--секция контейнера-->
<div class="container">
	<div id="content-title"></div>

</div>

Помочь нам может просмотр структуры каталогов. Она следующая:

jQuery

Шаг 2: Ресурсы

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

Фон заголовка

Содержимое заголовка

Навигацию

Фоновую полосу

Хорошо, давайте создадим фон заголовка. Откройте Photoshop и создайте холст размером 1×181 px или сделайте его побольше, а потом обрежьте изображение. Создайте слой и задайте ему линейный градиент от высокоприоритетного до низкоприоритетного в 171px, это будет основной градиент. Создайте другой слой и задайте ему линейный градиент от высокоприоритетного до прозрачного в 10px на нижней границе первого слоя для создания эффекта тени.

Вот как это должно выглядеть, при размере 100×181 px, которые я потом обрежу до 1×181 px.

jQuery

Сохраните его как ‘hdr-bkg.png’ в нашу папку ‘img’.

Далее мы создадим заголовок содержимого. Снова открываем Photoshop и создаем холст размером 934×284 px. Создайте прямоугольник с закругленными углами при помощи соответствующего инструмента, выделите получившуюся фигуру, создайте новый слой, добавьте градиент и придайте ему тень. У нас получится что-то вроде этого:

jQuery

Сохраните как ‘content-title.png’ в папке ‘img’.

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

Белое поле – это просто. Всего лишь создайте закругленный прямоугольник размером примерно в 98px x 58px и покрасьте в белый цвет. Убедитесь, что задний фон прозрачен.

jQuery

Сохраните как ‘white.jpg’ в папке ‘img’.

Для элемента навигации откройте свой Photoshop и создайте документ размером 490px x 58px. Создайте закругленный прямоугольник примерно 98px x 58px и внесите в него текст. Нам понадобится по две копии каждого текста. Я применил к текстам немного теней, но это по желанию. Можете выбрать свои собственные цвета.

jQuery

Теперь просто продублируйте этот слой вдоль горизонтальной линии. Примените различные цвета и напишите текст.

jQuery

Сохраните как ‘nav.jpg’ в папке ‘img’.

Наконец, для фоновой полосы я просто использовал онлайн-инструмент, который называется генератор полосы. Результат выглядит следующим образом:

jQuery

Здесь можно видеть мои настройки. Конечно, вы можете сами создать полосу в Photoshop’е, но почему бы не использовать вместо него маленький веб-инструмент :-) .

Шаг 3: HTML-код

Теперь давайте кратко запишем наш HTML.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>slick animated menu</title>
  	<!--наш CSS-файл-->
	<link rel="stylesheet" href="css/main.css" type="text/css" />
	 <!--библиотека jQuery-->
	<script type="text/javascript" src="js/jquery.js" ></script>
	<!--плагин jQuery, о нем поговорим позжеr-->
	<script type="text/javascript" src="js/jquery-bp.js" ></script>
	<!--наш скрипт анимации-->
	<script type="text/javascript" src="js/navigation.js" ></script>
</head>
<body>
	<div id="header"></div>
	<div id="navigation" class="container">
		<div id="home"><a href="home">home</a></div>
		<div id="about"><a href="about">about</a></div>
		<div id="services"><a href="services">services</a></div>
		<div id="solutions"><a href="solutions">solutions</a></div>
		<div id="contact"><a href="contact">contact</a></div>
	</div>
	<div class="container">
		<div class="content">
			<div id="content-title"></div>

		</div>
	</div>
</body>

Это очень близко соответствует нашему плану, изложенному в Шаге 1.

Я добавил ссылку на файл ‘main.css’, который еще необходимо создать, а еще я добавил ссылки на некоторые файлы javascript. Так как каждый элемент навигации уникален, я придал каждому из них свой ID. Нам еще понадобится немножко простого стиля для каждого пункта меню, что позже позволит нам легко управлять этим стилем.

Нам также нужно, чтобы сверху каждого пункта навигации появлялось белое поле, когда мы проводим мышью над меню или выбираем пункт меню, а для этого нам понадобится еще один контейнер <div>. Окончательный HTML-код будет выглядеть так:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>slick animated menu</title>

	<link rel="stylesheet" href="css/main.css" type="text/css" />

	<script type="text/javascript" src="js/jquery.js" ></script>
	<script type="text/javascript" src="js/jquery-bp.js" ></script>
	<script type="text/javascript" src="js/navigation.js" ></script>
</head>
<body>
	<div id="header"></div>
	<div id="navigation" class="container">
		<div id="home" class="pri-nav"><div><a href="home">home</a></div></div>
		<div id="about" class="pri-nav"><div><a href="about">about</a></div></div>
		<div id="services" class="pri-nav"><div><a href="services">services</a></div></div>
		<div id="solutions" class="pri-nav"><div><a href="solutions">solutions</a></div></div>
		<div id="contact" class="pri-nav"><div><a href="contact">contact</a></div></div>
	</div>
	<div class="container">
		<div class="content">
			<div id="content-title"></div>

		</div>
	</div>
</body>

Сохраните его как ‘index.html’. На данный момент это наша HTML-страница:

jQuery

Шаг 4: CSS

Давайте применим немного основных стилей к веб-странице. Начнем с определения фона и добавления области заголовка.

body {
	background: url(../img/body-bkg.jpg) repeat scroll;
	margin: 0;
	padding: 0;
}

.containe r{
	margin: 0pt auto;
	width:950px;
}
#header {
	background: url(../img/hdr-bkg.jpg) repeat-x scroll;
	height:181px;
}

Сохраните это как ‘main.css’ в папке ‘css’. У нас получилось нечто, выглядящее следующим образом:

jQuery

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

#navigation{
	height:60px;
}

#home, #home div,
#about, #about div,
#services , #services div,
#solutions, #solutions div,
#contact,  #contact div {
	height:80px;
	position:absolute;
	width:97px;
	float:left;
}

#home, #about, #services, #solutions, #contact{
	background-image: url(../img/nav.jpg);
	background-attachment: scroll;
	background-repeat: no-repeat;
	top:171px;
}

#home{
	background-position: 0px -25px;
	margin-left:6px;
}

#about{
	background-position: -98px -25px;
	margin-left:105px;
}

#services{
	background-position: -196px -25px;
	margin-left:204px;
}

#solutions{
	background-position: -294px -25px;
	margin-left:303px;
}

#contact{
	background-position: -392px -25px;
	margin-left:402px;
}

#home div, #about div, #services div, #solutions div, #contact div {
	background-image: url(../img/white.jpg);
	background-attachment: scroll;
	background-repeat: no-repeat;
	background-position: 0px -60px;
}

Вот что мы сейчас имеем:

jQuery

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

.pri-nav a{
	display:block;
	text-decoration:none;
	text-indent:-30000px;
}

Теперь все выглядит вот так:

jQuery

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

#header{
	background: url(../img/hdr-bkg.jpg) repeat-x scroll;
	height:181px;
	position:absolute;
	z-index :100; /* ensure the header is on top of navigation area */
	top: 0px;
	left:0px;
	width:100%;
}

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

jQuery

Идеально! Давайте добавим содержимое, чтобы можно было перейти к скрипту анимации.

.content{
	margin-top:160px;
}

#content-title{
	background: url(../img/content.jpg) no-repeat scroll;
	height:323px;
	position:absolute;
	width:100%;
}

Шаг 5: Скрипт анимации

Во-первых, давайте скачаем последний скрипт jQuery и поместим его в папку ‘js’.

Анимация – это в основном манипуляции стилем положения фона. К сожалению, у jQuery есть ошибки в анимировании стиля позиции фона. Но не беспокойтесь! Alexander Farkas создал плагин, решающий эту проблему. Скачайте файл, переименуйте его в jquery-bp.js и сохраните в папку ‘js’.

Перед тем, как продолжить, нужно понять кое-что. Цитирую из документации плагина:

По причине ошибок в браузере (т.е. Firefox) вам необходимо установить свою (первоначальную) встроенную позицию фона: <div style=»background-position: 10px 20px»></div> — Конечно, этого также можно достигнуть и с JavaScript (jQuery): $(‘#background’).css({backgroundPosition: ’10px 20px’});

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

// id для каждого из пунктов меню
var nav  = [ '#home', '#about', '#services', '#solutions', '#contact' ];
$(document).ready(function(){
  setBkgPos();
});

function setBkgPos()
{
  for ( i = 0; i < nav.length; i++ ){
    $(nav<em></em>).css({backgroundPosition: i*(-98) + 'px -25px'});
    $(nav<em></em> + ' div').css({ backgroundPosition: '0px -60px'});
  }
}

Сохраните это как ‘navigation.js’ в папке ‘js’.

Теперь привяжем по три события к каждому из пунктов меню. Можно сделать это путем вызова функции связывания.

$(document).ready(function(){
  setBkgPos();

// здесь привяжите событие к функции  

  for ( i = 0; i < nav.length; i++ ) {
    $(nav<em></em>).bind( 'mouseover', mMouseOver );
    $(nav<em></em>).bind( 'mouseout', mMouseOut );
    $(nav<em></em>).bind( 'click', mClick );
  }
});

Каждый раз, когда пользователь проводит мышью поверх пункта навигации, наш скрипт вызывает функцию ‘mMouseOver’. Когда пользователь убирает курсор с пункта навигации, скрипт вызывает функцию ‘mMouseOut’. А при щелчке на пункт навигации скрипт вызывает функцию ‘mClick’.
Шаг 5.1: «MouseOver»

Шаг 5.1: «MouseOver»

Давайте создадим «раскадровку» анимации «MouseOver».

При ‘Mouse Over’:

Изменится изображение меню навигации (свечение) и изменится курсор на указатель.

Пункт навигации немного приподнимется.

Белое поле опустится вниз.

И белое поле, и меню навигации сдвинутся вниз.

Меню навигации и белое поле займут свою конечную позицию.

Изображение меню навигации вернется в исходное состояние.

jQuery

Отлично, теперь давайте добавим эти функции под предыдущий скрипт:

function _getHPos( id )
{
  for ( i = 0; i < nav.length; i++ ){
    if ( '#' + id == nav<em></em> ){
      return i*(-98);
    }
  }
  return 0;
}

function mMouseOver(e)
{
  $(this)
 // остановить любую предыдущую анимацию
  .stop()
  // шаг 1. Изменить файл изображения и курсор
  .css({backgroundImage: 'url('+site_url+'img/nav-over.jpg)',cursor: 'pointer'})
 // шаг.2 немного сдвинуть пункт навигации
  .animate({ backgroundPosition:'(' + _getHPos( this.id ) +'px -30px}'},"fast",
   // эта секция будет выполнена после того, как сделан шаг.2
	function(){
	  $(this)
	    .children()
		  // шаг. 3 сдвинуть белое поле вниз
		  .animate({backgroundPosition:'(0px -40px)'},20)
		  // шаг 4. Сдвинуть белое поле вниз
		  .animate({backgroundPosition:'(0px -20px)'},"fast");
	  $(this)
		// шаг 4. Сдвинуть пункт навигации вниз
		.animate({backgroundPosition:'(' + _getHPos( this.id ) +'px 50px)'},"fast")
		 // шаг 5. Сдвинуть пункт навигации в исходное положение
		.animate({backgroundPosition:'(' + _getHPos( this.id ) +'px 25px)'},"fast");
	 // сохранить родительский элемент id для последующего использования
	  var parent = this;
	  $(this)
		.children()
		  // шаг 5. Сдвинуть белое поле в конечную позицию
		  .animate( {backgroundPosition:'(0px -45px)'},"fast",
			 // эта секция будет исполняться после окончания шага.2
			function(){
			  // шаг.6 вернуть изображение в исходное
			  $(parent).css({backgroundImage: 'url(img/nav.jpg)'});
			});
	});
}
  

Я должен здесь объяснить некоторые вещи:

_getHPos используется для корректировки позиции горизонтального фона навигации для каждого пункта. Например, фон пункта ‘Home’ начнется с 0, позиция горизонтального фона ‘About’ начнется с -98px и так далее.

Также заметьте, что в начале функции мы вызываем функцию ‘stop’. Мы делаем это для того, чтобы удостовериться, что любая анимация, запущенная до события ‘mouse over’, прекратилась. Зачем? Чуть позже мы добавим другую анимацию для события ‘mouse out’. А сейчас давайте предположим, что пользователь провел мышью по пункту, затем быстро перевел указатель мыши еще куда-нибудь и снова быстро провел над тем же пунктом. Если мы не остановим анимацию перед каждым событием, получится задержка, так как часть анимации будет стоять на очереди, или даже еще хуже – анимация станет несовместимой и будет раздражать пользователя.

Шаг 5.2: «MouseOut»

Так, это сделано. Теперь давайте создадим «раскадровку» для события ‘mouse out’

При ‘Mouse Out’:

Пункт навигации сдвинется вниз.

Белое поле сдвинется вниз.

Навигация поднимется вверх.

Пункт навигации поднимется в исходное положение.

Белое поле поднимется в исходное положение (невидимое).

Курсор вернется в нормальный вид.

jQuery

Код:

function mMouseOut(e)
{
  $(this)
 // остановить любую предыдущую анимацию
  .stop()
 // шаг.1 сдвинуть вниз пункт навигации
  .animate({backgroundPosition:'(' + _getHPos( this.id ) +'px 40px )'}, "fast",
   // эта секция будет исполняться после окончания шага.1
    function(){
       // шаг.2 белое поле движется действительно быстро
      $(this).children().animate({backgroundPosition:'(0px 70px)'}, "fast");
      // шаг 3. Сдвинуть пункт навигации вверх
      $(this).animate( {backgroundPosition:'(' + _getHPos( this.id ) +'px -40px)'}, "fast",
     // эта секция будет исполняться после окончания шага.3
        function(){
          // шаг 4. Сдвинуть пункт навигации в исходную позицию
          $(this).animate( {backgroundPosition:'(' + _getHPos( this.id ) +'px -25px)'}, "fast",
            // эта секция будет исполняться после окончания шага .4
            function(){
              // сдвинуть белое поле в исходную позицию, привести в готовность к следующей анимации
              $(this).children().css({ backgroundPosition:'0px -60px'});
            })
        })
    })
    .css({backgroundImage: 'url(img/nav.jpg)', cursor: ''});
}

Шаг 5.3: Клик

Почти закончили! Теперь нам нужно проработать тот момент, когда пользователь щелкает на пункт навигации.

function mClick(e)
{
  location.href = this.id;
}

Конечно, здесь вы можете указать какое угодно размещение, которое вам только понравится. Конкретно эта функция перенаправит ваш браузер на [current_url]/[navigation_id], так что для пункта ‘home’ это будет ‘[current_url]/home’, для ‘about’- ‘[current_url]/about’, и так далее.

Шаг 5.4: Указатель текущей страницы

Конечно, нам нужен индикатор того, что мы уже находимся на странице. Для этого необходим еще один класс CSS. Назовем этот класс ‘active’. Например, если мы сейчас на пункте ‘home’, HTML-файл будет:

<div id="home" class="pri-nav active"><div><a href="home">home</a></div></div>

Или если мы на ‘about’, он станет:

<div id="about" class="pri-nav active"><div><a href="about">about</a></div></div>

И так далее.
Теперь идея заключается в том, что после загрузки страницы наш скрипт проверит, какой из пунктов навигации имеет класс ‘active’. Затем мы прилагаем анимационный эффект. И еще нам нужно убедиться, что никакое другое событие ( ‘mouseover’, ‘mouseout’, ‘click’) не вызовет анимационного эффекта на ‘активном’ пункте.

Для этого нужно немного изменить наш код. Вот полный код после внесенных изменений:

var site_url = '';
var nav  = [ '#home', '#about', '#services', '#solutions', '#contact' ];

$(document).ready(function(){
  setBkgPos();

  for ( i = 0; i < nav.length; i++ ) {
    $(nav<em></em>).bind( 'mouseover', mMouseOver );
    $(nav<em></em>).bind( 'mouseout', mMouseOut );
    $(nav<em></em>).bind( 'click', mClick );
  }

  for ( i = 0; i < nav.length; i++ ) {
    // элемент класса ‘active’начинает анимацию
    if ( $(nav<em></em>).get(0).className.indexOf('active') >= 0 ){
      $(nav<em></em>)
      .animate({ backgroundPosition:'(' + _getHPos( nav<em></em> ) +'px -30px}'},"fast",
        function(){
          $(this)
            .children()
            .animate({backgroundPosition:'(0px -40px)'},20)
            .animate({backgroundPosition:'(0px -20px)'},"fast");
          $(this)
            .animate({backgroundPosition:'(' + _getHPos( nav<em></em> ) +'px 50px)'},"fast")
            .animate({backgroundPosition:'(' + _getHPos( nav<em></em> ) +'px 25px)'},"fast");
          var parent = this;
          $(this)
            .children()
            .animate( {backgroundPosition:'(0px -45px)'},"fast",
			  function(){
                $(parent).animate({backgroundPosition:'(' + _getHPos( parent.id ) +'px 25px)'},"fast");
                $(parent).css({backgroundImage: 'url(img/nav.jpg)'});
              });
        });
        break;
    }
  }
});

Закончили!

И вот наконец у нас есть наше замечательное маленькое анимированное меню для сайта.

Скачать исходники zip архивом

Просмотр Demo

Автор: Joash Xu

Перевод и редакция: Рог Виктор и Андрей Бернацкий. Команда webformyself.

Источник: http://net.tutsplus.com

E-mail: contact@webformyself.com

Проект webformyself.com — Как создать свой сайт. Основы самостоятельного сайтостроения

P.S. Хотите опубликовать интересный тематический материал и заработать? Если ответ «Да», то жмите сюда.

JavaScript&jQuery с нуля до профи

Пройдите пошаговый видеокурс по JavaScript&jQuery

Научиться

Метки: , , , ,

Комментарии Вконтакте:

Комментарии Facebook:

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

  1. Андрей

    Спасибо, очень подробно, четко и ясно! Это сколько же времени ушло на написание статьи?

  2. Александр

    Красивое меню получилось, только белые квадратики над кнопками мешают.

  3. Роман

    Спасибі за Ваші статті, дуже корисні і потрібні початківцям, особливо покращують сприйняття інформації відеоуроки. Ще раз спасибі.

  4. олег

    Изумительная вещь !!! Большое спасибо ! Но я ,вместо белой пластинки, вставил прозрачную (сделал фотошопом) пластинку .
    Бесподобное меню !

  5. Александр

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

  6. Тони

    Потрясающая статья, сколько уже пытался найти инструкции по созданию подобного меню. И вот оно! Спасибо=)

  7. xax

    Хороший у вас сайт!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree