How to Create Multi Level Sidebar Animation in React ?
Last Updated :
29 Jul, 2024
In this article, we will see how we can animate the Multi-level sidebar in ReactJS to enhance the overall appearance of the Sidebar component in the application. This attracts the user towards the interface more and also increases the look and feel of the application.
We will discuss the following two approaches to implement Multi Level Sidebar Animation in React.
Steps to Create the React Application:
Step 1: Create a React application using the following command.
npx create-react-app foldername
Step 2: Once done, change your directory to the newly created application using the following command.
cd foldername
Step 3: Install the required packages by executing the below command in the terminal.
npm install framer-motion react-icons
Project Structure:

The updated dependencies in package.json for a frontend will look like this:
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4",
"framer-motion": "^10.17.6",
"react-icons": "^4.12.0"
}
Approach 1: Using framer-motion
In this approach, we are using the Framer Motion animation where we have specified the state management to control the toggling of the sidebar, also we are performing the UI animation on the sidebar contents.
Example 1: Below is the implementation of above discussed approach.
CSS
body {
margin: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
display: flex;
height: 100vh;
overflow: hidden;
background-color: #f0f0f0;
}
.app {
display: flex;
flex: 1;
}
.sidebar {
width: 60px;
background-color: #333;
color: white;
padding: 20px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.logo {
color: #4caf50;
font-size: 24px;
margin-bottom: 20px;
transition: font-size 0.5s ease;
}
.approach-title {
margin-bottom: 20px;
}
.sidebar-item {
cursor: pointer;
margin-bottom: 10px;
transition: background-color 0.3s ease;
}
.sidebar-item.active {
background-color: #555;
}
.sub-items {
overflow: hidden;
}
.sub-item {
padding-left: 20px;
margin-top: 5px;
cursor: pointer;
}
.toggle-button {
cursor: pointer;
background-color: #4caf50;
color: white;
border: none;
padding: 10px;
margin-top: 20px;
border-radius: 5px;
outline: none;
transition: margin-top 0.5s ease;
}
.sidebar-open .sidebar {
width: 300px;
}
.sidebar-open .logo {
font-size: 18px;
}
.sidebar-open .toggle-button {
margin-top: 30px;
}
.sidebar-open .sub-item {
padding-left: 20px;
}
.sidebar:not(.sidebar-open) {
overflow: hidden;
width: 400px;
transition: width 0.5s ease;
}
.sidebar:not(.sidebar-open) .toggle-button {
margin-top: 0;
}
.sidebar:not(.sidebar-open) .sub-item {
padding-left: 10;
}
.content {
flex: 1;
padding: 20px;
background-color: #fff;
overflow-y: auto;
}
.content-title {
color: #333;
font-size: 32px;
margin-bottom: 10px;
}
.content-subtitle {
color: #555;
font-size: 18px;
margin-bottom: 20px;
}
JavaScript
//App.js
import React, { useState } from "react";
import { motion } from "framer-motion";
import "./App.css";
const dataSide = [
{
id: 1,
title: "Home",
subItems: [],
},
{
id: 2,
title: "Topics",
subItems: [
{ id: 21, title: "React" },
{ id: 22, title: "JavaScript" },
{ id: 23, title: "CSS" },
],
},
{
id: 3,
title: "About",
subItems: [
{ id: 31, title: "GeeksforGeeks" },
{ id: 32, title: "Team" },
],
},
{
id: 4,
title: "More",
subItems: [
{ id: 41, title: "Animations" },
{ id: 42, title: "Components" },
],
},
];
const App = () => {
const [item_Select, set_Item_Select] = useState(null);
const [sideBar_Open, set_SideBar_Open] = useState(false);
const dataClickFn = (i) => {
set_Item_Select(i.id === item_Select?.id ? null : i);
};
const sideBarFn = () => {
set_SideBar_Open(!sideBar_Open);
};
return (
<div className={`app ${sideBar_Open ? "sidebar-open" : ""}`}>
<div className="sidebar">
{sideBar_Open && (
<>
<h1 className="logo">GeeksforGeeks</h1>
<motion.div
className="approach-title"
animate={{ opacity: 1, y: 0 }}
initial={{ opacity: 0, y: -20 }}
>
<h3>Approach 1: Using Framer Motion</h3>
</motion.div>
{dataSide.map((item) => (
<motion.div
key={item.id}
className={`sidebar-item ${
item_Select?.id === item.id ? "active" : ""
}`}
onClick={() => dataClickFn(item)}
whileHover={{ scale: 1.1 }}
>
{item.title}
{item.subItems.length > 0 && (
<motion.div
initial={false}
animate={{
height:
item_Select?.id === item.id
? "auto"
: 0,
}}
className="sub-items"
>
{item.subItems.map((subItem) => (
<motion.div
key={subItem.id}
className="sub-item"
>
{subItem.title}
</motion.div>
))}
</motion.div>
)}
</motion.div>
))}
</>
)}
<motion.button
className="toggle-button"
whileHover={{ scale: 1.1 }}
onClick={sideBarFn}
>
{sideBar_Open ? "Close Sidebar" : "Open Sidebar"}
</motion.button>
</div>
<div className="content">
<motion.h1
className="content-title"
animate={{ opacity: 1, y: 0 }}
initial={{ opacity: 0, y: -20 }}
>
Welcome to GeeksforGeeks
</motion.h1>
<motion.h3
className="content-subtitle"
animate={{ opacity: 1, y: 0 }}
initial={{ opacity: 0, y: -20 }}
>
Explore our amazing content
</motion.h3>
</div>
</div>
);
};
export default App;
Step to run the application: Open the terminal and type the following command.
npm start
Output: Open the browser and our project is shown in the URL http://localhost:3000/
Approach 2: Using CSS Only
In this approach, we are animating the multilevel sidebar by using CSS styling properties and keyframes. We are not using any other animation package like Approach 1. We have created all the animations by using CSS properties only.
Example 1: Below is the implementation of above discussed approach.
CSS
.app {
display: flex;
height: 100vh;
overflow: hidden;
}
.sidebar {
width: 200px;
background: linear-gradient(to right, #3f3f3f, #1a1a1a);
color: white;
padding: 20px;
transition: width 0.3s ease, box-shadow 0.3s ease;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
}
.sidebar-item {
cursor: pointer;
margin-bottom: 10px;
transition: all 0.3s ease;
position: relative;
animation: bounce 0.5s ease;
}
@keyframes bounce {
0%,
20%,
50%,
80%,
100% {
transform: translateY(0);
}
40% {
transform: translateY(-10px);
}
60% {
transform: translateY(-5px);
}
}
.sidebar-item span {
display: inline-block;
transition: transform 0.3s ease, text-shadow 0.3s ease;
}
.sidebar-item:hover {
margin-left: 10px;
box-shadow: 5px 0px 15px rgba(0, 0, 0, 0.3);
background: linear-gradient(to right, #555, #444);
border-radius: 10px;
color: #ffeb3b;
}
.sidebar-item:hover span {
transform: translateX(5px);
text-shadow: 2px 2px 5px rgba(255, 255, 255, 0.5);
}
.sidebar-item:after {
content: '';
display: block;
height: 2px;
width: 0;
background: rgb(224, 0, 0);
transition: width 0.3s ease;
}
.sidebar-item:hover:after {
width: 100%;
}
.open {
font-weight: bold;
}
.sub-menu {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease, opacity 0.3s ease;
animation: fadeIn 0.5s ease;
}
.sidebar-item.open .sub-menu {
max-height: 500px;
opacity: 1;
}
.sub-menu-item {
opacity: 0;
transform: translateY(-10px);
transition: opacity 0.5s ease, transform 0.5s ease;
color: #4caf50;
}
.sub-menu-item.show {
opacity: 1;
transform: translateY(0);
}
@media screen and (max-width: 768px) {
.app {
flex-direction: column;
}
.sidebar {
width: 100%;
position: absolute;
left: -100%;
transition: left 0.3s ease;
}
.sidebar.open {
left: 0;
}
.sidebar-item {
margin-left: 0;
}
.content {
opacity: 0;
transition: opacity 0.3s ease;
}
.content.open {
opacity: 1;
}
.hamburger {
display: block;
cursor: pointer;
order: -1;
}
}
.sidebar.open {
width: 250px;
}
.content {
color: green;
flex: 1;
padding: 20px;
background-color: #f4f4f4;
}
JavaScript
// App.js
import React, { useState } from "react";
import { FaHome, FaBook, FaLaptop, FaBookOpen, FaTools } from "react-icons/fa";
import { BsFillCaretDownFill } from "react-icons/bs";
import "./App.css";
const SidebarItem = ({ item, onClick }) => {
const [isOpen, setIsOpen] = useState(false);
const itemClickFn = () => {
setIsOpen(!isOpen);
if (onClick) {
onClick(item);
}
};
const getIcon = (label) => {
const iconMap = {
Home: <FaHome />,
Topics: <FaBook />,
Languages: <FaLaptop />,
About: <FaBookOpen />,
Frameworks: <FaTools />,
};
return iconMap[label] || <BsFillCaretDownFill />;
};
return (
<div
className={`sidebar-item ${isOpen ? "open" : ""}`}
onClick={itemClickFn}
>
<span className="icon">{getIcon(item.label)}</span>
<span>{item.label}</span>
{isOpen && item.children && (
<div className="sub-menu">
{item.children.map((child, index) => (
<SidebarItem key={index} item={child} />
))}
</div>
)}
</div>
);
};
const App = () => {
const data = [
{ label: "Home" },
{
label: "Topics",
children: [
{ label: "React" },
{ label: "JavaScript" },
{ label: "CSS" },
],
},
{
label: "Languages",
children: [
{
label: "Front-end",
children: [
{ label: "HTML" },
{ label: "CSS" },
{ label: "JavaScript" },
],
},
{
label: "Back-end",
children: [
{ label: "Node.js" },
{ label: "Python" },
{ label: "Ruby" },
],
},
],
},
{ label: "About" },
{
label: "Frameworks",
children: [
{ label: "React" },
{ label: "Angular" },
{ label: "Vue.js" },
],
},
];
return (
<div className="app">
<div className="sidebar">
{data.map((item, index) => (
<SidebarItem key={index} item={item} />
))}
</div>
<div className="content">
<h1>GeeksforGeeks</h1>
<h3>Approach 2: Using CSS Only</h3>
</div>
</div>
);
};
export default App;
Step to run the application: Open the terminal and type the following command.
npm start
Output: Open the browser and our project is shown in the URL http://localhost:3000/
Similar Reads
How to create Menu Item Component in ReactJS ?
React JS is a popular JavaScript library used for building user interfaces. It provides a component-based architecture that allows developers to create reusable UI elements. Material UI for React has this component available for us and it is very easy to integrate. We can use Menu Component in React
2 min read
How to create Accordion in ReactJS ?
Accordions contain creation flows and allow lightweight editing of an element. Material UI for React has this component available for us, and it is very easy to integrate. We can create it in React using the following approach.Approach to create Accordion in React JSTo create accordion in react we w
2 min read
How to create a Responsive Carousel in React JS ?
A carousel, often seen in web and mobile applications, is a user interface component used to display a set of content items such as images or text in a rotating manner. It allows users to view multiple items within a limited space by scrolling horizontally or vertically through the content. In this
2 min read
How to create a Scroll To Bottom button in React JS ?
Learn to implement a "Scroll to Bottom" button in React using the useState() hook, a feature commonly seen in chat applications like WhatsApp and Telegram for effortless navigation to the end of a chat window. Prerequisites:NodeJS or NPMReact JSstyled-componentReact useState()Steps to Create the Rea
2 min read
How to create Loading Screen in ReactJS ?
Loading screen plays a major role in enhancing UX development. In this article, we are going to learn how we can create a Loading Screen in ReactJs. A loading screen is a picture shown by a computer program, often a video game, while the program is loading or initializing.PrerequisitesJavaScript and
2 min read
How to Create a Scroll To Top Button in React JS ?
You will see there are lots of websites, that are using a useful feature like if you're scrolling the webpage, and now you are at the bottom of that page then you can use this button to scroll up automatically like skip to the content. The following example covers create a Scroll To Top button in Re
3 min read
Exploring React Reveal: Creating Stunning Animations in React
React Reveal is an animation library for React. In this article, we will see few of the implementation of this library and learn more about it.We will discuss the following two approaches:Table of ContentUsing the Fade EffectUsing the slide EffectCombining Animation and SequencePrerequisitesJavaScri
2 min read
How to create a multi level Dropdown NavBar in React-bootstrap using map?
In this article, we are going to implement a drop-down-based navigation bar using React-Bootstrap. We will map the navigation links from an array to a navigation bar with suitable React-Bootstrap classes and components.Prerequisite:React JSHTML CSSJavaScriptJSXSteps to create React Application and i
4 min read
How to Create a Sidebar in NextJS & Tailwind CSS?
In web development, sidebars are commonly used to organize navigation elements and provide quick access to different sections of a website. A sidebar is a vertical menu or panel that is typically positioned on the left or right side of the main content area. Prerequisites:Next.jsTailwindJavaScriptSt
5 min read
How to create Tabs in ReactJS ?
Tabs make it easy to explore and switch between different views. Material UI for React has this component available for us and it is very easy to integrate. We can use Tabs Component in ReactJS using the following approach.Prerequisites:NPM & Node.jsReact JSMaterial UIwe have these approaches to
4 min read