How to make tabs – Vanilla JavaScript ES5

What are we going to do?

We are going to make tabs. Tabs are good to switch content on a page in one place. They are also good for one-page applications.

You can see the full version on CodePen here: https://codepen.io/lovetocodex/pen/VyQLYE?editors=1010

 

The HTML

Get to know the HTML before moving forward. Note that in the ‘services-tab__nav’, the anchor tag has a href of ‘#tab_1’. While the ‘services-tab__tab-item’ has an id (#).

If this was a long page and we were to click e.g. ‘#tab_1’, it would bring us to the id of ‘tab_1’.

So here we are using the same logic, however, we will make tabs out of it.

<section class="services-tab">
<div class="services-tab__container">

  <div class="services-tab__list-topic">
  <ul class="services-tab__nav">

    <li class="services-tab__list-item">
      <a href="#tab_1" class="services-tab__link-item is-active">
        <span>Tab1</span>
                
      </a>
    </li>

    <li class="services-tab__list-item">
      <a href="#tab_2" class="services-tab__link-item">
        <span>Tab2</span>
      </a>
    </li>

    <li class="services-tab__list-item">
      <a href="#tab_3" class="services-tab__link-item">
        <span>Tab3</span>
      </a>
    </li>

    <li class="services-tab__list-item">
      <a href="#tab_4" class="services-tab__link-item">
        <span>Tab4</span>
      </a>
    </li>

  </ul>
  </div><!-- /list-topic -->

  <div class="services-tab__list-content">

    <div id="tab_1" class="services-tab__tab-item is-visible">
      <h2>Tab 1</h2>
      <p>Lorem ipsum dolor a, quod  debitis aspernatur neque sit distinctio. Sit amet consectetur adipisicing elit.        Itaque nemo atque incidunt laborum delectus. Cum adipisci perspiciatis blanditiis magni velit nihil id vero? </p>
    </div>

    <div id="tab_2" class="services-tab__tab-item">
      <h2>Tab 2 - YAY</h2>
      <p>Is vero? no, false. Itaque nemo atque incidunt laborum delectus a, quod  debitis aspernatur neque sit distinctio. Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
    </div>

    <div id="tab_3" class="services-tab__tab-item">
      <h2>Tab 3 - Awesome!</h2>
      <p>Cum adipisci perspiciatis blanditiis magni velit nihil   id vero?  Lorem ipsum dolor sit amet consectetur adipisicing   elit. Itaque nemo atque incidunt laborum delectus a, quod  debitis aspernatur neque sit distinctio.</p>
    </div>

    <div id="tab_4" class="services-tab__tab-item">
      <h2>Tab 4 - Happy Coding!</h2>
      <p>Cum adipisci perspiciatis blanditiis magni velit nihil   id vero? Itaque nemo atque incidunt laborum delectus a, quod  debitis aspernatur neque sit distinctio.</p>
    </div>

  </div><!-- /services-tab__list-content -->

</div>
</section>

 

The CSS

Simple CSS code.

/* GLOBAL */
h2 {
    margin: 0;
}

/* TAB MENU */
.services-tab__container {
    width: 50%;
    margin: 0 auto;
}

.services-tab__nav {
    list-style: none;
    padding: 0;
}

.services-tab__list-item {
    display: inline-block;
}

.services-tab__link-item {
    text-decoration: none;
    text-transform: uppercase;
    display: block;
    background-color: #ffb577;
    padding: 9px 14px;
    color: white;
    font-size: 14px;
    border-radius: 6px;
    font-weight: bold;
    transition: .15s ease-in-out;
}

.services-tab__link-item.is-active {
    background-color: #f9913a;
}

.services-tab__link-item:hover {
    background-color: #fd9c4a;
}

/* TAB ITEMS */
.services-tab__tab-item {
    background-color: #f9913a;
    padding: 20px;
    border-radius: 5px;
    display: none;
    color: white;
}

