5

Pure CSS toggle-based Responsive Unlimited Levels Menu

Share Button

This is a brief tutorial to show you how to create a simple CSS-only responsive menu. You can find ready-to-use menus if you google for ‘pure css responsive menu’ and you will find variety of ways but most of them involves Javascript. I am going to use an approach which doesn’t require Javascript (unless you want to support older browsers).

Responsive CSS Menu

We will cover these steps:

Prepare HTML

We will using following HTML for tutorial:

Result

Click the Edit button shown below to open the demo in new window.

See the Pen BIefm by Aamir Afridi (@aamirafridi) on CodePen.

This is just an example where we have created a menu for up to 4 levels.

CSS to style the menu for desktop browsers

Next step is we will going to style it for desktop browsers i.e. for large screens. We need to add following CSS:

Result

Hover over Menu 1 > Menu 1.3 > Menu 1.3.2 > Menu 1.3.2.1 to see depest level.

See the Pen phKif by Aamir Afridi (@aamirafridi) on CodePen.

 

Now that we have pure CSS based Menu (with submenus) ready, Lets jump to how can we make it responsive.

Make it responsive by adding media query

First of all we will make some changes to the HTML by adding a checkbox and a label right before the parent <ul>. We will use this checkbox and label to toggle the menu in responsive mode. We will hide them by default and make it visible inside media query.

Changes to html

To get the three lines menu icon, you can read this useful article by the awesome dude @ChrisCoyier. Also try this codepen.

Hide the checkbox and label

Add following at the end of CSS code we wrote in above example.

Media query for responsive design

Now its upto you that at what screen size you want to make the menu responsive. Also depends on how wide is the menu, when it starts breaking when you narrow down the browser window.

Here we will assume that our menu is breaking at 400px width so we will add media query accordingly.

Also we are showing menu and submenus vertically by slightly indenting submenu items to show the hierarchy.

In the following CSS we are simply displaying the menu whenever user clicks the menu label which will toggle the checkbox and hence we can target the menu using :checked pseudo-selector.

Final Result

Resize the following box to see the result, using this bar ————————————v

See the Pen yEtbC by Aamir Afridi (@aamirafridi) on CodePen.


You can also do slightly adjustment to the CSS to make the menu on the top of content. Here is how:

Add some CSS animations

You can add some fading effects using CSS transitions. First set the opacity set to zero and then on hover make it 1.

Here are the changes you need in following selectors:

Result:

See the Pen qnwGj by Aamir Afridi (@aamirafridi) on CodePen.

Get the result in HAML with SASS

Here is the example to see how the above example can be written in HAML and SASS. Note I am using .SCSS not .SASS (Google for difference).

See the Pen dpHuI by Aamir Afridi (@aamirafridi) on CodePen.

Adding more options using JS (optional)

I cannot figure out how the menu can be closed if you click/tap outside the menu area using just CSS. So I have to use some Javascript. Here is the example.
Note: you can try :active pseudo but doesn’t give exactly what I am after.

This is how you can achieve this using jQuery:

Result

Expend the menu, scroll to the bottom and click are outside the menu to close it. You can also add SlideUp/down animations using jQuery but I would prefer performance over animations :)

See the Pen wxsgG by Aamir Afridi (@aamirafridi) on CodePen.


Final Result

Helpful links

Share Button
  • Melissa

    Hi there! I just created a responsive menu based off of your code here, so thanks! The issue I’m having is that ios7 doesn’t support labels, so when viewed on an iphone/ipad the menu cannot be clicked open. I’ve already tried several workarounds (including adding onclick=”” to the label and styling the label with cursor:pointer). Is there any way you can supply some jQuery to make this work on ios7? Thanks so much!

    • http://www.aamirafridi.com/ Aamir Afridi

      get rid of label and use the checkbox directly. Style the checkbox as burger sign using :after or :before. I hope you got the clue.

  • JenZzz

    Old comments I know, but perhaps nevertheless useful …
    I’ve changed ‘checkbox’ and ‘label’ tags to ‘button’ tag and the ‘checked’ selector to ‘focus’, the advantage of this changes are, buttons are easier to style and focus is a css2 selector which expands the compatibilty with old browsers. And it solves the ‘click anywhere to close’.
    I’ve not tested it on all browsers, systems, phones, etc. but on the few I’ve tested, it works like a charm …
    Please let me know, what you think about this.

    • JenZzz

      Please forget it … you can’t click any Link in menu, it hides instantly if focus is lost.

  • mo

    Hey it’s an old post to ask but can we hide and display submenu under parent items on click/touch for mobile in css?

Copyright © 2017 — musings of Aamir Afridi