Рубрика CSS
Создание анимационного меню с помощью CSS и jQuery
Эффекты анимации являются прекрасным дополнением к навигации что улучшает взаимодействие с веб-сайтом. Хотя с применением Adobe Flash все было бы намного оживленнее, но мы воспользуемся всей мощью JavaScript, тем самым избежим использование Flash в целом. Итак, сегодня мы собираемся создать анимированное меню навигации, используя только CSS и JQuery.
Обзор.
Меню, которое мы создадим, будет выгладить следующим образом.
Я собираюсь разбить этот урок на пять разделов следующим образом:
- Создание макета и структуры каталогов
- Создание графических элементов
- Запись HTML
- Запись CSS
- Создание анимации используя jQuery
Шаг 1: Создание макета.
Прежде всего, давайте посмотрим, что мы должны здесь сделать.
Вот примерное представление о том, что мы должны сделать:
- Итак, разделим страницу на 4 части: заголовок (шапку), навигацию, содержание и оставшуюся часть сайта.
- В заголовке будет <div> контейнер.
- Области навигации будут разделены на несколько <div> контейнеров, соответствующие пункту меню.
- В большинстве случаев для создания меню используются теги <ul> <li>, но так как каждый пункт меню является уникальным, то я не вижу преимущества использования тегов<ul> <li> и поэтому буду использовать тег <div>.
- В содержании будет <div> контейнер.
Итак, подведем итог:
<!-- header section-->
<div id="header"></div>
<!-- navigation section-->
<div id="navigation">
<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>
<!-- container section-->
<div>
<div id="content-title"></div>
<!-- rest of the content -->
</div>
Структура каталогов выглядит следующим образом:
Шаг 2: Создание графических элементов
Я полагаю, у вас есть базовые знания по работе в Photoshop, поэтому я не буду давать слишком подробно инструкции по этому поводу.
Вот несколько вещей, которые мы должны сделать:
- Шапку
- Блок для содержания
- Элементы для навигации
- Элемент для создания фона
Замечу, если вы хотите пропустить этот шаг, вы можете воспользоваться готовым вариантом, просто скачайте его по этой ссылке.
Хорошо, давайте создадим шапку. Откройте Photoshop и создайте документ размером 1 × 181 пикселей, или вы можете создать его больше, а затем обрезать до нужного размера.
Далее создайте слой и задайте ему градиент как на рисунке ниже. Теперь создайте еще один слой и задайте линейный градиент от основного к прозрачному с запасом в 10px в нижней части первого слоя.
Вот как это изображение выглядит с размерами 100 × 181 пикселей, которое я потом обрежу до 1 × 181 пикселей.
Сохраняем как «hdr-bkg.png» в папке IMG.
Далее, мы будем создавать графический элемент для контента. Для этого в программе Photoshop создаем документ следующих размеров 934 × 284 пикселей.
С помощью инструмента Rounded Rectangle Tool на новом слое создаем прямоугольник с закругленными углами, добавив градиент и тень.
В результате у нас получится что-то вроде этого:
Сохраняем как «content-title.png’ в папке IMG.
Теперь давайте создадим графические элементы для навигации. Для этого нам необходимо создать два набора изображений и белый прямоугольник.
Для создания прямоугольника с закругленными углами устанавливаем следующие размеры 98px х 58px и заливаем его белым цветом. Фон при этом должен быть прозрачным.
Сохраняем как «white.jpg ‘в’ папке IMG.
Для создания пунктов навигации, открываем Photoshop и создаем документ 490px х 58px.
Далее необходимо создать прямоугольник с округлыми краями размером 98px х 58px и вписать необходимый нам текст. Для стилизации кнопок и текста вы можете использовать свои варианты.
Теперь просто дублируйте этот слой вдоль горизонтальной линии с применением различных цветов и текста.
Сохраняем как «nav.jpg ‘в папке IMG.
Наконец, для создания фона я воспользовался специальным сервисом. Фон выглядит следующим образом:
Вы можете задать свои настройки.
Шаг 3: 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>
<!--our CSS file-->
<link rel="stylesheet" href="css/main.css" type="text/css" />
<!--jQuery library-->
<script type="text/javascript" src="js/jquery.js" ></script>
<!--jQuery plugin, we’ll get to this later-->
<script type="text/javascript" src="js/jquery-bp.js" ></script>
<!--Our animation script-->
<script type="text/javascript" src="js/navigation.js" ></script>
</head>
<body>
<div id="header"></div>
<div id="navigation">
<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>
<div>
<div id="content-title"></div>
<!-- the rest of the content-->
</div>
</div>
</body>
Теперь вкратце рассмотрим шаг 1.
Итак, в начале я подключаю все необходимые файлы для работы меню. Каждому элементу навигации присвоен свой уникальный 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">
<div id="home"><div><a href="home">home</a></div></div>
<div id="about"><div><a href="about">about</a></div></div>
<div id="services"><div><a href="services">services</a></div></div>
<div id="solutions"><div><a href="solutions">solutions</a></div></div>
<div id="contact"><div><a href="contact">contact</a></div></div>
</div>
<div>
<div>
<div id="content-title"></div>
<!-- the rest of the content-->
</div>
</div>
</body>
Шаг 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.
Вот что у нас получилось:
Теперь давайте добавим стиль каждому из пунктов меню. Теперь для каждого из пункта меню устанавливаем свойство position:absolute.
#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;
}
Вот что мы имеем:
Одна из проблем, ссылка <a href> появляется в верхней части меню, давайте удалим ее большим текстовым отступом за пределы экрана.
Добавим в таблицу стилей.
.pri-nav a{
display:block;
text-decoration:none;
text-indent:-30000px;
}
Теперь она будет выглядеть следующим образом:
У нас появилась еще одна проблема – это тень над заголовком меню. Для решения этой проблемы можно воспользоваться следующим кодом:
#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 с прозрачностью, то у нас получилось следующее.
Готово. Теперь давайте добавим контент и приступим к анимации.
.content{
margin-top:160px;
}
#content-title{
background: url(../img/content.jpg) no-repeat scroll;
height:323px;
position:absolute;
width:100%;
}
Шаг 5: Сценарий анимации.
Прежде всего, давайте обновим JQuery и поместим его в папку «JS.
К сожалению в JQuery есть ошибка в анимации при использовании свойства background-position. Но волноваться не стоит! Alexander Farkas создал плагин, который решает эту проблему.
Загрузите файл, переименуйте его в JQuery-bp.js и сохраните его в папке «JS. Для пояснения я процитирую документацию по данному плагину:
‘Из-за некоторых ошибок браузера например, Firefox, вы должны изначально установить свойство background-position’.
<div style="background-position: 10px 20px"> </> Div
- Конечно, вы можете добиться этого и с помощью JavaScript (JQuery).
$ ('# Условия "). CSS ((backgroundPosition: 20px '10px'));
Итак, устанавливаем свойство background-position для каждого пункта, в начале нашего сценария.
Сохраняем как ‘navigation.js’ в папке ‘js’.
Теперь мы свяжем 3 события с каждым из пунктов меню.
$(document).ready(function(){
setBkgPos();
// bind the event to function here
for ( i = 0; i < nav.length; i++ ) {
$(nav[i]).bind( 'mouseover', mMouseOver );
$(nav[i]).bind( 'mouseout', mMouseOut );
$(nav[i]).bind( 'click', mClick );
}
});
Всякий раз, когда пользователь наводит курсор мыши на элемент навигации, наш сценарий вызовет функцию ‘mMouseOver’.
Когда пользователь убирает курсор мыши с элемента навигации, наш сценарий вызовет функцию ‘mMouseOut’.
И когда пользователь щелкает по элементу навигации, наш сценарий вызовет функцию ‘mClick’.
Шаг 5.1: Функция «mMouseOver»
Давайте рассмотрим этапы анимации.
- Изменение изображения меню навигации и изменение курсора на указатель.
- Элементы навигации будут двигаться немного вверх.
- Белый блок смещается вниз.
- Белый блок и элемент навигации движутся вниз.
- Белый блок и элемент навигации движутся до окончательной позиции.
- Элементы меню возвращаются в исходное состояние.
Теперь, давайте добавим эти функции ниже предыдущего сценария:
function _getHPos( id )
{
for ( i = 0; i < nav.length; i++ ){
if ( '#' + id == nav[i] ){
return i*(-98);
}
}
return 0;
}
function mMouseOver(e)
{
$(this)
// stop any animation that took place before this
.stop()
// step 1. change the image file and change the cursor
.css({backgroundImage: 'url('+site_url+'img/nav-over.jpg)',cursor: 'pointer'})
// step.2 move up the navigation item a bit
.animate({ backgroundPosition:'(' + _getHPos( this.id ) +'px -30px}'},"fast",
// this section will be executed after the step.2 is done
function(){
$(this)
.children()
// step. 3 move the white box down
.animate({backgroundPosition:'(0px -40px)'},20)
// step 4. move the white box down
.animate({backgroundPosition:'(0px -20px)'},"fast");
$(this)
// step 4. move the navigation item down
.animate({backgroundPosition:'(' + _getHPos( this.id ) +'px 50px)'},"fast")
// step 5. move the navigation item to its final position
.animate({backgroundPosition:'(' + _getHPos( this.id ) +'px 25px)'},"fast");
// store the parent element id for later usage
var parent = this;
$(this)
.children()
// step 5. move the white box to its final position
.animate( {backgroundPosition:'(0px -45px)'},"fast",
// this section will be executed after the step.2 is done
function(){
// step.6 change the image to its original image
$(parent).css({backgroundImage: 'url(img/nav.jpg)'});
});
});
}
Поясню некоторые моменты.
Функция _getHPos необходима для точного позиционирования для каждого из элементов меню.
Также обращаю внимание на функцию «stop«. Она необходима для остановки события при наведении курсора мыши на графический элемент меню.
Шаг 5.2: функция «mMouseOut».
Теперь рассмотрим сценарий функции «mMouseOut».
- Смещение элемента навигации вниз.
- Смещение блока вниз.
- Перемещение элемента навигации вверх.
- Перемещение элемента навигации до своей первоначальной позиции.
- Перемещение белого блока в исходное положение (невидимый).
- Возвращение курсора в нормальное состояние.
function mMouseOut(e)
{
$(this)
// stop any animation that took place before this
.stop()
// step.1 move down navigation item
.animate({backgroundPosition:'(' + _getHPos( this.id ) +'px 40px )'}, "fast",
// this section will be executed after the step.1 is done
function(){
// step.2 white box move really fast
$(this).children().animate({backgroundPosition:'(0px 70px)'}, "fast");
// step 3. move navigation item up
$(this).animate( {backgroundPosition:'(' + _getHPos( this.id ) +'px -40px)'}, "fast",
// this section will be executed after the step.3 is done
function(){
// step 4. move navigation item ot its original position
$(this).animate( {backgroundPosition:'(' + _getHPos( this.id ) +'px -25px)'}, "fast",
// this section will be executed after the step.4 is done
function(){
// move white box to its original position, ready for next animation
$(this).children().css({ backgroundPosition:'0px -60px'});
})
})
})
.css({backgroundImage: 'url(img/nav.jpg)', cursor: ''});
}
Шаг 5.3: функция «mClick».
Почти у цели! Теперь нам необходимо разобрать ситуацию, когда пользователь нажимает на элемент навигационного меню.
function mClick(e)
{
location.href = this.id;
}
Эта функция будет направлять пользователя в соответствии с пунктом меню.
Шаг 5.4: Текущий индикатор страницы.
Для определения текущей страницы нам необходим своеобразный индикатор. Для этого мы создадим дополнительный класс CSS и назовем его «active».
Например, если мы будем находиться на странице «Home» , то HTML код будет выглядеть так:
<div id="home"><div><a href="home">home</a></div></div>
Или так, если на странице «about».
<div id="about"><div><a href="about">about</a></div></div>
Вот окончательный вариант кода после всех изменений:
var site_url = '';
var nav = [ '#home', '#about', '#services', '#solutions', '#contact' ];
$(document).ready(function(){
setBkgPos();
for ( i = 0; i < nav.length; i++ ) {
$(nav[i]).bind( 'mouseover', mMouseOver );
$(nav[i]).bind( 'mouseout', mMouseOut );
$(nav[i]).bind( 'click', mClick );
}
for ( i = 0; i < nav.length; i++ ) {
// element with ‘active’ class will start animation
if ( $(nav[i]).get(0).className.indexOf('active') >= 0 ){
$(nav[i])
.animate({ backgroundPosition:'(' + _getHPos( nav[i] ) +'px -30px}'},"fast",
function(){
$(this)
.children()
.animate({backgroundPosition:'(0px -40px)'},20)
.animate({backgroundPosition:'(0px -20px)'},"fast");
$(this)
.animate({backgroundPosition:'(' + _getHPos( nav[i] ) +'px 50px)'},"fast")
.animate({backgroundPosition:'(' + _getHPos( nav[i] ) +'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;
}
}
});
Надеюсь у вас получилось!














