Multilevel Accordion Menu with Plain HTML & CSS

Category: Accordion , CSS & CSS3 , Menu & Navigation | November 3, 2015
Author: alexdevero
Views Total: 6,003
Official Page: Go to website
Last Update: November 3, 2015
License: MIT

Preview:

Multilevel Accordion Menu with Plain HTML & CSS

Description:

A simple Html5 / CSS3 approach to making a multilevel sliding accordion menu from nested html lists. It uses checkbox+label hacks for toggling hierarchical menus and several CSS3 properties for smooth sliding effects.

How to use it:

Include the Font Awesome 4 for menu toggle icons.

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

Create a 3-level accordion menu following the markup structure like this:

<nav class="nav" role="navigation">
  <ul class="nav__list">
    <li>
      <input id="group-1" type="checkbox" hidden />
      <label for="group-1"><span class="fa fa-angle-right"></span> First level</label>
      <ul class="group-list">
        <li><a href="#">1st level item</a></li>
        <li>
          <input id="sub-group-1" type="checkbox" hidden />
          <label for="sub-group-1"><span class="fa fa-angle-right"></span> Second level</label>
          <ul class="sub-group-list">
            <li><a href="#">2nd level nav item</a></li>
            <li><a href="#">2nd level nav item</a></li>
            <li><a href="#">2nd level nav item</a></li>
            <li>
              <input id="sub-sub-group-1" type="checkbox" hidden />
              <label for="sub-sub-group-1"><span class="fa fa-angle-right"></span> Third level</label>
              <ul class="sub-sub-group-list">
                <li><a href="#">3rd level nav item</a></li>
                <li><a href="#">3rd level nav item</a></li>
                <li><a href="#">3rd level nav item</a></li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
    </li>
    <li>
      <input id="group-2" type="checkbox" hidden />
      <label for="group-2"><span class="fa fa-angle-right"></span> First level</label>
      <ul class="group-list">
        <li>
          <li><a href="#">1st level item</a></li>
          <li><a href="#">1st level item</a></li>
          <input id="sub-group-2" type="checkbox" hidden />
          <label for="sub-group-2"><span class="fa fa-angle-right"></span> Second level</label>
          <ul class="sub-group-list">
            <li><a href="#">2nd level nav item</a></li>
            <li><a href="#">2nd level nav item</a></li>
            <li>
              <input id="sub-sub-group-2" type="checkbox" hidden />
              <label for="sub-sub-group-2"><span class="fa fa-angle-right"></span> Third level</label>
              <ul class="sub-sub-group-list">
                <li><a href="#">3rd level nav item</a></li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
    </li>
    <li>
      <input id="group-3" type="checkbox" hidden />
      <label for="group-3"><span class="fa fa-angle-right"></span> First level</label>
      <ul class="group-list">
        <li>
          <li><a href="#">1st level item</a></li>
          <li><a href="#">1st level item</a></li>
          <input id="sub-group-3" type="checkbox" hidden />
          <label for="sub-group-3"><span class="fa fa-angle-right"></span> Second level</label>
          <ul class="sub-group-list">
            <li><a href="#">2nd level nav item</a></li>
            <li><a href="#">2nd level nav item</a></li>
            <li><a href="#">2nd level nav item</a></li>
            <li>
              <input id="sub-sub-group-3" type="checkbox" hidden />
              <label for="sub-sub-group-3"><span class="fa fa-angle-right"></span> Third level</label>
              <ul class="sub-sub-group-list">
                <li><a href="#">3rd level nav item</a></li>
                <li><a href="#">3rd level nav item</a></li>
                <li><a href="#">3rd level nav item</a></li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
    </li>
    <li>
      <input id="group-4" type="checkbox" hidden />
      <label for="group-4"><span class="fa fa-angle-right"></span> First level</label>
      <ul class="group-list">
        <li>
          <li><a href="#">1st level item</a></li>
          <input id="sub-group-4" type="checkbox" hidden />
          <label for="sub-group-4"><span class="fa fa-angle-right"></span> Second level</label>
          <ul class="sub-group-list">
            <li><a href="#">2nd level nav item</a></li>
            <li><a href="#">2nd level nav item</a></li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</nav>

Styling top level menu items.

.nav a, .nav label {
  display: block;
  padding: .85rem;
  color: #fff;
  background-color: #151515;
  box-shadow: inset 0 -1px #1d1d1d;
  -webkit-transition: all .25s ease-in;
  transition: all .25s ease-in;
}

.nav a:focus, .nav a:hover, .nav label:focus, .nav label:hover {
  color: rgba(255, 255, 255, 0.5);
  background: #030303;
}

.nav label { cursor: pointer; }

Styling sub menu items.

/**
 * Styling first level lists items
 */

.group-list a, .group-list label {
  padding-left: 2rem;
  background: #252525;
  box-shadow: inset 0 -1px #373737;
}

.group-list a:focus, .group-list a:hover, .group-list label:focus, .group-list label:hover { background: #131313; }

/**
 * Styling second level list items
 */

.sub-group-list a, .sub-group-list label {
  padding-left: 4rem;
  background: #353535;
  box-shadow: inset 0 -1px #474747;
}

.sub-group-list a:focus, .sub-group-list a:hover, .sub-group-list label:focus, .sub-group-list label:hover { background: #232323; }

/**
 * Styling third level list items
 */

.sub-sub-group-list a, .sub-sub-group-list label {
  padding-left: 6rem;
  background: #454545;
  box-shadow: inset 0 -1px #575757;
}

.sub-sub-group-list a:focus, .sub-sub-group-list a:hover, .sub-sub-group-list label:focus, .sub-sub-group-list label:hover { background: #333333; }

/**
 * Hide nested lists
 */

.group-list, .sub-group-list, .sub-sub-group-list {
  height: 100%;
  max-height: 0;
  overflow: hidden;
  -webkit-transition: max-height .5s ease-in-out;
  transition: max-height .5s ease-in-out;
}

.nav__list input[type=checkbox]:checked + label + ul { /* reset the height when checkbox is checked */
max-height: 1000px; }

Rotating chevron icon on toggle.

label > span {
  float: right;
  -webkit-transition: -webkit-transform .65s ease;
  transition: transform .65s ease;
}

.nav__list input[type=checkbox]:checked + label > span {
  -webkit-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  transform: rotate(90deg);
}
  • ttouinta

    hello is there any way so to keep the state? I mean to keep open the menu according whice page is open. thank you

  • Jeff Cartwright

    This was the best accordion menu on the web. Tried out about ten, and all had some limitation or another. Your implementation was great and did everything I needed. I made a few changes, but mostly cosmetic. I posted my changed here: http://www.instructables.com/id/Accordion-Menu/

  • gr8kodr

    The Accordion works great, and it’s implementation was easy to understand … I updated the font-awesome call to the latest version (4.7.0), one issue though – the page doesn’t validate as HTML5. Is there any way to fix so that it validates without breaking it?

  • Roy Goring

    Great Accordion – is there a way to close any open ‘first level’ when another ‘first level’ is opened, please?
    Roy

    • -You need JS for that.- Sorry, you can achieve that with radio inputs.