Skip to content

Creating slide out or drop down mobile menus with CSS

A while ago I created my submission for a simple project for the Udacity Front End Web Developer nanodegree. The brief was to design and implement a responsive home page for a web site.

One interesting restriction they set was a ban on using JavaScript, which made things a bit more interesting when it came to create a drop down menu for the mobile view.

The web site home page in mobile view showing the menu in closed and open states.
The mobile view menu in closed and open states.

Normally I would immediately turn to JavaScript for something like this, so it was interesting to be forced out of my comfort zone and come up with a solution using only HTML and CSS.

Now I knew that CSS could be used to animate a transition between states. So in this case, the menu can initially be positioned just to the right of the visible part of the page, so it is not seen and then transition into view when needed.

#main-nav {
  transition: left 0.5s ease;
  position: fixed;
  top: 0;
  left: 101%;
  width: 35%;
  background-color: #2d3c49;
  padding: 1em;
  z-index: 2;
}

You can see in line 5 of the CSS for the menu, I set it’s left edge to be at 101%, which means it will initially sit to the right of the visible page and it will not be seen. In line 2 I add a transition, so that if the left property is ever changed, rather than jumping instantly to that point, it will slide smoothly.

The challenge for me was how to trigger the menu to open and close. Normally I would solve this by simply adding event listeners to the burger menu button and the close button and then have handlers that simply set a new value for the left style property. But that wasn’t an option for this assignment.

The solution is a really useful CSS pseudo class :target. This enables a class to be applied to any element whose id is a target in the URL. Have a look at the HTML for this part of the page:

<header>
  <div id="logo">
    <img src="img/logo.svg" alt="Personal logo for Laurence Scotford">
  </div>
  <div id="title">
    <h1>Laurence Scotford</h1>
    <h2>Front End Web Developer</h2>
  </div>
  <a id="menu" href="#main-nav"><img src="img/burger.svg" alt="Hamburger menu"></a>
</header>
<nav id="main-nav">
  <a href="#" id="close-nav">CLOSE</a>
  <a href="#" class="nav-item active">HOME</a>
  <a href="#" class="nav-item">PORTFOLIO</a>
  <a href="#" class="nav-item">BLOG</a>
  <a href="#" class="nav-item">ABOUT</a>
</nav>

In line 11 you can see that the menu has an id of main-nav. In line 9, the burger menu button has a link to #main-nav. This is going to change the url from <site url>/index.htm to <site url>/index.htm#main-nav. Note also in line 12, the close button has a link to #. This will change the url from <site url>/index.htm#main-nav to <site url>/index.htm#. You’ll also see the other links are the same. If this was a full site rather than just a front page demo, these would point to different parts of the site.

Now because the menu is positioned at the top of the page, these changes to the url are not going to affect the vertical positioning of the page. So how does this help me? Well, this is where the :target pseudo class comes in.

#main-nav:target {
  left: 65%;
}

This rule will be applied whenever the url ends with #main-nav. At this point, the left property changes to 65% and, because of the transition set in the earlier CSS, it will slide nicely into view. When the Close button is clicked, that element of the url is removed and the menu will slide back to its original position.

So this is a really elegant way of creating simple menus and sidebars rather than the brute force approach of using event handlers in JavaScript.

You can see this in action using the live link or by watching this short video:

You can see the full source code on GitHub.

Published inProgramming

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *