Building a Simple Tab Component with Vanilla JavaScript
- Tarun Ranka
🎯 Building a Simple Tab Component with Vanilla JavaScript¶
If you’ve ever wanted to create a basic tabbed interface without relying on frameworks like React, Vue, or even jQuery — you're in the right place. Today, we’ll walk through a clean and functional JavaScript implementation of a tab component.
This small project demonstrates how to dynamically generate tabs, manage active states, and toggle content sections using just Vanilla JS (aka plain JavaScript).
💡 What Are Tabs?¶
Tabs are UI components that allow you to switch between different views or content blocks without leaving the page. Think of it like a mini navigation system, perfect for dashboards, settings panels, or any grouped content.
🧱 The Data Structure¶
We start with a list of tabs:
let tabList = [
{ id: "tab-1", title: "Tab 1", content: "Content 1" },
{ id: "tab-2", title: "Tab 2", content: "Content 2" },
{ id: "tab-3", title: "Tab 3", content: "Content 3" },
];
Each tab has:
- A unique
id
- A
title
to be shown on the tab button - The
content
that appears when the tab is active
🎨 HTML Structure (Expected)¶
Make sure your HTML has two container elements with IDs tabs
and tab-contents
:
🚀 The renderTabs
Function¶
The renderTabs()
function is the star of the show. It does three things:
- Clears the previous tab and content HTML
- Dynamically creates tab buttons and corresponding content sections
- Handles click events to switch the active tab
Let’s break it down.
Step 1: Clear Existing Content
tabs.innerHTML = "";
tabContents.innerHTML = "";
Each time renderTabs()
is called, we wipe the slate clean to avoid duplicate elements.
Step 2: Loop Through Tabs
tabList.forEach(({ id, title, content }) => {
...
});
For every item in tabList
, we:
- Create a
<button>
for the tab - Create a
<div>
for the tab content - Attach an event listener to handle clicks
Step 3: Handle Tab Clicks¶
tab.addEventListener("click", () => {
let activeTab = document.getElementById(activeTabNum);
let activeContent = document.getElementById(`content-${activeTabNum}`);
...
});
When a tab is clicked:
- We first reset the currently active tab and hide its content.
- Update
activeTabNum
to the new tab. - Change the tab’s background to show it’s active.
- Show the associated content block.
✨ Active Tab Highlighting¶
By default, only the content of the initially active tab (tab-1
) is visible. When a tab is selected, its background color changes and the corresponding content is shown:
tab.style.backgroundColor = "lightgray";
contentDiv.style.display = "block";
Simple yet effective UI feedback.
✅ Final Touch: Run the Function
renderTabs();
Calling renderTabs()
on page load initializes the tab UI.
let tabs = document.getElementById("tabs");
let tabContents = document.getElementById("tab-contents");
let tabList = [
{
id: "tab-1",
title: "Tab 1",
content: "Content 1",
},
{
id: "tab-2",
title: "Tab 2",
content: "Content 2",
},
{
id: "tab-3",
title: "Tab 3",
content: "Content 3",
},
];
function renderTabs(activeTabNum = "tab-1") {
tabs.innerHTML = "";
tabContents.innerHTML = "";
tabList.forEach(({ id, title, content }) => {
let tab = document.createElement("button");
tab.innerText = title;
tab.setAttribute("id", id);
tab.addEventListener("click", () => {
let activeTab = document.getElementById(activeTabNum);
let activeContent = document.getElementById(`content-${activeTabNum}`);
activeTab.style.backgroundColor = "white";
activeContent.style.display = "none";
activeTabNum = id;
tab.style.backgroundColor = "lightgray";
let contentDiv = document.getElementById(`content-${id}`);
contentDiv.style.display = "block";
});
tabs.appendChild(tab);
let contentDiv= document.createElement("div");
contentDiv.innerText = content;
contentDiv.setAttribute("id", `content-${id}`);
contentDiv.style.display = "none";
if (activeTabNum === id) {
contentDiv.style.display = "block";
}
tabContents.appendChild(contentDiv);
})
}
renderTabs();
🔄 Bonus: Improvements You Can Add¶
- Styling: Add some CSS for hover effects and better spacing.
- Accessibility: Add
aria-*
attributes and keyboard navigation. - Animations: Add smooth fade or slide transitions.
- Reusability: Turn this into a class or module for use in multiple components.
🧠Final Thoughts¶
This code is a great example of how you can build interactive UI components using plain JavaScript. No libraries. No dependencies. Just core DOM manipulation.
This type of approach is not only educational but can also be incredibly performant when you want a lightweight, dependency-free interface.
Let me know if you want this turned into a CodePen, live demo, or a reusable component!