.services-tab__tab-item.is-visible {
    display: block;
}

 

The JavaScript

What we want to do is when we click the tab, the corresponding tab content will show, while it changes the state to active(giving us the nice background colour and displaying it). Alright, so we got a basic idea on what we want to do, let’s think about how we’ll go about this in the code.

Planning

The first thing we will need to select the items.

To get the tabs and link, we will need to loop through them. We want to do something on click, so we will need ‘eventListener’.

When the tabs and links are the same, we want to add the appropriate class, and if they aren’t we want to remove it.

Variables

It’s a good practice to include:

window.onload = function() {}

As that tells the browser to load the script once the HTML and CSS is loaded first.

Let’s get the tab links and the tab content first.

We can select that by using the ‘querySelectorAll’ , instead of  the old way ‘getElementById’ or ‘getElementsByClassName’.

// Variables 	
var tabLinks = document.querySelectorAll('.services-tab__link-item');
var tabContents = document.querySelectorAll('.services-tab__tab-item');

 

For Loop

We need to loop throw the items we want to work with.

Looping through the ‘tab links’

Now that we can select the elements, we want to add event listeners to our tab links, since we need to know when they are beeing clicked.

To do that, we are going to use a ‘for loop’.

window.onload = function() {

  // Variables 	
  var tabLinks = document.querySelectorAll('.services-tab__link-item');
  var tabContents = document.querySelectorAll('.services-tab__tab-item');

  // Loop through the tab link
  for (var i = 0; i < tabLinks.length; i++) {

  }

}

The reason we are doing it this way is because we need to get every single tab that is out there. To achieve that effect we can loop throw it. However, how much should we loop? We can use simple math and JS magic to solve that.

What we are doing here, is setting a variable ‘i’ which stands for index in programming terms – you can name it however you want. We will set the value to 0.

Next, we want to say that if the ‘i’ is less than ‘tabLinks’, loop through it. We can achieve that on the next part with the ‘i++’, which will increment by 1 each time.

You might be wondering what is the ‘tabLinks.lenght’. With this JS method, we are getting the length of the ‘tabLinks’. So instead of hardcoding a value there, as we can add or delete the links, we will count it dynamically.

We need to understand that what’s in between the for loop, is a super easy math calculation that is dynamic. We are doing that to get a number.

If you were to put that on my name ‘Aurelian’, it would display 8, since my name has 8letters. If you were to put that on the tabs we are doing, it will display 4. So in other words, the code might as well look like this :

for (var i = 0; i < 4; i++) {

 }

But again, we are getting the tab links and we want their value.

Looping through the tab content

The idea is the same as before, however, we need to loop it inside the previous loop. Such as:

 // Loop through the tab link
for (var i = 0; i < tabLinks.length; i++) {
   
    // Loop through the tab content
    for (var j = 0; j < tabContents.length; j++) {

    }
 
  }

 

This is the whole code we should have so far.

window.onload = function() {

  // Variables 	
  var tabLinks = document.querySelectorAll('.services-tab__link-item');
  var tabContents = document.querySelectorAll('.services-tab__tab-item');

  // Loop through the tab link
  for (var i = 0; i < tabLinks.length; i++) {
     

      // Loop through the tab content
      for (var j = 0; j < tabContents.length; j++) {

      
      }
 
  }
    
}

 

Getting the values

The loop alone isn’t any good without a use. We need to connect it to something, so it has a purpose, instead of just doing loops 🙂

How do we get the tab links we just looped?

We need to select it, ‘tabLinks[i]’.

The items we have looped are stored in the ‘i’, so now we can do something with it. Same for the tab content, however let’s add in a variable for it, as we are going to use it few times.

var tabContent = tabContents[j];

That way all the tabContents is sotred in tabContent.

Let’s finish off the settings.

Adding Event listener and preventing default

