Create Bottom Navigation Menu Bar using HTML CSS JS

A clean and interactive navigation menu improves user experience and makes any website more engaging. In this tutorial, we’ll create a modern bottom navigation menu bar with an animated circular highlighter that smoothly follows the active menu item. This effect is built using HTML, CSS and JavaScript without any external libraries (other than Font Awesome for icons).

This type of navigation bar is especially useful for mobile-first designs, dashboards and modern web applications. Let’s go step by step.

HTML Structure

We’ll start with the HTML markup for the navigation menu.

<div id="main-container" class="flex-c">
    <div class="nav-container flex-c">
        <ul class="menu flex-c">
            <div class="highlighter"></div>
            <li class="item flex-c active">
                <a href="#" class="icon flex-c"><span class="fas fa-home"></span></a>
                <span class="dot"></span>
            </li>
            <li class="item flex-c">
                <a href="#" class="icon flex-c"><span class="fas fa-search"></span></a>
                <span class="dot"></span>
            </li>
            <li class="item flex-c">
                <a href="#" class="icon flex-c"><span class="fas fa-plus"></span></a>
                <span class="dot"></span>
            </li>
            <li class="item flex-c">
                <a href="#" class="icon flex-c"><span class="fas fa-bell"></span></a>
                <span class="dot"></span>
            </li>
            <li class="item flex-c">
                <a href="#" class="icon flex-c"><span class="fas fa-user"></span></a>
                <span class="dot"></span>
            </li>
        </ul>
    </div>
</div>
  • #main-container → wraps everything and centers the navigation bar both vertically and horizontally.
  • .nav-container → acts as the navigation bar background with rounded corners and gradient styling.
  • .menu → an unordered list containing each menu item (li.item).
  • .highlighter → the animated circular indicator that moves beneath the active item.
  • .item elements → each contains an icon (.icon) and a hidden dot that becomes visible when active.
  • Font Awesome icons → used to represent Home, Search, Add, Notifications and Profile.

The HTML is structured in a way that’s flexible and easily extendable—add more li.item elements if you want more navigation options.

CSS Styling

Now we’ll apply styles to make the bottom navigation menu bar visually appealing and add smooth animations.

@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.css');

:root {
    --bg-color: #0a0a0a;
}

body {
    background: var(--bg-color);
}

.flex-c {
    display: flex;
    align-items: center;
    justify-content: center;
}

#main-container {
    min-height: 100vh;
    min-width: 420px;
}

.nav-container {
    width: 420px;
    height: 60px;
    border-radius: 15px;
    background: linear-gradient(rgb(79 104 103), rgb(11 19 47));
}

.menu {
    gap: 15px;
    height: 100%;
    position: relative;
}

.highlighter {
    left: 0;
    top: -50%;
    height: 100%;
    transition: .5s;
    aspect-ratio: 1;
    border-radius: 50%;
    position: absolute;
    border: 5px solid var(--bg-color);
    background: linear-gradient(rgb(103, 119, 118), rgb(11 19 47));
}

.highlighter::before,
.highlighter::after {
    content: '';
    position: absolute;
    width: 22px;
    height: 22px;
    bottom: 3px;
}

.highlighter::before {
    left: -22px;
    border-radius: 0px 25px 0px 0px;
    box-shadow: 1px -10px 0px 0px var(--bg-color);
}

.highlighter::after {
    right: -22px;
    border-radius: 25px 0px 0px 0px;
    box-shadow: -1px -10px 0px 0px var(--bg-color);
}

.item {
    z-index: 1;
    height: 100%;
    cursor: pointer;
    aspect-ratio: 1;
    transition: .5s;
    list-style: none;
    border-radius: 50%;
}

.item .icon {
    text-decoration: none;
    height: 100%;
    width: 100%;
    font-size: 18px;
    color: white;
    transition: .5s;
}

.dot {
    opacity: 0;
    width: 8px;
    aspect-ratio: 1;
    position: absolute;
    border-radius: 50%;
    background: #ffffff;
    transform: translateY(30px);
    transition: transform .5s, opacity .3s;
    box-shadow: 0px 0px 8px 2px #ffffff99;
}

.active {
    transform: translateY(-50%);
}

.active .dot {
    opacity: 1;
    transform: translateY(45px);
}
  • Layout basics → Flexbox (.flex-c) centers content neatly.
  • Navigation bar styling.nav-container has a gradient background with rounded edges.
  • Highlighter → styled as a circular element that moves horizontally using transform. The ::before and ::after pseudo-elements create smooth cut-out effects.
  • Menu items → each .item is circular, with hover and active transitions.
  • Dot indicator → initially hidden (opacity: 0), becomes visible and glows when the item is active.
  • Active state → moves the item upward (translateY(-50%)) for a floating effect.

The CSS brings the menu to life with smooth animations, glowing effects and a unique moving highlighter that makes the bottom navigation menu bar stand out.

JavaScript Functionality

Finally, let’s add JavaScript to make the highlighter follow the active menu item.

const items = document.querySelectorAll('.item');
const highlighter = document.querySelector('.highlighter');

function removeActive() {
    items.forEach(elem => elem.classList.remove('active'));
}

items.forEach((elem, index) => {
    elem.addEventListener('click', () => {
        highlighter.style.transform = `translateX(${index * 75}px)`;
        removeActive();
        elem.classList.add('active');
    });
}); 
  • Selecting elements → grab all .item elements and the .highlighter.
  • removeActive() → helper function to reset all items by removing the active class.
  • Event listener on each item → when clicked:
    • Move the highlighter horizontally using translateX(${index * 75}px) (75px spacing per item).
    • Remove active states from all items.
    • Add active to the clicked item so it floats up and shows its dot.

The JavaScript adds interactivity, making the highlighter slide smoothly across the menu and updating the active item dynamically.

Final Thoughts

With this tutorial, you’ve built a modern animated bottom navigation menu bar using HTML, CSS and JavaScript. The highlighter effect makes the design look sleek and interactive, while the active dot adds a finishing touch.

This type of menu can be adapted for:

  • Mobile app-like bottom navigation bars
  • Interactive dashboards
  • Websites that need a stylish and modern UI

You can further enhance it by adding tooltips, labels or even integrating it with routing for a complete navigation experience.

Leave a Comment

Scroll to Top