Creating a Light Basic Sliding Animated Menu

Creating a Responsive Animated Sliding Tab Menu

You want a tab menu that is animated? Great you have arrived in the perfect location! In this tutorial, we will be creating a responsive animated sliding tab menu. This tutorial will also provide 2 other themes you may use! We will be including Google Material Icons in this project. This tutorial will require the basic knowledge of HTML, CSS, JavaScript, and jQuery.

Getting Started

First we will want to write some basic HTML code. This will create the HTML model we will be using.

<div class="mobile-container">
  <div class="container">
    <div class="tab tab-home">
      <span class="material-icons">home</span>
    </div>
    <div class="tab tab-account">
      <span class="material-icons">person_outline</span>
    </div>
    <div class="tab tab-cart">
      <span class="material-icons">shopping_cart</span>
    </div>
    <div class="tab tab-menu">
      <span class="material-icons">menu</span>
    </div>
    <div class="highlighter"></div>
  </div>
</div>  

<div class="themePicker">
  <div class="theme themeClassic">
    <div class="type">Classic</div>
  </div>
  <div class="theme themeDark">
    <div class="type">Dark</div>
  </div>
  <div class="theme themeHue">
    <div class="type">Hue</div>  
  </div>
</div>

You can see there are two groups of div containers holding most of the other elements including child div and span elements. The first group called “mobile-container” is the actual container that holds the elements the display the menu. The second group “theme picker” changes the theme of the sliding menu.

Rendering of HTML Without Styles

<div class="mobile-container">
  <div class="container">
    <div class="tab tab-home">
      <span class="material-icons">home</span>
    </div>
    <div class="tab tab-account">
      <span class="material-icons">person_outline</span>
    </div>
    <div class="tab tab-cart">
      <span class="material-icons">shopping_cart</span>
    </div>
    <div class="tab tab-menu">
      <span class="material-icons">menu</span>
    </div>
    <div class="highlighter"></div>
  </div>
</div>  

<div class="themePicker">
  <div class="theme themeClassic">
    <div class="type">Classic</div>
  </div>
  <div class="theme themeDark">
    <div class="type">Dark</div>
  </div>
  <div class="theme themeHue">
    <div class="type">Hue</div>  
  </div>
</div>

Adding Some CSS

Let’s add some CSS to give the menu some style! Can also style the theme picker.

html {
  font-family: Roboto, arial, sans-serif;
}

.tab {
  width: 25%;
  float: left;
  height: 60px;
  line-height: 60px;
  text-align: center;
  padding-top: 4px;
}

.mobile-container {
  margin: 50px auto 0 auto;
  margin-top: 5%;
  border-top: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  height: 68px;
  position: absolute;
  background: white;
  max-width: 540px;
  min-width: 200px;
  bottom: 0;
  right: 20%;
  left: 20%;
}

.material-icons {
  font-size: 30px !important;
  margin-top: 15px;
  color: #373737;
  pointer-events: none;
}

.highlighter {
  height: 8px;
  background: #2f9599;
  border-radius: 0 0 10px 10px;
  position: absolute;
  top: -1px;
  left: 5%;
  right: 80%;
  transition: 200ms 50ms cubic-bezier(0.4, 0, 0.6, 1);
}

.themePicker {
  position: absolute;
  max-width: 540px;
  min-width: 200px;
  top: 0;
  right: 20%;
  left: 20%;
  margin: 0 auto;
}

.theme {
  width: 30%;
  float: left;
  height: 40px;
  line-height: 40px;
  margin: 20px 1% 0 1%;
  color: #000;
  border: 3px solid #708a9b;
  border-radius: 4px;
  background: #f6f6f6;
}

.type {
  text-align: center;
}

Rendering With CSS

Now that we have the HTML and CSS we have a basic model that is functionless.

<div class="mobile-container">
  <div class="container">
    <div class="tab tab-home">
      <span class="material-icons">home</span>
    </div>
    <div class="tab tab-account">
      <span class="material-icons">person_outline</span>
    </div>
    <div class="tab tab-cart">
      <span class="material-icons">shopping_cart</span>
    </div>
    <div class="tab tab-menu">
      <span class="material-icons">menu</span>
    </div>
    <div class="highlighter"></div>
  </div>
</div>  

<div class="themePicker">
  <div class="theme themeClassic">
    <div class="type">Classic</div>
  </div>
  <div class="theme themeDark">
    <div class="type">Dark</div>
  </div>
  <div class="theme themeHue">
    <div class="type">Hue</div>  
  </div>
</div>
html {
  font-family: Roboto, arial, sans-serif;
}

.tab {
  width: 25%;
  float: left;
  height: 60px;
  line-height: 60px;
  text-align: center;
  padding-top: 4px;
}

.mobile-container {
  margin: 50px auto 0 auto;
  margin-top: 5%;
  border-top: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  height: 68px;
  position: absolute;
  background: white;
  max-width: 540px;
  min-width: 200px;
  bottom: 0;
  right: 20%;
  left: 20%;
}

.material-icons {
  font-size: 30px !important;
  margin-top: 15px;
  color: #373737;
  pointer-events: none;
}

.highlighter {
  height: 8px;
  background: #2f9599;
  border-radius: 0 0 10px 10px;
  position: absolute;
  top: -1px;
  left: 5%;
  right: 80%;
  transition: 200ms 50ms cubic-bezier(0.4, 0, 0.6, 1);
}

.themePicker {
  position: absolute;
  max-width: 540px;
  min-width: 200px;
  top: 0;
  right: 20%;
  left: 20%;
  margin: 0 auto;
}

.theme {
  width: 30%;
  float: left;
  height: 40px;
  line-height: 40px;
  margin: 20px 0.9% 0 1%;
  color: #000;
  border: 3px solid #708a9b;
  border-radius: 4px;
  background: #f6f6f6;
}

.type {
  text-align: center;
}

Adding Functionality (JavaScript & JQuery)

To add some function to this menu we added jQuery to speed up the development of the animation. We created a function called animate menu in JQuery. Whenever there is a touch or click event on one of the four tabs. We pass the absolute position (right or left) and a percent of the screen. This moves the selected tab highlighter across the screen as if the tab has been selected. We calculate the last known direction of the right absolute value and compare it to the new one. If the new value is greater than the last know right value, then we know the animation is moving to the left. (newValue > knownValue = moving left) Hence the opposite would be to the right. (newValue < knownValue = moving right) Now that we know the direction of the animation, we can place a delay when we moving the second corner of the highlighter. This gives the highlighter a stretching and then contracting animating as it moves across the tabs. Let’s add the JavaScript and JQuery to give the model it’s function.

var knownPosition = 80;

$(".tab-home").on("click", function () {
  animateMenu("right", "80%", "left", "5%");
});

$(".tab-account").on("click", function () {
  animateMenu("right", "55%", "left", "30%");
});

$(".tab-cart").on("click", function () {
  animateMenu("right", "30%", "left", "55%");
});

$(".tab-menu").on("click", function () {
  animateMenu("right", "5%", "left", "80%");
});

function animateMenu(
  directionOne,
  directionOnePercent,
  directionTwo,
  directionTwoPercent
) {
  newPosition = directionOnePercent.replace(/[^0-9]/g, "");

  if (parseInt(newPosition) > parseInt(knownPosition)) {
    var trans = $(".highlighter").css({
      left: directionTwoPercent
    });
    setTimeout(function () {
      trans.css({
        right: directionOnePercent
      });
    }, 200);
  } else {
    var trans = $(".highlighter").css({
      right: directionOnePercent
    });
    setTimeout(function () {
      trans.css({
        left: directionTwoPercent
      });
    }, 200);
  }

  knownPosition = newPosition;
}

$(".themeClassic").on("click", function () {
  $(".material-icons").css({
    color: "#373737"
  });
  $(".mobile-container").css({
    background: "#fff"
  });
  $(".highlighter").css({
    background: "#2f9599"
  });
});

$(".themeDark").on("click", function () {
  $(".material-icons").css({
    color: "#ccc"
  });
  $(".mobile-container").css({
    background: "black"
  });
  $(".highlighter").css({
    background: "#b06d19"
  });
});

$(".themeHue").on("click", function () {
  $(".material-icons").css({
    color: "#fff"
  });
  $(".mobile-container").css({
    background: "#4f053b"
  });
  $(".highlighter").css({
    background: "#b851a2"
  });
});

CSS Transition Effect

In order to achieve the full effect the the sliding animation. We need to include a CSS transition style. Without this transition effect. The tab will move instantly to the location that we pass through the JavaScript function. Within the “.highlighter” CSS class we will include:

