Implement a responsive multi level menu using HTML and CSS without JavaScript.

Toomtarm Kung
4 min readMay 25, 2017
Photo From: http://www.html5xcss3.com

Not every user enable the JavaScript to their browser. Some people still use the outdated browsers, some people use the low spec mobile. However, the JavaScript can slow down and consume lots of resources while the page is rendering.

The experienced front-end developers know HTMLand css very well, but have you ever known that we can implement a simple multi-level menu for the responsive website using only HTML4 and CSS2. However, the advantage of using CSS3 is the UI can smoothly toggle the menu and the font-icon.

There are 3 keys of this technique

  1. Label
  2. Checkbox
  3. CSS Selection

The concept is you create a label and style it as button, then use for to the checkbox target. Finally, use the selection of CSS to show and hide the sub-menu when the checkbox is checked and unchecked.

For the responsive menu, you can use max-width, and width.

<!DOCTYPE html>
<html lang="en-US" manifest="conference.appcache">
<head>
<meta charset="UTF-8">
<meta name="keywords" content="responsive, menu">
<meta name="description" content="Implement a responsive multi level menu using HTML4 and CSS2 without JavaScript.">
<meta name="author" content="PlaySafe">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=0">
<link rel="stylesheet" href="style.css">
<title>Implement a responsive multi level menu using HTML4 and CSS2 without JavaScript.</title>
</head>
<body>
<div id="menu_bar">
<input type="checkbox" id="menu_switch" class="hidden" checked="checked">
<nav id="navigator">
<label for="menu_switch" id="toggle"></label>
<ul>
<li><a href="#">Home Page</a></li>
<li>
<input type="checkbox" id="menu1-level1" class="switch"/>
<label for="menu1-level1" class="hasChild">Menu1</label>
<ul class="toggle">
<li><a href="https://www.google.com" target="_blank">Menu1.1 New Tab</a></li>
<li><a href="#">Menu1.2</a></li>
<li><a href="#">Menu1.3</a></li>
</ul>
</li>
<li><a href="#">Menu2</a></li>
<li><a href="#">Menu3</a></li>
<li>
<input type="checkbox" id="menu4-level1" class="switch"/>
<label for="menu4-level1" class="hasChild">Menu4</label>
<ul class="toggle">
<li><a href="#">Menu4.1</a></li>
<li><a href="#">Menu4.2</a></li>
<li><a href="#">Menu4.3</a></li>
<li><a href="#">Menu4.4</a></li>
<li><a href="#">Menu4.5</a></li>
</ul>
</li>
<li>
<input type="checkbox" id="menu5-level1" class="switch"/>
<label for="menu5-level1" class="hasChild">Menu5</label>
<ul class="toggle">
<li><a href="#">Menu5.1</a></li>
</ul>
</li>
<li>
<input type="checkbox" id="menu6-level1" class="switch"/>
<label for="menu6-level1" class="hasChild">Menu6</label>
<ul class="toggle">
<li><a href="#">Menu6.1</a></li>
<li><a href="#">Menu6.2</a></li>
<li><a href="#">Menu6.3</a></li>
</ul>
</li>
<li>
<input type="checkbox" id="menu7-level1" class="switch"/>
<label for="menu7-level1" class="hasChild">Menu7</label>
<ul class="toggle">
<li><a href="#">Menu7.1</a></li>
<li><a href="#">Menu7.2</a></li>
<li><a href="#">Menu7.3</a></li>
<li><a href="#">Menu7.4</a></li>
</ul>
</li>
</ul>
</nav>
</div>
</body>
</html>
* {
margin: 0;
padding: 0;
font-family: "Helvetica Neue", Helvetica, Verdana;
font-weight: normal;
}
body {
width: 100%;
background: hsl(40, 60%, 100%);
height: 100%;
overflow-x: hidden;
}
a {
cursor: pointer;
text-decoration: none;
}
.switch:checked ~ ul, .switch:checked ~ .toggle {
display: block;
}
.switch ~ .toggle, .hidden, .switch {
display: none;
}
.hasChild > ul {
-webkit-transition: all 0.7s ease-in-out;
-moz-transition: all 0.7s ease-in-out;
-ms-transition: all 0.7s ease-in-out;
-o-transition: all 0.7s ease-in-out;
transition: all 0.7s ease-out; /* Make any transition gradually change */
}
nav {
width: 80%; /* For small screen we set to 80% of screen width */
max-width: 16em; /* However, we still keep the maximum size of navigation when show on big screen */
right: -16em; /* Generally, we hide this menu from sight */
position: fixed; /* Menu will show on screen even if we scroll mouse*/
height: 100%; /* Full screen menu */
z-index: auto; /* Make it at the top layer (the front layer)*/
-webkit-transition: all 0.7s ease-in-out;
-moz-transition: all 0.7s ease-in-out;
-ms-transition: all 0.7s ease-in-out;
-o-transition: all 0.7s ease-in-out;
transition: all 0.7s ease-out; /* Make any transition gradually change */
}
nav > ul {
overflow-y: auto;
height: 100%;
max-height: 100%;
}
nav ul, nav li {
list-style-type: none;
}
nav ul {
position: relative;
clear: both;
}
nav li {
text-indent: 1em;
}
nav li label {
cursor: pointer;
}
nav input {
width: 80%;
padding: 0.5em;
}
nav ul li a, nav ul li label {
display: block;
padding: 1.5em 0;
text-indent: 1.5em;
}
nav ul li ul li a {
display: block;
padding: 1em 0;
text-indent: 3em;
}
nav ul li ul {
display: none;
}
#toggle:before, nav li a, nav li label {
color: hsl(255, 90%, 100%);
}
#toggle:before {
font-size: 2em;
width: 2em;
height: 2em;
line-height: 2em;
text-align: center;
}
#toggle:hover:before, nav li a:hover, nav li label:hover {
color: hsl(250, 100%, 90%);
background: hsl(0, 70%, 40%);
}
#toggle:active:before, nav li a:active {
background: hsl(0, 70%, 35%);
}
#toggle:before {
content: '\e0b8';
position: absolute;
margin: 0 0 0 -2em;
}
#toggle {
cursor: pointer;
width: 20%;
}
#menu_switch:checked + nav {
right: 0;
}
#menu_bar {
min-height: 60px;
height: 4em;
width: 100%;
}
#menu_bar, nav {
z-index: 10;
}
nav, #toggle:before {
background: hsl(0, 70%, 50%);
}

If you want to support for the extra-small screen, you might need to use @media of css3

@media screen and (max-width: 319px) {
nav {
max-width: 100%; /* For small screen */
right: -80%;
}
}

If you have the old browser like Internet Explorer 7,8 you can change the nav tag to div and try to run this code.

--

--