Из этого туториала вы узнаете, как создать и анимировать значок меню гамбургера, а затем подключить прослушиватель событий через jQuery для вызова раскрывающегося меню.
Я буду использовать Jade (Pug) и Sass вместо ванильного HTML и CSS. Так что вы должны хотя бы иметь базовые знания об этих шаблонизаторах.
Создание детской площадки
Начнем с реализации простой игровой площадки. Я буду предоставлять только шаблон Jade вместе со стилем Sass, так как это не входит в учебник. Вы можете взять и использовать его или придумать свой собственный дизайн.
Нефритовый файл:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
body
#container
#header
#body
.content
.left
.right
— for (i=1; i <= 5 ; i++ )
div( id=»text» + i )
.content
.left
.right
— for (j=6; j <= 10 ; j++ )
div( id=»text» + j )
.content
.left
.right
— for (k=11; k <= 15 ; k++ )
div( id=»text» + k )
|
Sass файл:
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
=flex()
display: -webkit-box
display: -moz-box
display: -ms-flexbox
display: -webkit-flex
display: flex
=transition($time)
-webkit-transition: all $time ease
-moz-transition: all $time ease
-ms-transition: all $time ease
-o-transition: all $time ease
transition: all $time ease
html, body
margin: 0
padding: 20px 0
+flex()
justify-content: center
//———————————-//
#container
width: 320px
height: 550px
background-color: #ebebeb
overflow: hidden
#header
height: 45px
background-color: #9b9b9b
position: relative
#body
padding: 0 20px
padding-top: 40px
+flex()
flex-direction: column
justify-content: flex-start
.content
+flex()
flex-direction: row
justify-content: flex-start
margin-bottom: 25px
.left
width: 100px
height: 100px
margin-right: 15px
background-color: #e1e1e1
.right
@for $i from 1 through 15
#text#{$i}
margin-top: 10px
width: 50 + random(100) + px
height: 10px
background-color: #e1e1e1
|
Примечание: здесь я создал два миксина с именем flex
и transition
. Миксины облегчают повторное использование некоторых правил CSS, группируя их. Всякий раз, когда мне нужно добавить display:flex
со всеми префиксами вендора, я могу просто использовать вместо него +flex()
, благодаря mixin.
Мы будем использовать эту структуру и опираться на нее до конца урока.
Конечный результат должен выглядеть так:
Значок меню гамбургера
Теперь пришло время создать простое, но привлекательное меню для гамбургеров и анимировать его с помощью CSS.
Добавьте новый div внутри #header
и назовите его #hamburger
. Затем создайте двух дочерних #hamburger
внутри #hamburger
. Они должны иметь общий класс и индивидуальные идентификаторы.
1
2
3
|
#hamburger
.strip#top
.strip#bottom
|
Теперь нам нужно #hamburger
родительский div #hamburger
и #hamburger
div с общим классом .strip
.
1
2
3
4
5
6
7
8
|
#hamburger
height: 100%
width: 45
+flex()
flex-direction: column
justify-content: space-between
padding-left: 20px
|
Мы устанавливаем высоту div, равную его родительскому div, который является #header
, определяя height: 100%
. Также мы устанавливаем значение ширины для этого родительского элемента div, который будет определять его «активируемую» область.
Далее мы добавляем flexbox со всеми префиксами вендоров, используя миксины, которые мы создали ранее.
Поскольку мы хотим, чтобы наши .strip
.strip располагались вертикально, мы устанавливаем flex-direction: column
и затем используем justify-content: space-between
.strip
чтобы поместить пробел между .strip
.strip.
Затем нам нужно подтолкнуть эти div к друг другу, добавив нижний и верхний отступы к соответствующим div.
1
2
3
4
5
|
#top
margin-top: 17px
#bottom
margin-bottom: 17px
|
Мы также добавили padding-left: 20px
, чтобы переместить .strip
.strip дальше вправо.
Следующее, что нужно, это оформить полоски. Это относительно просто, просто определив размер и цвет элементов.
1
2
3
4
|
.strip
width: 25px
height: 2px
background-color: #ffffff
|
Окончательный результат со значком меню гамбургера должен выглядеть следующим образом:
Следующее, что нужно сделать, это анимировать значок меню, чтобы при щелчке он превращался в знак креста.
Анимация иконки меню гамбургера
На этом этапе мы собираемся использовать базовый jQuery для переключения некоторых классов CSS.
Давайте сначала создадим CSS-классы для переключения.
Мы будем использовать настройки translate и rotate свойства transform
CSS вместе со свойством transition
.
Сначала добавьте переходы в #top
и #bottom
, используя миксины с определенным параметром синхронизации.
1
2
3
4
5
6
7
|
#top
margin-top: 17px
+transition(.25s)
#bottom
margin-bottom: 17px
+transition(.25s)
|
Теперь нам нужно определить стили классов, которые будут переключаться.
Мы будем вращать и переводить каждый .strip
div по отдельности, поэтому нам нужно переключать разные классы как для #top
и #bottom
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
#top
margin-top: 17px
+transition(.25s)
&.topRotate
transform-origin: center
transform: translateY(4px) rotateZ(45deg)
#bottom
margin-bottom: 17px
+transition(.25s)
&.bottomRotate
transform-origin: center
transform: translateY(-5px) rotateZ(-45deg)
|
Здесь мы определили стиль для двух разных классов с именами .bottomRotate
и .topRotate
, которые будут добавлены и удалены из соответствующих ссылок на #top
, #top
и #bottom
.
Обратите внимание, что разные размеры класса .strip
могут привести к необходимости использования разных значений translateY
и rotateZ
, чтобы анимировать их в правильный крестик.
Класс Переключение с JQuery
Мы определили, как каждый .strip
div будет анимироваться, когда topRotate
классы topRotate
и bottomRotate
. Однако нам еще предстоит подключить прослушиватель событий для переключения этих классов.
Создайте новый файл JavaScript и используйте следующий код для переключения классов #top
и #bottom
идентификаторами #top
и #bottom
соответственно.
1
2
3
4
5
6
|
$(document).ready(function(){
$(«#hamburger»).click(function(){
$(«#top»).toggleClass(«topRotate»);
$(«#bottom»).toggleClass(«bottomRotate»);
});
})
|
Мы помещаем весь наш код в $(document).ready(function(){})
, чтобы дождаться загрузки всей страницы, прежде чем предпринимать какие-либо действия.
Когда мы #hamburger
div #hamburger
, он переключает классы для div с конкретными идентификаторами.
Примечание. Не забудьте добавить исходный файл jQuery в ваш проект.
Создание списка меню
Следующим шагом является создание меню с элементами списка.
Используйте следующую структуру под #header
:
1
2
3
4
5
6
7
8
9
|
#dropDown
#background
ul
li Home
li Blog
li Projects
li Authors
li Jobs
li Contact
|
Поэтому здесь мы использовали тег ul
в качестве родительского для того, чтобы сгруппировать элементы с тегами li
качестве дочерних. Более того, чтобы создать расширяющуюся фоновую анимацию, мы также добавили div с идентификатором #background
.
Давайте сначала li
элементы ul
и li
.
1
2
3
4
|
ul
list-style: none
padding: 0
margin: 0
|
Установите list-style
в none
, чтобы удалить маркеры из элементов ul
а также установите для padding
и margin
значение 0, чтобы удалить все предопределенные значения.
Теперь стиль элементов li
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
li
//display: none
background-color: #9b9b9b
color: #ffffff
font-family: ‘Quicksand’, sans-serif
font-weight: lighter
font-size: 15px
padding: 20px
padding-left: 60px
&:after
position: absolute
content: »
left: 60px
width: 60%
height: 1px
bottom: 4px
background: rgba(255, 255, 255, 0.25)
&:last-child:after
width: 0
|
Здесь я закомментировал display:none
, чтобы можно было увидеть результат. Однако при анимации мы будем использовать его, чтобы изначально скрыть элементы списка.
Я также добавил псевдоэлемент after
и стилизовал его соответственно, чтобы отделить каждый элемент li
прямой линией. :last-child:after
удаляет эту строку для последнего элемента li
.
Анимация списка меню
Теперь мы собираемся использовать некоторые директивы управления Sass для добавления анимации ключевых кадров CSS с различными атрибутами к каждому элементу li
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@keyframes drop
0%
opacity: 0
transform: scale(1.3)
100%
opacity: 1
transform: scale(1)
@keyframes fold
0%
opacity: 1
transform: scale(1)
100%
opacity: 0
transform: scale(0.7)
|
Здесь мы определили анимацию ключевого кадра « drop
and fold
.
drop
для анимации открытия списка меню. Начальное масштабирование на 30% больше, и оно уменьшается до исходного размера, когда прозрачность изменяется от 0 до 1. Противоположное действие происходит в fold
.
Теперь нам нужно прикрепить эти ключевые кадры к элементам li
. В этой части Sass пригодится.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@for $i from 1 through 6
li:nth-child(#{$i})
animation:
name: fold
duration: 80ms*(6-$i) + 1ms
timing-function: ease-in-out
fill-mode: forwards
li.anim:nth-child(#{$i})
animation:
name: drop
duration: 100ms*$i
timing-function: ease-in-out
fill-mode: forwards
|
Здесь я использовал цикл for, который идет от 1 до 6 с индексом $i
.
Теперь нам нужно использовать этот индекс, чтобы прикрепить каждую анимацию к элементам li
разной длительности.
Сначала рассмотрим li.anim:nth-child(#{$i})
.
Здесь мы берем $i
й дочерний элемент элемента li
с классом anim
.
Мы будем переключать этот класс anim
. Таким образом, при добавлении к элементам li
анимация ключевого кадра с именем drop
будет действовать. Когда он будет удален, анимация fold
будет действовать.
Следующая важная вещь — это атрибут duration
.
duration: 100ms*$i
для анимации drop
увеличивает продолжительность анимации для каждого увеличивающегося дочернего числа. Итак, когда этот код скомпилирован, первый дочерний duration: 600ms
будет иметь duration: 100ms
, а последний дочерний duration: 600ms
будет иметь duration: 600ms
.
Это даст смысл анимации каждого элемента один за другим.
Мы делаем то же самое для fold
анимации. На этот раз последний элемент должен быть анимирован быстрее, следовательно, duration: 80ms*(6-$i) + 1ms
. Добавление 1 мс к длительности связано с тем, что при установке длительности на 0 могут возникнуть некоторые проблемы, и ваша анимация может работать некорректно.
Когда мы разрабатывали элемент li
, я упоминал, что нам нужно использовать display:none
, чтобы избежать нежелательного воспроизведения анимации. Если вы не установите его в none
, вы увидите, что анимация fold
проигрывается один раз при загрузке страницы.
Если мы установим для свойства display
значение none
, мы этого не увидим, а затем нам нужно показать элемент li
перед переключением класса anim
.
Мы хотим, чтобы наша анимация воспроизводилась, когда мы щелкаем значок гамбургера. Итак, давайте используем jQuery для установки свойства display
каждого элемента li
для block
а также для переключения класса anim
.
01
02
03
04
05
06
07
08
09
10
|
$(document).ready(function(){
$(«#hamburger»).click(function(){
$(«#top»).toggleClass(«topRotate»);
$(«#bottom»).toggleClass(«bottomRotate»);
$(«li»).show();
$(«li»).toggleClass(«anim»);
});
})
|
Вы заметите, что мы можем видеть анимацию каждого элемента li
отдельности. Тем не менее, мы бы предпочли ощущение расширения меню.
Чтобы это исправить, нам просто нужно увеличить высоту div. Это div #background
, который мы изначально добавили при создании элементов ul
и li
.
1
2
3
4
5
6
7
8
9
|
#background
width: 100%
height: 0
background-color: #9b9b9b
position: absolute
+transition(.45s)
&.expand
height: 550px
|
Мы будем переключать класс expand
, чтобы установить для атрибута height
значение 550px
течение .45s
. Обратите внимание, что я использовал transition
миксин для определения перехода с определенным параметром времени.
Вывод
На протяжении всего этого урока мы практиковались в использовании циклов в HTML и CSS с помощью шаблонизаторов Jade и Sass. Кроме того, мы создали анимации ключевых кадров CSS и прикрепили их с различными атрибутами продолжительности к определенным элементам HTML. Затем мы переключили классы с помощью jQuery для управления этими анимациями.