As I wrote before, we need to listen to the tabs. We can do that by attacking event listener to the tabLinks[i] inside the loop, and the other loop will need to be wrapped around that, such as:

window.onload = function() {

  // Variables 	
  var tabLinks = document.querySelectorAll('.services-tab__link-item');
  var tabContents = document.querySelectorAll('.services-tab__tab-item');

  // Loop through the tab link
  for (var i = 0; i < tabLinks.length; i++) {
    tabLinks[i].addEventListener('click', function(e) {

      // Loop through the tab content
      for (var j = 0; j < tabContents.length; j++) {
        var tabContent = tabContents[j];
      }
            
      this.classList.add('is-active');
    });
  }
    
}

Remember that we need to pass in something in the function, we’ll pas an e, which will be for event. Since on click, we want to do something, or prevent.

Let’s add the prevent default. We do this so the page doesn’t jump to to the id, or won’t refresh the page upon clicking the anchor tag.

We can do that by adding:

e.preventDefault();

We are passing the event here, so on click, the ‘e’ will go to the function, and the function is connected to this, so it will prevent the default.

Matching the tab-link and tab-content

Remember when I was talking about the anchor tag and ID?

Well, what we want to do is add a class that will show the corresponding tab, as well as change the visual effect of the link.

We will want to say if the anchor tag herf matched with the id, do this. There’s one problem, m however, because the href has a hashtag ‘#’, we need to remove it before we can compare it to the id, and do something. Otherwise, they will be different.

Let’s create a variable with the name of id, so we can store it easily.

Next, we want to get the tab links, and we can do this with ‘this’. Since we have looped through the tabs, we get all of the links, and with ‘this’, we get the specific one that’s clicked.

So far we should have this:

var id = this

Now, we want to modify the hash, so we can use the ‘hash’ property. The ‘hash’ properly returns the (#) sign.

So we add it to the code we have, but between them have a dot.

We want to delete that. We can achieve it with ‘replace’ property. What we can do is replace the hash, with nothing.

var id = this.hash.replace('#', '');

 

So far you should have this code

window.onload = function() {

  // Variables 	
  var tabLinks = document.querySelectorAll('.services-tab__link-item');
  var tabContents = document.querySelectorAll('.services-tab__tab-item');

  // Loop through the tab link
  for (var i = 0; i < tabLinks.length; i++) {
    tabLinks[i].addEventListener('click', function(e) {
      e.preventDefault();
      var id = this.hash.replace('#', '');

      // Loop through the tab content
      for (var j = 0; j < tabContents.length; j++) {
            

      }
            
    });
  }
    
}

 

Adding the show/hide functionality

Now the exciting part!

Let’s move to the tab content loop and get the tabs. However, let’s store it in a varible so we can easily re-use it.

var tabContent = tabContents[j];

On click, we want to remove the active classes that are set on the items.

Since we are going to want to activate a class to the element we clicked, we will want to remove the previous active class – so the effect actually works and we have one tab displayed at the time, and one color.

tabContent.classList.remove('is-visible');
tabLinks[j].classList.remove('is-active');

We have removed it on click, but we need to add it when it’s selected.

We can say to add the class when the id is the same as the href – that’s why we took the hash out of the href, so we can now compare them and so something.

 

if (tabContent.id === id) {
  tabContent.classList.add('is-visible');
}

 

There is one more piece of code missing, which is that we need to activate the tab links color.

We can do that by putting this code:

this.classList.add('is-active');

 

Outside the tab-content loop. Since we want to add the class to the tab-links, we put it outside.

 

Conclusion

If you liked the article, have any suggestion, comment below!

The full source to the code: https://codepen.io/lovetocodex/pen/VyQLYE?editors=1010

Happy Coding!

Meet the author

Meet the author

Aurelian Spodarec

Front-end WordPress developer that blogs about web development. I like using the right tools for the job. In my spare time, I enjoy cooking healthy food and then eating it. Delicious!

Comments