Cool dashboard side menu using CSS and JavaScript
Tags: css, webdev, beginners, tutorial
Published: 2021-11-14 00:37:30

In this article, we will create a cool dashboard side menu that you can use in your web projects. Let's first look at what are we building:

<img src="https://raw.githubusercontent.com/romaopedro199/dashboard-navigation-side-menu/main/demo.gif" alt="Example gif" title="Example gif" width="200"/>

## HTML

```html
<div class="container">
  <div class="menu">

    <div class="main-menu">

      <div class="logo">
        <img src="your_image_url">
      </div>

      <div class="button-list">
        <div class="item" active>
          <i class="fas fa-home"></i>
        </div>
        <div class="item">
          <i class="fas fa-user"></i>
        </div>
        <div class="item">
          <i class="fas fa-briefcase"></i>
        </div>
        <div class="item">
          <i class="fas fa-chart-pie"></i>
        </div>
        <div class="item">
          <i class="fas fa-user-cog"></i>
        </div>
        <div class="item">
          <i class="fas fa-cog"></i>
        </div>
      </div>

    </div>

    <div class="secondary-menu" expand>
      <div class="content">

        <div class="title">
          <span>Settings</span>
        </div>

        <div class="button-list-title">
          <span>User admin</span>
        </div>

        <div class="button-list">
          <div class="item" active>
            <div class="border-left"></div>
            <span>My Profile</span>
          </div>
          <div class="item">
            <div class="border-left"></div>
            <span>Org</span>
          </div>
          <div class="item">
            <div class="border-left"></div>
            <span>Teams</span>
          </div>
          <div class="item">
            <div class="border-left"></div>
            <span>Roles</span>
          </div>
          <div class="item">
            <div class="border-left"></div>
            <span>Profiles</span>
          </div>
        </div>

        <div class="button-list-title">
          <span>System config.</span>
        </div>

        <div class="button-list">
          <div class="item">
            <div class="border-left"></div>
            <span>Rulesets</span>
          </div>
          <div class="item">
            <div class="border-left"></div>
            <span>Prospects</span>
          </div>
          <div class="item">
            <div class="border-left"></div>
            <span>Accounts</span>
          </div>
          <div class="item">
            <div class="border-left"></div>
            <span>Calls</span>
          </div>
          <div class="item">
            <div class="border-left"></div>
            <span>Triggers</span>
          </div>
          <div class="item">
            <div class="border-left"></div>
            <span>Phones</span>
          </div>
        </div>

      </div>
    </div>

  </div>
</div>
```

In the HTML code, the "main-menu" class is the main container with the icon buttons and "secondary-menu" class is the secondary container with the submenus.

Now let's look at the CSS:

## CSS

