Saturday, 7 November 2015
Hello? So in the
previous post, we saw how to make a CSS drop down menu. In this post we will be turning that menu into a responsive one.
On smaller screens, the menu will be invisible, but there will be a menu icon visible. When this menu icon is clicked or touched(on touchscreens) it should reveal the menu a drop-down with all the list items stacked on top of each other. Once a link is selected, the menu should close until the menu icon is pressed again.
We will use a pretty awesome check-box hack to pull this off.
How it works.
On desktop screens, the menu icon will not be displayed but on small screens the menu icon will be displayed while the menu will be hidden.
This menu icon will be linked to the check-box via a check-box label so that when the icon is clicked, it will be the same as clicking the check box itself. Therefore clicking the icon will change the status of the check-box to checked and when clicked again, it will un-check the check box.
On small screens, the menu will have a display on none. We will then have it's display set to block when the check box is checked.
The HTML.
<input type="checkbox" id="activator" />
<label for="activator">
<div class="activator">
Menu
</div>
</label>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a>
<ul>
<li><a href="#">Web Design</a></li>
<li><a href="#">Web Development</a></li>
<li><a href="#">Web Hosting</a></li>
</ul>
</li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
As you can see, compared to the markup we started with in part 1, we have added a few elements. First we start by adding an input on type checkbox with an id of "activator". We then add a label for the check-box. The label has an attribute "for" with a value of activator. This tells the label to link to an input with an id that has a value of "activator".
N.B This works with id's only.
The label then houses a div with a class of "activator" and the word "Menu" in it. This simply means that if you click the label it will activate the check-box, so clicking the div will also activate the check-box since it's inside the label. To demonstrate this, click on the word "Menu" and you will notice it activates and deactivates the check-box.
Another important note to keep in mind is that for this hack to work, the check-box, its label and the menu(in this case the input, label and nav) will have to be siblings inside a common container/parent.
CSS.
We will start by styling the div inside the label, this div is going to serve as our icon. Add the following css to your styles from where we left off in part 1.
.activator{
width: 100%;
height: 40px;
background-color: #232323;
border-bottom: 1px solid #000;
line-height: 40px;
text-align: center;
color: #fff;
cursor: pointer;
}
We give it a width of 100% and a height of 40px. The 40px line-height is to make sure that the text in the div vertically centered. We also set the text-align to center, to horizontally center the text. We give it the same background color as the menu but add a bottom black border of 1px to separate the two. The cursor is not that important since most of the devices we are targeting are touch enabled, but I put it there anyways, for the sake of this project(it's optional).
Save the css and reload the menu on the browser. You should have a menu resembling the pic below.
Now try to click anywhere in the div and you will notice that, when you click it the check box on the top left corner is checked and when you press the div again the check box unchecked.
Since we know the div can activate and deactivate the check box, there is no need for the check box to be visible. So lets hide the check box .
We know the check box has an id of "activator", so let's use that to set it's display to none.
#activator{
display: none;
}
The check box should now be hidden and the menu occupies the whole space, like in the pic below.
Now remember we said that we didn't want the menu icon/label to be visible on desktop screens, so on the div's styling we also need to set it's display to none to hide it. Next I will show us how we will make it visible on smaller screens. So add "display: none;" to the style of ".activator". The activator's class style should now be.
.activator{
width: 100%;
height: 40px;
background-color: #232323;
border-bottom: 1px solid #000;
line-height: 40px;
text-align: center;
color: #fff;
cursor: pointer;
display: none;
}
The menu should now be like how we left it off in part 1.
Alternative styling.
With CSS Media Queries, we can give elements different properties based on the width of the browsers view port. So in our case, we want the menu to have a different appearance when it's viewed on screens(view ports) that are 530px in width and below.
NB: 530px doesn't follow any standard, but it's just a value that I'm using to demonstrate this concept. Feel free to search for standard screen width for your future projects.
Media Query Syntax.
@media screen and (max-width: 530px){
/* Alternative styles go here*/
}
The code above tells the browser that if the screen has a width of 530px or below, to use the styles within that media query. basically we will be overwriting the classes that we need changed.
So the first thing we will do is hide the menu(nav) and display the div we hid earlier.
@media screen and (max-width: 530px){
nav{
display: none;
}
.activator{
display: block;
}
}
We set the nav's display to none so as to hide it and .activator's(the div we hid before) to block so as to make it visible when the screen has a width of 530px or below. To see this in action, just re size your browser to a smaller size, and you will notice that when the browser's width hits 530px, the nav disappears and the div with the label appears, magic right? Well not really.
Moving on, we now need to make the menu appear when the check-box is checked, so when it's unchecked the div should disappear again, obviously. So inside the media query, add the following CSS.
#activator:checked ~ nav{
display: block;
}
What the CSS above is doing is simply checking whether the element with an id of activator is checked. If this condition is true, it select a sibling called nav and changes it's display to block, we achieve sibling selection using the sibling selector ~ (it's a tilde , in most computers it before the key with number 1. just SHIFT + that key )
Now when you press the div with the word "Menu", the menu appears, when you press it again, the menu disappears. lucky for us we know whats going on behind the scenes.
Now a few more things, first we have to make the list items to appear stacked on top of each other and the inner ul to shift a few pixels inward to show that they are sub-menus. This will give the menu that Mobile phone feeling. So inside the media query, add the following styles.
nav ul li{
display: block;
}
nav ul ul{
display: block;
position: relative;
padding-left: 25px;
}
The code above targets the list elements and the nested ul. The first (nav ul li) sets the list items's display to block from inline-block, this will make the li items appear stacked on top of each other.
then the second style (nav ul ul) targets the nested unordered list. The first thing it does is set it's display to block from hidden so that it's always visible on smaller screens, and since we don't need the previous hover effect, we changes it's position to relative from absolute so that it lines up nicely with the other items. lastly the padding on it's left side is to help the user know that it's a sub-menu of the preceding menu link.
I hope this tutorial was informative to you. You can download the project files
here or view the demo
here .
If you have any questions, suggestions or corrections to offer please feel free to use the comments section. Thank you.
By: Unknown |
On:
Saturday, 7 November 2015
|
At: 05:16 |
IN: