Vincenzo Vincenzo - 1 year ago 142
CSS Question

Responsive Menu, Multi-level, CSS and Javascript ONLY, no jQuery


Using ONLY javascript and CSS, I need to create a responsive menu. The menu must also supports one level sub-menus.

Due to the memory limitations of the embedded hardware, I cannot use external libraries/frameworks.

I have browsed as much as I could. The examples I have found don't quite address my problem.

  • If the menu is responsive, it does not support sub-menus ...

  • If it supports sub-menus, the submenus expand within the menus, instead of replacing them ...

  • If it does everything I need, then it is in jQuery, and I cannot use it ...

I have been 'piecing' together snippets of code (

However, I am now stuck with the following problem. Because I embedded the submenu (id="myDropdown")

<div class="dropdown-content" id="myDropdown">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>

within the main menu (id="myTopnav"), I don't manage to display the submenu when in the minimized state.

The only solution I could come up with is to duplicate the submenu (id="myDropdown2")

<div class="dropdown-content" id="myDropdown2">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>

which, of course, is "so wrong on so many different levels" ... :-)

Can you improve my code in such a way that I am using only one occurrence of the submenu? A link to a JSFiddle, CodePen, or similar would be extremely helpful ...

Please NO jQuery. I can only use javascript and CSS. However, if you are aware of a little js-css-only library that achieves what I am looking for (MIT license), that will also do the trick ... :-)

Thank you so much ...


Answer Source

Here is a "not so simple" demo of responsive navigation taken from w3schools, and modified by me to show a simple submenu behavior.

The most important part here to take note is that you might have to create a function to close other submenus, when you open another one and edit the non responsive CSS.

function myFunction() {
    var x = document.getElementById("myTopnav");
    if (x.className === "topnav") {
        x.className += " responsive";
    } else {
        x.className = "topnav";
function openSubMenu() {
    var x = document.getElementById("submenuNav");
    if (x.hidden === true) {
        x.hidden = false;
    } else {
        x.hidden = true;
body {margin:0;}
ul.topnav {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: #333;

ul.topnav li {float: left;}

ul.topnav li a {
  display: inline-block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  transition: 0.3s;
  font-size: 17px;

ul.topnav li a:hover {background-color: #555;}

ul.topnav li.icon {display: none;}

@media screen and (max-width:680px) {
  ul.topnav li:not(:first-child) {display: none;}
  ul.topnav li.icon {
    float: right;
    display: inline-block;

@media screen and (max-width:680px) {
  ul.topnav.responsive {position: relative;}
  ul.topnav.responsive li.icon {
    position: absolute;
    right: 0;
    top: 0;
  ul.topnav.responsive li {
    float: none;
    display: inline;
  ul.topnav.responsive li a {
    display: block;
    text-align: left;
<ul class="topnav" id="myTopnav">
  <li><a class="active" href="#home">Home</a></li>
  <li><a href="#news">News</a></li>
  <li><a href="#contact"  onclick="openSubMenu()">Contact</a>
  <ul class="subnav" id="submenuNav" hidden >
      <li><a href="#contact" class="submenu">Sub Menu1</a></li>
      <li><a href="#contact" class="submenu">Sub Menu2</a></li>
      <li><a href="#contact" class="submenu">Sub Menu3</a></li>
  <li><a href="#about">About</a></li>
  <li class="icon">
    <a href="javascript:void(0);" style="font-size:15px;" onclick="myFunction()">☰</a>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download