.highlighter {
  transition: 200ms 50ms cubic-bezier(0.4, 0, 0.6, 1);
}

No CSS Transition Easing

Here we provide an example of how the CSS transition affects the animation by excluding it. We see below that there is no smooth transition to the new location.

<div class="mobile-container">
  <div class="container">
    <div class="tab tab-home">
      <span class="material-icons">home</span>
    </div>
    <div class="tab tab-account">
      <span class="material-icons">person_outline</span>
    </div>
    <div class="tab tab-cart">
      <span class="material-icons">shopping_cart</span>
    </div>
    <div class="tab tab-menu">
      <span class="material-icons">menu</span>
    </div>
    <div class="highlighter"></div>
  </div>
</div>  

<div class="themePicker">
  <div class="theme themeClassic">
    <div class="type">Classic</div>
  </div>
  <div class="theme themeDark">
    <div class="type">Dark</div>
  </div>
  <div class="theme themeHue">
    <div class="type">Hue</div>  
  </div>
</div>
html {
  font-family: Roboto, arial, sans-serif;
}

.tab {
  width: 25%;
  float: left;
  height: 60px;
  line-height: 60px;
  text-align: center;
  padding-top: 4px;
}

.mobile-container {
  margin: 50px auto 0 auto;
  margin-top: 5%;
  border-top: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  height: 68px;
  position: absolute;
  background: white;
  max-width: 540px;
  min-width: 200px;
  bottom: 0;
  right: 20%;
  left: 20%;
}

.material-icons {
  font-size: 30px !important;
  margin-top: 15px;
  color: #373737;
  pointer-events: none;
}

.highlighter {
  height: 8px;
  background: #2f9599;
  border-radius: 0 0 10px 10px;
  position: absolute;
  top: -1px;
  left: 5%;
  right: 80%;
/*   transition: 200ms 50ms cubic-bezier(0.4, 0, 0.6, 1); */
}

.themePicker {
  position: absolute;
  max-width: 540px;
  min-width: 200px;
  top: 0;
  right: 20%;
  left: 20%;
  margin: 0 auto;
}

.theme {
  width: 30%;
  float: left;
  height: 40px;
  line-height: 40px;
  margin: 20px 0.9% 0 1%;
  color: #000;
  border: 3px solid #708a9b;
  border-radius: 4px;
  background: #f6f6f6;
}

.type {
  text-align: center;
}
var knownPosition = 80;

$(".tab-home").on("click", function () {
  animateMenu("right", "80%", "left", "5%");
});

$(".tab-account").on("click", function () {
  animateMenu("right", "55%", "left", "30%");
});

$(".tab-cart").on("click", function () {
  animateMenu("right", "30%", "left", "55%");
});

$(".tab-menu").on("click", function () {
  animateMenu("right", "5%", "left", "80%");
});

function animateMenu(
  directionOne,
  directionOnePercent,
  directionTwo,
  directionTwoPercent
) {
  newPosition = directionOnePercent.replace(/[^0-9]/g, "");

  if (parseInt(newPosition) > parseInt(knownPosition)) {
    var trans = $(".highlighter").css({
      left: directionTwoPercent
    });
    setTimeout(function () {
      trans.css({
        right: directionOnePercent
      });
    }, 200);
  } else {
    var trans = $(".highlighter").css({
      right: directionOnePercent
    });
    setTimeout(function () {
      trans.css({
        left: directionTwoPercent
      });
    }, 200);
  }

  knownPosition = newPosition;
}

$(".themeClassic").on("click", function () {
  $(".material-icons").css({
    color: "#373737"
  });
  $(".mobile-container").css({
    background: "#fff"
  });
  $(".highlighter").css({
    background: "#2f9599"
  });
});

$(".themeDark").on("click", function () {
  $(".material-icons").css({
    color: "#ccc"
  });
  $(".mobile-container").css({
    background: "black"
  });
  $(".highlighter").css({
    background: "#b06d19"
  });
});

$(".themeHue").on("click", function () {
  $(".material-icons").css({
    color: "#fff"
  });
  $(".mobile-container").css({
    background: "#4f053b"
  });
  $(".highlighter").css({
    background: "#b851a2"
  });
});

Functional Rendered Sliding Tab Menu

