Sie sind auf Seite 1von 13

Creating a Drop-Down

Menu for Mobile Pages


by Dogacan Bilgili19 Jan 2018
Difficulty:IntermediateLength:MediumLanguages:
JadeSassjQueryJavaScriptCSSWeb Development
This tutorial will teach you how to create and animate a hamburger menu icon and
then attach an event listener through jQuery for triggering a drop-down menu.

I will be using Jade (Pug) and Sass instead of vanilla HTML and CSS. So you should
at least have a basic knowledge of these templating engines.

Creating the Playground


We will start with the implementation of a simple playground. I will only be
providing the Jade template along with Sass styling, since this is not the scope of the
tutorial. You can take it and use it or you can come up with your own design.

Jade file:
01
body
02 #container
03 #header
04 #body
05 .content
06 .left
.right
07 - for (i=1; i <= 5 ; i++ )
08 div( id="text" + i )
09 .content
10 .left
.right
11 - for (j=6; j <= 10 ; j++ )
12 div( id="text" + j )
13 .content
14 .left
15 .right
- for (k=11; k <= 15 ; k++ )
16 div( id="text" + k )
17
18
19
Sass file:
01 =flex()
display: -webkit-box
02 display: -moz-box
03 display: -ms-flexbox
04 display: -webkit-flex
05 display: flex
06
07 =transition($time)
-webkit-transition: all $time ease
08 -moz-transition: all $time ease
09 -ms-transition: all $time ease
10 -o-transition: all $time ease
11 transition: all $time ease
12
html, body
13 margin: 0
14 padding: 20px 0
15 +flex()
16 justify-content: center
17
18 //----------------------------------//
19
#container
20 width: 320px
21 height: 550px
22 background-color: #ebebeb
23 overflow: hidden
24
#header
25
height: 45px
26 background-color: #9b9b9b
27 position: relative
28
29
30 #body
31 padding: 0 20px
padding-top: 40px
32 +flex()
33
34 flex-direction: column
35 justify-content: flex-start
36
37 .content
38 +flex()
39
flex-direction: row
40 justify-content: flex-start
41 margin-bottom: 25px
42
43
44 .left
45 width: 100px
height: 100px
46 margin-right: 15px
47 background-color: #e1e1e1
48
49 .right
50 @for $i from 1 through 15
#text#{$i}
51 margin-top: 10px
52 width: 50 + random(100) + px
53 height: 10px
54 background-color: #e1e1e1
55
56
57
58
59
60
61
62
63
Note: Here I created two mixins named flex and transition . Mixins make it
easier to reuse some CSS rules by grouping them. Whenever I need to
add display:flex with all vendor prefixes, I can just use +flex() instead, thanks
to the mixin.

We will use this structure and build upon it for the rest of the tutorial.

The final result should look like this:


View the current code

Hamburger Menu Icon


Now it is time to create a simple yet attractive hamburger menu and animate it
through CSS.

Add a new div inside #header and name it #hamburger . Then create two children
divs inside #hamburger . They should have a common class and individual IDs.
1 #hamburger
2 .strip#top
3 .strip#bottom
Now we need to style the parent #hamburger div and the children divs with the
common class of .strip .

1
#hamburger
2 height: 100%
3 width: 45
4 +flex()
5
6 flex-direction: column
justify-content: space-between
7 padding-left: 20px
8
We set the height of the div equal to its parent div, which is #header , by defining
the height: 100% . Also, we set a width value for this parent div, which will define
its "clickable" region.

Next, we add flexbox with all vendor prefixes by using mixins, which we created
earlier.

Since we want our .strip divs to be positioned vertically, we set flex-direction:


column and then use justify-content: space-between in order to put space in
between the .strip divs.

Then we need to push those divs towards each other by adding bottom and top
padding to the respective divs.
1 #top
2 margin-top: 17px
3
4 #bottom
5 margin-bottom: 17px

We also added padding-left: 20px in order to move the .strip divs further to the
right.

The next thing is to style the strips. This is relatively easy by just defining the size and
the color of the divs.
1 .strip
2 width: 25px
3 height: 2px
4 background-color: #ffffff

The final result with the hamburger menu icon should look like this:

The next thing is to animate the menu icon so that when it is clicked, it should animate
into a cross sign.

Animating the Hamburger Menu Icon


At this point, we are going to use basic jQuery to toggle some CSS classes.

Let's first create the CSS classes to be toggled.

We are going to utilize the translate and rotate settings of the transform property of
CSS along with the transition property.

First, add transitions to both the #top and #bottom divs by using mixins with a
specific timing parameter.
1 #top
2 margin-top: 17px
3 +transition(.25s)
4
5 #bottom
6 margin-bottom: 17px
+transition(.25s)
7
Now we need to define the styling of the classes to be toggled.

We will be rotating and translating each .strip div individually, so we need to


toggle different classes both for the #top and #bottom divs.

01
02 #top
03 margin-top: 17px
+transition(.25s)
04
05 &.topRotate
06 transform-origin: center
07 transform: translateY(4px) rotateZ(45deg)
08
09 #bottom
10 margin-bottom: 17px
+transition(.25s)
11
12 &.bottomRotate
13 transform-origin: center
14 transform: translateY(-5px) rotateZ(-45deg)
15
Here we defined the styling for two different classes
named .bottomRotate and .topRotate , which will be added to and removed from
their respective reference divs, #top and #bottom .
Note that different sizing of the .strip class would result in a need for
different translateY and rotateZ values in order to animate into a proper cross
sign.

Class Toggling With jQuery


