Creating an Interactive Tabbed Interface with JavaScript
Tags: webdev, javascript, beginners, programming
Published: 2023-06-15 23:00:00

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 👇🏽

[Spread Operator](https://dev.to/devlawrence/level-up-your-javascript-skills-with-the-spread-operator-5dc0)

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 👇🏽

```jsx
	<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 👇🏽

![html-output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0i3o1zf3pqulewkt4ex.png)

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 👇🏽

```
	
		*,
		*::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 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 👇🏽


![css-output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v75v1giepoqzqqu0rlg5.png)

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 👇🏽

[Final-output](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExZmJlNDEwMTkxZjljZmE0ZTlhOTMyNGI4NDBjOWNmODc1MzhkMDM5MCZlcD12MV9pbnRlcm5hbF9naWZzX2dpZklkJmN0PWc/Gykk00z8U8WC2luUCU/giphy.gif)

## 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. 😃