Now that we’ve provided all the steps which include HTML, CSS, and JavaScript, JQuery. We can display a working functional version. Remember that this animated menu works on mobile touch input and can be clicked on with a cursor.

<div class="mobile-container">
  <div class="container">
    <div class="tab tab-home">
      <span class="material-icons">home</span>
    </div>
    <div class="tab tab-account">
      <span class="material-icons">person_outline</span>
    </div>
    <div class="tab tab-cart">
      <span class="material-icons">shopping_cart</span>
    </div>
    <div class="tab tab-menu">
      <span class="material-icons">menu</span>
    </div>
    <div class="highlighter"></div>
  </div>
</div>  

<div class="themePicker">
  <div class="theme themeClassic">
    <div class="type">Classic</div>
  </div>
  <div class="theme themeDark">
    <div class="type">Dark</div>
  </div>
  <div class="theme themeHue">
    <div class="type">Hue</div>  
  </div>
</div>
html {
  font-family: Roboto, arial, sans-serif;
}

.tab {
  width: 25%;
  float: left;
  height: 60px;
  line-height: 60px;
  text-align: center;
  padding-top: 4px;
}

.mobile-container {
  margin: 50px auto 0 auto;
  margin-top: 5%;
  border-top: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  height: 68px;
  position: absolute;
  background: white;
  max-width: 540px;
  min-width: 200px;
  bottom: 0;
  right: 20%;
  left: 20%;
}

.material-icons {
  font-size: 30px !important;
  margin-top: 15px;
  color: #373737;
  pointer-events: none;
}

.highlighter {
  height: 8px;
  background: #2f9599;
  border-radius: 0 0 10px 10px;
  position: absolute;
  top: -1px;
  left: 5%;
  right: 80%;
  transition: 200ms 50ms cubic-bezier(0.4, 0, 0.6, 1);
}

.themePicker {
  position: absolute;
  max-width: 540px;
  min-width: 200px;
  top: 0;
  right: 20%;
  left: 20%;
  margin: 0 auto;
}

.theme {
  width: 30%;
  float: left;
  height: 40px;
  line-height: 40px;
  margin: 20px 0.9% 0 1%;
  color: #000;
  border: 3px solid #708a9b;
  border-radius: 4px;
  background: #f6f6f6;
}

.type {
  text-align: center;
}
var knownPosition = 80;

$(".tab-home").on("click", function () {
  animateMenu("right", "80%", "left", "5%");
});

$(".tab-account").on("click", function () {
  animateMenu("right", "55%", "left", "30%");
});

$(".tab-cart").on("click", function () {
  animateMenu("right", "30%", "left", "55%");
});

$(".tab-menu").on("click", function () {
  animateMenu("right", "5%", "left", "80%");
});

function animateMenu(
  directionOne,
  directionOnePercent,
  directionTwo,
  directionTwoPercent
) {
  newPosition = directionOnePercent.replace(/[^0-9]/g, "");

  if (parseInt(newPosition) > parseInt(knownPosition)) {
    var trans = $(".highlighter").css({
      left: directionTwoPercent
    });
    setTimeout(function () {
      trans.css({
        right: directionOnePercent
      });
    }, 200);
  } else {
    var trans = $(".highlighter").css({
      right: directionOnePercent
    });
    setTimeout(function () {
      trans.css({
        left: directionTwoPercent
      });
    }, 200);
  }

  knownPosition = newPosition;
}

$(".themeClassic").on("click", function () {
  $(".material-icons").css({
    color: "#373737"
  });
  $(".mobile-container").css({
    background: "#fff"
  });
  $(".highlighter").css({
    background: "#2f9599"
  });
});

$(".themeDark").on("click", function () {
  $(".material-icons").css({
    color: "#ccc"
  });
  $(".mobile-container").css({
    background: "black"
  });
  $(".highlighter").css({
    background: "#b06d19"
  });
});

$(".themeHue").on("click", function () {
  $(".material-icons").css({
    color: "#fff"
  });
  $(".mobile-container").css({
    background: "#4f053b"
  });
  $(".highlighter").css({
    background: "#b851a2"
  });
});

Theme Picker

The theme picker built-in provides two other themes to choose from for the example.

Summary

Languages that we used:

  • HTML
  • CSS
  • JavaScript
  • JQuery

Important materials to include:

Want More Tutorials?

Visit the home page to find more usable tutorials!