```css
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@600;700&display=swap');

:root {
  --color-primary: #546de5;
  --color-secondary: #8395e9;
  --color-secondary-light: rgb(84, 109, 229, .05);
  --color-dark: #303952;
  --color-dark-light: #4f576c;
  --color-light: #ffffff;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  display: flex;
  align-items: flex-start;
}

.menu {
  display: flex;
  align-items: flex-start;
  height: 100vh;
/*   overflow-y: hidden; */
}

.menu .main-menu {
  width: 60px;
  height: 100vh;
  background-color: var(--color-dark);
}

.menu .main-menu .logo {
  display: flex;
  padding: 10px;
}

.menu .main-menu .logo img {
  width: 40px;
  margin: 0px auto;
}

.menu .main-menu .button-list {
  margin-top: 30px;
}

.menu .main-menu .button-list .item {
  display: flex;
  padding: 15px 10px;
  cursor: pointer;
  transition: all .5s;
}

.menu .main-menu .button-list .item:hover {
  background-color: var(--color-dark-light);
}

.menu .main-menu .button-list .item[active] {
  background-color: var(--color-primary);
}

.menu .main-menu .button-list .item i {
  font-size: 16px;
  color: var(--color-light);
  margin: 0px auto;
  pointer-events: none;
}

.menu .secondary-menu {
  padding: 20px 0px;
  width: 0px;
  height: 100vh;
  background-color: var(--color-light);
  -webkit-box-shadow: 10px 0px 15px 0px rgba(48,57,82,0.1);
  -moz-box-shadow: 10px 0px 15px 0px rgba(48,57,82,0.1);
  box-shadow: 10px 0px 15px 0px rgba(48,57,82,0.1);
  transition: all .5s;
}

.menu .secondary-menu .content {
  opacity: 0;
}

.menu .secondary-menu[expand] {
  width: 200px;
}

.menu .secondary-menu[expand] .content {
  opacity: 1;
}

.menu .secondary-menu .content {
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  transition: opacity .5s;
  
  /*  Firefox  */
  scrollbar-color: var(--color-secondary-light) var(--color-secondary-light) !important;
  scrollbar-width: thin !important;
}

.menu .secondary-menu .content::-webkit-scrollbar {
  width: 2px;
}

.menu .secondary-menu .content::-webkit-scrollbar-track {
  background: var(--color-secondary-light);
}

.menu .secondary-menu .content .title {
  padding: 0px 20px;
}

.menu .secondary-menu .title span {
  font-family: 'Open Sans', sans-serif;
  font-size: 18px;
}

.menu .secondary-menu .button-list-title {
  padding: 20px 20px 10px 20px;
}

.menu .secondary-menu .button-list-title span {
  font-family: 'Open Sans', sans-serif;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
}

.menu .secondary-menu .button-list {
  padding: 20px 0px;
}

.menu .secondary-menu .button-list .item {
  display: flex;
  align-items: center;
  height: 35px;
  padding: 0px 20px;
  cursor: pointer;
  transition: all .5s;
}

.menu .secondary-menu .button-list .item:hover {
  background-color: var(--color-secondary-light);
}

.menu .secondary-menu .button-list .item .border-left {
  height: 100%;
  border-left: 2px solid var(--color-dark-light);
  opacity: 0.1;
  margin-right: 15px;
  pointer-events: none;
}

.menu .secondary-menu .button-list .item span {
  font-family: 'Open Sans', sans-serif;
  font-size: 12px;
  color: var(--color-dark-light);
  opacity: 0.3;
  pointer-events: none;
}

.menu .secondary-menu .button-list .item[active] {
  background-color: var(--color-light);
}

.menu .secondary-menu .button-list .item[active] .border-left {
  border-left-color: var(--color-secondary);
  opacity: 1;
}

.menu .secondary-menu .button-list .item[active] span {
  color: var(--color-secondary);
  opacity: 1;
}
```

## JavaScript
```javascript
const mainButtons = document.querySelectorAll('.main-menu .item')
const secondaryButtons = document.querySelectorAll('.secondary-menu .item')

const handleMainButtonClick = (event) => {
  const button = event.target
  if (!isActive(button)) {
    removeMainActive()
    addActive(button)
  }
}

const handleSecondaryButtonClick = (event) => {
  const button = event.target
  if (!isActive(button)) {
    removeSecondaryActive()
    addActive(button)
  }
}

mainButtons.forEach(button => {
  button.addEventListener('click', handleMainButtonClick)
})

secondaryButtons.forEach(button => {
  button.addEventListener('click', handleSecondaryButtonClick)
})

function isActive (button) {
  return button.hasAttribute('active')
}

function removeMainActive () {
  document.querySelectorAll('.main-menu .item[active]').forEach(item => {
    item.removeAttribute('active')
  })
}

function removeSecondaryActive () {
  document.querySelectorAll('.secondary-menu .item[active]').forEach(item => {
    item.removeAttribute('active')
  })
}

function addActive (button) {
  button.setAttribute('active', '')
}
```

## Codepen is here:
{% codepen https://codepen.io/romaopedro199/pen/OJjgZVR %}