HTML Auto-Hiding menu with lock

We will build from scratch a navigation menu which can appear on mouse hover and auto hide otherwise. 

Locking / Unlocking the menu will also be possible when clicking on a button on top of the menu.

Checkout the result before diving into the code :

Auto Hiding menu

Don’t bother the ugly template, just add some icons and change the colors and that should be so much better !

This tutorial will be split into 3 pages :

  1. HTML/Sass implementation with JavaScript
  2. Plugin in Material UI
  3. Integration within Angular 9.0

You are currently watching the first part.

Sass Installation

This is a pre-requesite before diving into the code.

If you haven’t installed Sass on your system, it’s time now :

sudo npm install -g sass

Depending on your IDE (editor – ie : Sublime Text, Atom, Visual Studio Code, WebStorm…), you might be using a filewatcher to auto compile your code. Let’s assume you haven’t configured anything yet, to compile your code :

  • open up a terminal, pointing to your code folder, run the following command and let it go :
sass --watch SASS_SOURCE_FOLDER:CSS_DESTINATION_FOLDER

Preparing your codebase 

Now time to organize your code architecture and we will start by using the 7-1 pattern for that :

mkdir sass/base sass/layout sass/vendors sass/components sass/pages sass/themes sass/utilities

Then create your main.scss file using your IDE, place it at the root of the sass directory.

css
sass 
    abstracts
    base
    layout
    pages
main.scss

Not all folders are listed as we skipped them, just add them whenever they are needed.

We won’t be talking about the 7-1 pattern also, you can have a look at this page which describes the architecture. It is good practice recognized by most front-end developers.

HTML structure

We will keep things simple, I assume you have some knowledge about HTML5 so just read over this 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="css/main.css">
</head>
<body class="page">

<nav class="nav nav--autohide" id="navigation">
    <h2 class="nav__title">NAV BAR</h2>

    <span id="lock">LOCK</span>

    <ul class="nav__menu">
        <li class="nav__link nav__link--active">Home</li>
        <li class="nav__link">Page 1</li>
        <li class="nav__link">Page 2</li>
        <li class="nav__link">Page 3</li>
    </ul>
</nav>

<main class="content">
    <h1 class="content__title">The page title</h1>
    <article class="content__article">
        Welcome here dude, here is the content of the page...
    </article>
</main>

<script type="application/javascript" src="js/script.js"></script>

</body>
</html>
 

Basically there is a menu and the content of the page. The Javascript added allows us to play with the Lock/Unlock feature.

Javascript code

Once again, the code speaks for itself, it’s just about DOM manipulation:

const lock = document.getElementById('lock');
const navigation = document.getElementById('navigation');
let isLocked = false;

lock.addEventListener('click', function(){

    if (isLocked)
    {
        navigation.classList.remove('nav--locked');
        navigation.classList.add('nav--autohide');
        this.innerHTML = 'LOCK';
        isLocked = false;
    }
    else {
        navigation.classList.remove('nav--autohide');
        navigation.classList.add('nav--locked');
        this.innerHTML = 'UNLOCK';
        isLocked = true;
    }
});

That could also be refactored to avoid some duplication, I let you with the exercise.

Sass code

Checkout the main part with all imports :

@import "base/reset";
@import "abstracts/variables";
@import "layout/navigation";
@import "pages/home";

And the partials :

$menu-width: 250px;
$menu-min-width: 50px;
$mini-padding: 5px;
$border-width: 10px;
$mini-size: 1.5em;
body, ul {
  margin: 0;
}
ul, li {
  padding: 0;
}

.page {
  display: flex;
  padding: $mini-padding;
  box-sizing: border-box;
  height: 100vh;
}

.content {
  border: $border-width solid darkred;
  padding: $mini-padding;
  flex: 1;
}

.nav {
  border: $border-width solid purple;
  padding: $mini-padding;
  overflow: hidden;
  width: $menu-min-width;
  transition: width 2s;

  &amp;__title {
    color: burlywood;
  }

  &amp;__menu {
    background-color: pink;
  }

  &amp;__link {
    list-style-type: none;
    background-color: antiquewhite;
    font-size: $mini-size;
    height: $mini-size;
    line-height: $mini-size;
    overflow: hidden;

    &amp;:before {
      content: "[]";
      width: $menu-min-width;
      text-align: center;
      display: inline-block;
    }
  }

  &amp;--autohide:hover, &amp;--locked {
    width: $menu-width;
  }

  > #lock {
    cursor: pointer;
  }

}


The code base is pretty straightforward, we simply use a simple transition effect (ease in out) on the menu width. You can customize things according to your project.

Note : we use the BEM methodology to name our elements properly (good practice again :)), check out this website for more information and particularly this page and some nice points here.

The full codebase of this tutorial is on Github.

I hope you enjoyed the sources provided here, take the time to look at other resources. And if you have a comment, I’ll be looking forward to reading it.

 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Want more information?

Related links will be displayed within articles for you to pick up another good spot to get more details about software development, deployment & monitoring.

Stay tuned by following us on Youtube.

%d bloggers like this: