Hey guys! In today’s article, we'll explore how to create a dynamic and interactive tabbed interface using the power of HTML, CSS, and JavaScript. We’ll also implement the spread operator that we discussed in our previous article in this article. In case you missed it, you can catch up on it here 👇🏽
Let’s dive right in😉
🧰 Prerequisites
Basic knowledge of HTML and CSS.
Fundamental knowledge of JavaScript (I will still explain everything).
🏚️ HTML Structure
First, Let's analyze the code before diving into the explanation 👇🏽
<body>
<div class="tabs">
<ul class="tabs-header">
<li class="default-tab">Introduction</li>
<li>Features</li>
<li>Documentation</li>
</ul>
<ul class="tabs-content">
<li class="tab">
<h2>Welcome to the Introduction</h2>
<p>This tab provides an overview of our product.</p>
</li>
<li class="tab">
<h2>Explore the Features</h2>
<p>
In this tab, you will discover the exciting features of our product.
</p>
</li>
<li class="tab">
<h2>Access the Documentation</h2>
<p>
Here, you can find detailed documentation on how to use our product.
</p>
</li>
</ul>
</div>
<script src="script.js"></script>
From the code above, You’ll see that In the <body>
section, we have a <div>
element with the class "tabs" that acts as the parent container for our tabbed interface. Inside this container, there are two nested <ul>
elements: one with the class "tabs-header" and another with the class "tabs-content."
The "tabs-header" <ul>
contains three <li>
elements, representing the tabs: "Introduction," "Features," and "Documentation." The first tab has an additional class of "default-tab" to indicate it as the default active tab.
The "tabs-content" <ul>
also includes three <li>
elements, each representing the content of the corresponding tab. These content sections contain <h2>
headings and <p>
paragraphs to provide relevant information for each tab.
💡 You can also change the <li>
to <button>
if you want to. Just have fun with it 😃
Before we move on to the CSS styling, Let’s see what we have so far 👇🏽
Wow, Look at how awesome it looks 😅. I am just kidding.
Now let’s make it look better.
🏡 CSS Styling
Next, let's see the CSS code that styles our Tabs 👇🏽
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;700&display=swap');
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Poppins', sans-serif;
font-size: 1rem;
line-height: 1.5;
background: #f8fafc;
color: #333;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
ul {
list-style: none;
}
h2 {
margin-bottom: 0.3rem;
}
p {
font-weight: 400;
}
.tabs-header {
display: flex;
justify-content: center;
gap: 3rem;
background: #333;
color: #fff;
padding: 1rem 3rem;
}
.tabs-header li {
cursor: pointer;
font-weight: 400;
}
.tabs-content {
padding: 20px;
border: 1px solid #333;
font-weight: bold;
background: #f4f4f4;
}
.tab {
display: flex;
flex-direction: column;
}
.active {
color: orange;
font-weight: 800;
}
The CSS code starts with an @import
rule that imports the "Poppins" font family from Google Fonts. This ensures consistent and visually pleasing typography throughout the tabbed interface.
The remaining CSS styles target different elements of the tabbed interface, such as the body
selector, which sets the font family, font size, background color, and centers the content vertically and horizontally.
The ul
, h2
, and p
selectors define styles for unordered lists, headings, and paragraphs, respectively, ensuring proper formatting and typography within the tabbed interface.
The .tabs-header
selector applies styles to the container of the tab headers, such as background color, text color, and padding. This helps distinguish the tab headers from the content sections.
The .tabs-content
selector defines styles for the container of the tab content sections. It sets the padding, border, and background color, creating a clear visual separation between different tabs' content.
The .tab
selector arranges the tab content sections in a column layout, ensuring proper alignment and spacing.
The .active
selector modifies the appearance of the active tab header by changing the text color and font weight. This visual cue helps users identify the currently active tab.
Let’s see how the output looks 👇🏽
Looking really nice. But you’ll notice that the three contents are showing but we need only the first one to show. We can achieve that using CSS or JavaScript, But we’ll use the JavaScript approach in this article.
🏗️ JavaScript Code
This is the fun part of the project because we’ll be adding interactivity to the tabbed interface. Let's take a look at the code 👇🏽
const createTabs = (tabContainers) => {
// Selecting header and content containers
const headerContainer = document.querySelector('.tabs-header');
const contentContainer = document.querySelector('.tabs-content');
// Converting HTML collections to arrays
const tabHeaders = [...headerContainer.children];
const tabContents = [...contentContainer.children];
// Hide all tab contents
tabContents.forEach((content) => (content.style.display = 'none'));
let currentTabIndex = -1;
const setTab = (index) => {
// Remove active class and hide previous tab content
if (currentTabIndex > -1) {
tabHeaders[currentTabIndex].classList.remove('active');
tabContents[currentTabIndex].style.display = 'none';
}
// Add active class and display selected tab content
tabHeaders[index].classList.add('active');
tabContents[index].style.display = 'flex';
// Update currentTabIndex
currentTabIndex = index;
};
// Determine default tab index
let defaultTabIndex = tabHeaders.findIndex((header) =>
header.classList.contains('default-tab')
);
defaultTabIndex = defaultTabIndex === -1 ? 0 : defaultTabIndex;
// Set default tab
setTab(defaultTabIndex);
// Add click event listeners to tab headers
tabHeaders.forEach((header, index) => {
header.addEventListener('click', () => {
setTab(index);
});
});
};
// Select all tab containers and apply createTabs function
const tabContainers = [...document.querySelectorAll('.tabs')];
tabContainers.forEach(createTabs);
The code above begins by defining a function called createTabs
that accepts an array of tab container elements as a parameter.
Inside the createTabs
function, we selected the header and content containers by querying the DOM using their respective class names. It then converts the resulting HTML collections of tabHeaders
and tabContents
into regular arrays using the spread operator.
We then hide all tabContents
by setting their display
property to 'none'
. This ensures that only the content of the active tab is initially visible.
The variable currentTabIndex
is initialized to -1. This variable keeps track of the currently active tab.
The function setTab
is defined to handle tab switching. It takes an index
as an argument, representing the tab to be activated. Inside the function, it first checks if there is a currently active tab. If so, it removes the 'active'
class from the corresponding header and hides the associated content section.
Next, it adds the 'active'
class to the new tab header and displays the corresponding content section by setting its display
property to 'flex'
. Finally, it updates the currentTabIndex
variable to the index of the newly activated tab.
We then determined the default tab index by finding the index of the header element with the class 'default-tab'
. If no default tab is found, it defaults to index 0.
The default tab is then set using the setTab
function with the default tab index as the argument.
We then added event listeners to each tab header using the forEach
loop. When a header is clicked, the corresponding tab is activated by calling the setTab
function with the header's index as the argument.
Finally, we selected all tab container elements and applies the createTabs
function to each container using another forEach
loop.
That’s all guys, Hope it makes sense.
Now let’s our output so far 👇🏽
Conclusion
Congrats on getting to the end of the article 🎉 🎉. I sincerely hope you've gained valuable insights along the way. I highly recommend writing out the code instead of simply copying and pasting it. This hands-on approach will deepen your understanding and allow you to explore modifications to achieve similar results. For instance, you can try replacing the spread operator in tabHeaders
or tabContents
with something like Array.from()
. Remember, it's absolutely normal if you don't grasp everything immediately. You're not alone, and always keep in mind that PRACTICE is the key to mastery. Wishing you a fantastic weekend, and I’ll see you next week. 😃
##