Responsive menu with clickable sub-menu that changes place depending screen size

Viewed 101

My best describing the situation:

The menu on mobile is vertical and on desktop is horizontal.

.menu {
        list-style-type: none;
        display: flex;
        flex-wrap: wrap;
        flex-direction: column;
        @media (min-width: 768px) {
        flex-direction: row;        
        justify-content: space-between;
      };    
    }

The first menu link is a clickable sub-menu. This complicates the situation because it means sub-menu needs to be duplicated so that on mobile(when the menu is vertical) sub-menu is in-between menu links and on desktop(when a menu is horizontal) below the menu links (so sub-menu does not break the alignment of justify-content: space-between;). HTML:

<footer>
  <hr />
  <ul class="menu">
    <li>
      <a class="toggle" href="#submenu">submenu</a>
      <ol id="submenu" class="table-of-contents toggle-content is-mobile">
        <li>
          <a href="#" class="content-entry">sub-menu</a>
        </li>
        ...
      </ol>
    </li>
    <li><a href="#">link2</a></li>
    <li><a href="#">link3</a></li>
    <li><a href="#">link4</a></li>
  </ul>
  <ol id="submenu" class="table-of-contents toggle-content is-desktop">
    <li>
      <a href="#" class="content-entry">lorem the ipsum placeholder text</a>
    </li>
    ...
  </ol>
  <hr />
  <p class="additional">some text</p>
</footer>

So far the sub-menu appears as described above, but the problem arises in making sub-menu clickable, because sub-menu has the same ID. The question is how to make sub-menu is my scenario clickable in both mobile and desktop.

Please look at jsfiddle example (changing width of result window) https://jsfiddle.net/virsis12/c4Lt2krm/31/

1 Answers

There's no need to dublicate the html for #submenu.

You should move the #submenu inside the first li element and on desktop screens, set its position to absolute. Use javascript to show or hide the sub-menu.

const toggle = document.querySelector('.toggle');
const submenu = document.getElementById('submenu');

toggle.addEventListener('click', () => {
  submenu.classList.toggle('showSubMenu');
});
ol, ul {
  list-style-type: none;
}

.menu {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
}

.submenu-container {
  position: relative;
}

.table-of-contents {
  display: none;
  box-sizing: border-box;
  padding: 10px;
  text-align: left;
  overflow: hidden;
}

.table-of-contents li {
  padding: 5px 0;
}

.showSubMenu {
  display: block;
}

@media (min-width: 768px) {
  .table-of-contents {
    background: #fff;
    position: absolute;
    box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
    top: 120%;
    left: 0;
    width: 150px;
    text-align: center;
  }
  .menu {
    flex-direction: row;
    justify-content: space-between;
  }
}
<footer class=" footer">
  <hr>
  <ul class="menu">
    <li class="submenu-container">
      <a class="toggle" href="#submenu">submenu</a>
      <ol id="submenu" class="table-of-contents">
        <li><a href="#" class="content-entry">placeholder text</a></li>
        <li><a href="#" class="content-entry">placeholder text</a></li>
        <li><a href="#" class="content-entry">placeholder text</a></li>
        <li><a href="#" class="content-entry">placeholder text</a></li>
        <li><a href="#" class="content-entry">placeholder text</a></li>
        <li><a href="#" class="content-entry">placeholder text</a></li>
      </ol>
    </li>
    <li><a href="#">link2</a></li>
    <li><a href="#">link3</a></li>
    <li><a href="#">link4</a></li>
  </ul>
  <hr>
  <p class="additional">some text</p>
</footer>

Related