We defined how each .strip div will animate when
the topRotate and bottomRotate classes are present. However, we have yet to
attach an event listener to toggle those classes.

Create a new JavaScript file and use the following code to toggle
the topRotate and bottomRotate classes to divs with #top and #bottom IDs
respectively.
1 $(document).ready(function(){
2 $("#hamburger").click(function(){
3 $("#top").toggleClass("topRotate");
4 $("#bottom").toggleClass("bottomRotate");
5 });
})
6
We put all our code inside $(document).ready(function(){}) in order to wait for
the whole page to be loaded before taking any action.

When we click the #hamburger div, it will toggle the classes for divs with specific
IDs.

Note: Do not forget to add the jQuery source file into your project.

View the current code

Creating the Menu List


The next step is to create a menu with list items.

Use the following structure under the #header :


1
2 #dropDown
#background
3 ul
4 li Home
5 li Blog
6 li Projects
li Authors
7 li Jobs
8 li Contact
9
So here we used the ul tag as the parent in order to group the items with li tags as
children. Moreover, in order to create an expanding background animation, we also
added a div with the ID of #background .

Let's style the ul and li elements first.

1 ul
2 list-style: none
3 padding: 0
4 margin: 0

Set the list-style to none in order to remove the bullets from the ul elements
and also set both padding and margin to 0 in order to remove all predefined values.

Now style the li elements:

01 li
02 //display: none
03 background-color: #9b9b9b
color: #ffffff
04
05 font-family: 'Quicksand', sans-serif
06 font-weight: lighter
07 font-size: 15px
08 padding: 20px
padding-left: 60px
09
10 &:after
11 position: absolute
12 content: ''
13 left: 60px
14 width: 60%
height: 1px
15 bottom: 4px
16 background: rgba(255, 255, 255, 0.25)
17
18 &:last-child:after
19 width: 0
20
21
22
Here I commented out the display:none in order to be able to see the result.
However, when animating, we will use it to hide the list elements initially.

I also added the after pseudo-element and styled it accordingly in order to separate
each li element with a straight line. :last-child:after removes this line for the
last li element.

View the current code

Animating the Menu List


Now we are going to use some Sass control directives in order to add CSS keyframe
animations with different attributes to each li element.

01
02 @keyframes drop
03 0%
04 opacity: 0
transform: scale(1.3)
05
06 100%
07 opacity: 1
08 transform: scale(1)
09
10 @keyframes fold
11 0%
opacity: 1
12 transform: scale(1)
13
14 100%
15 opacity: 0
16 transform: scale(0.7)
17
Here we defined our keyframe animations drop and fold .
drop is for animating the opening of the menu list. The initial scaling is 30% more,
and it scales back down to the original size as the transparency goes from 0 to 1. The
opposite action takes place in fold .

Now we need to attach those keyframes to li elements. This part is where the Sass
comes in handy.
01
02 @for $i from 1 through 6
03 li:nth-child(#{$i})
04 animation:
name: fold
05 duration: 80ms*(6-$i) + 1ms
06 timing-function: ease-in-out
07 fill-mode: forwards
08
09 li.anim:nth-child(#{$i})
animation:
10 name: drop
11 duration: 100ms*$i
12 timing-function: ease-in-out
13 fill-mode: forwards
14
Here I used a for loop that goes from 1 to 6 with the index of $i .

Now we need to use this index to attach each animation to li elements with different
durations.

First, consider the li.anim:nth-child(#{$i}) line.

Here we are grabbing the $i th child of the li element with class of anim .

We will be toggling this anim class. So, when it is added to li elements, the
keyframe animation with the name of drop will take action. When it is removed,
the fold animation will take action.

The next important thing is the duration attribute.


duration: 100ms*$i for the drop animation is extending the duration of the
animation for each incrementing child number. So, when this code is compiled, the
first li child will have duration: 100ms , and the last child will have duration:
600ms .

This will give the sense of animating each element one after another.

We do the same thing for the fold animation. This time, the last element should be
animated faster, hence duration: 80ms*(6-$i) + 1ms . The 1ms added to the
duration is due to the fact that when you set the duration to 0, some problems are
likely to occur, and your animation might not work properly.

When we were styling the li element, I mentioned that we needed to


use display:none in order to avoid undesired animation playing. If you don't set it
to none , you will see that the fold animation plays once when the page is loaded.

If we set the display property to none , we won't see that, and then we need
to show the li element before toggling the anim class.

We want our animations to play when we click the hamburger icon. So let's use some
jQuery to set the display property of each li item to block and also toggle
the anim class.

01
$(document).ready(function(){
02 $("#hamburger").click(function(){
03 $("#top").toggleClass("topRotate");
04 $("#bottom").toggleClass("bottomRotate");
05
06 $("li").show();
07 $("li").toggleClass("anim");
08
});
09 })
10
View the current code
You will notice that we can see the animation of each li element individually.
However, we'd rather have an expanding menu feeling.

In order to fix that, we simply need to expand the height of a div. That div
is #background , which we initially added when creating the ul and li elements.

1
#background
2 width: 100%
3 height: 0
4 background-color: #9b9b9b
5 position: absolute
6 +transition(.45s)
7
&.expand
8 height: 550px
9
We will be toggling the expand class in order to set the height attribute
to 550px within .45s . Note that I used the transition mixin to define the
transition with a specific time parameter.

Final Result

Conclusion
Throughout this tutorial, we practiced how to use for loops within HTML and CSS
through the Jade and Sass templating engines. On top of that, we created CSS
keyframe animations and attached them with different duration attributes to specific
HTML elements. Then we toggled classes with jQuery to control those animations.

Das könnte Ihnen auch gefallen