Crear pestañas de contenido o ‘tabs’ con javascript

Las pestañas de contenido ó tabs son uno de los recursos más utilizados para organizar los contenidos web. En este artículo veremos una manera fácil de crear grupos de pestañas con Javascript puro, basándonos en una estructura HTML predefinida.

El HTML específico, una función Javascript, y un puñado de CSS es todo lo que necesitamos.

Ver Demo

HTML

Para crear un grupo de pestañas usaremos la siguiente estructura HTML con sus respectivas clases:

  • Añadimos o eliminamos elementos li con la clase t-tab , uno por cada pestaña deseada.
  • Añadimos o eliminamos elementos li con la clase t-content , uno por cada pestaña creada.
  • Asegúrate de que los pares de elementos li de cada grupo de pestañas son los mismos.
<div class="t-container">
  <ul class="t-tabs">  
    <li class="t-tab">Uno</li>  
    <li class="t-tab">Dos</li> 
    <li class="t-tab">Tres</li>  
  </ul>
  <ul class="t-contents">
    <li class="t-content"><p>Contenido Uno</p></li>
    <li class="t-content"><p>Contenido Dos</p></li>
    <li class="t-content"><p>Contenido Tres</p></li>
  </ul>
</div>
  • Uno
  • Dos
  • Tres
  • Contenido Uno

  • Contenido Dos

  • Contenido Tres

Ya tenemos la estructura HTML, vamos a vestirla con algo de CSS

CSS

Añadimos unos estilos CSS para darle forma al grupo de pestañas que acabamos de crear.

.t-container {
  margin: 0 auto;
  padding: 0 2em;
}
.t-tabs, .t-contents {
  list-style-type: none;
  margin: 0;
  padding: 0 2% 0 2%;
  box-sizing: border-box;
}
.t-tabs li {
  color: #dedede;
  padding: 0.5em 0.7em;
  text-decoration: none;
  float: left;
  text-align: center;
  font-size: 1.1em;
  background: #717171;
  border-bottom: 0;
  min-width: 40px;
  margin-right: 2px;
  margin-bottom: 0 !important;
  box-sizing: border-box;
  cursor: pointer;
}
.t-tabs li:hover {
  background-color: #545454;
  color: #d2d2d2;
}
.t-tabs li.selected {
  color: #458ace;
  cursor: default;
  background: #333;
}
.t-contents {
  padding: 0 !important
}
.t-content {
  padding: 0 1em;
  background-color: #333;
  box-sizing: border-box;
  float: left;
  width: 100%;
  color: #b7b7b7;
  line-height: 1.3em;
  text-align: justify;
  z-index: 1;
  position: relative;
  max-height: 0;
  transition: max-height 0.5s ease 0s;
  overflow: hidden;
}
.t-content.selected {
  max-height: 3000px;
  transition: max-height 1.25s ease 0.5s;
}
  • Uno
  • Dos
  • Tres
  • Contenido Uno

  • Contenido Dos

  • Contenido Tres

Esto va tomando forma, pero las pestañas siguen sin funcionar…

Vamos ya con la función Javascript

Javascript

La función easyTabs() es la que hace todo el trabajo y monta la estructura definitiva de nuestro grupo de pestañas:

function easyTabs() {
  var groups = document.querySelectorAll('.t-container');
  if (groups.length > 0) {
    for (i = 0; i < groups.length; i++) {
      var tabs = groups[i].querySelectorAll('.t-tab');
      for (t = 0; t < tabs.length; t++) {
        tabs[t].setAttribute("index", t+1);
        if (t == 0) tabs[t].className = "t-tab selected";
      }
      var contents = groups[i].querySelectorAll('.t-content');
      for (c = 0; c < contents.length; c++) {
        contents[c].setAttribute("index", c+1);
        if (c == 0) contents[c].className = "t-content selected";
      }
    }
    var clicks = document.querySelectorAll('.t-tab');
    for (i = 0; i < clicks.length; i++) {
      clicks[i].onclick = function() {
        var tSiblings = this.parentElement.children;
        for (i = 0; i < tSiblings.length; i++) {
          tSiblings[i].className = "t-tab";
        }
        this.className = "t-tab selected";
        var idx = this.getAttribute("index");
        var cSiblings = this.parentElement.parentElement.querySelectorAll('.t-content');
        for (i = 0; i < cSiblings.length; i++) {
          cSiblings[i].className = "t-content";
          if (cSiblings[i].getAttribute("index") == idx) {
            cSiblings[i].className = "t-content selected";
          }
        }
      };
    }
  }
}

La función, explicada linea a linea, trabaja de la siguiente manera:

  1. Nombre de la función: easyTabs
  2.  Variable groups: con todos los elementos con la clase .t-container
  3.  Condicional if: si la propiedad length de la variable groups es mayor de cero
  4.   Bucle for: que recorre cada elemento de la variable groups
  5.    Variable tabs: con todos los elementos con la clase .t-tab dentro de ese grupo
  6.    Bucle for: que recorre cada elemento de la variable tabs
  7.     Se asigna el atributo index con valor incremental a cada elemento con clase .t-tab
  8.     Condicional if: si es el primero se le añade la clase .selected
  9.    Cierre de for linea 6
  10.    Variable contents: con todos los elementos con la clase .t-contents dentro de ese grupo
  11.    Bucle for: que recorre cada elemento de la variable contents
  12.     Se asigna el atributo index con valor incremental a cada elemento con clase .t-content
  13.     Condicional if: si es el primero se le añade la clase .selected
  14.    Cierre de for linea 11
  15.   Cierre de for linea 4
  16.   Variable clicks: con todos los elementos con la clase .t-tab
  17.   Bucle for: que recorre cada elemento de la variable clicks
  18.    Al hacer clic en cada elemento de la variable clicks
  19.     Variable tSiblings: con todos los elementos hermanos del elemento clicado
  20.     Bucle for: para cada uno de los elementos de la variable tSiblings
  21.      Eliminamos la clase .selected
  22.     Cierre de for linea 20
  23.     Añadimos la clase .selected al elemento en el que hemos hecho clic
  24.     Variable idx: valor del atributo index del elemento en el que hemos hecho clic
  25.     Variable cSiblings: con todos los elementos con clase .t-content de ese grupo
  26.     Bucle for: para cada uno de los elementos de la variable cSiblings
  27.      Eliminamos la clase .selected
  28.      Condicional if: si el valor del atributo index del elemento es igual a la variable idx
  29.        Añadimos la clase .selected al elemento
  30.       Cierre de if linea 28
  31.     Cierre de for linea 26
  32.    Cierre clic en clicks linea 18
  33.   Cierre de for linea 17
  34.  Cierre de if linea 3
  35. Cierre de la función easyTabs linea 1

Solo nos queda llamar a la función easyTabs() cuando el HTML del documento esté cargado. La función buscará los grupos de pestañas y los convertirá en pestañas funcionales:

(function() { 
  easyTabs();
})();

Resultado

Y listo, ya podemos crear grupos de pestañas de manera rápida y simple usando la estructura HTML predeterminada, y rellenándola con nuestros propios contenidos.

<div class="t-container">
  <ul class="t-tabs">  
    <li class="t-tab">Uno</li>  
    <li class="t-tab">Dos</li> 
    <li class="t-tab">Tres</li>  
  </ul>
  <ul class="t-contents">
    <li class="t-content"><p>Contenido Uno</p></li>
    <li class="t-content"><p>Contenido Dos</p></li>
    <li class="t-content"><p>Contenido Tres</p></li>
  </ul>
</div>
  • Uno
  • Dos
  • Tres
  • Contenido Uno

  • Contenido Dos

  • Contenido Tres

Más ejemplos:

<div class="t-container">
  <ul class="t-tabs">  
    <li class="t-tab">Alfa</li> 
    <li class="t-tab">Beta</li> 
  </ul>
  <ul class="t-contents"> 
    <li class="t-content"><p>Contenido para pestaña Alfa.</p></li>
    <li class="t-content"><p>Contenido para pestaña Beta.</p></li>
  </ul>
</div>
  • Alfa
  • Beta
  • Contenido para pestaña Alfa.

  • Contenido para pestaña Beta.

Otro ejemplo con cuatro pestañas:

<div class="t-container">
  <ul class="t-tabs">  
    <li class="t-tab">Rojo</li> 
    <li class="t-tab">Verde</li> 
    <li class="t-tab">Azul</li> 
    <li class="t-tab">Amarillo</li> 
  </ul>
  <ul class="t-contents">  
    <li class="t-content"><p>Contenido para pestaña Rojo.</p></li>
    <li class="t-content"><p>Contenido para pestaña Verde.</p></li>
    <li class="t-content"><p>Contenido para pestaña Azul.</p></li>
    <li class="t-content"><p>Contenido para pestaña Amarillo.</p></li>
  </ul>
</div>
  • Rojo
  • Verde
  • Azul
  • Amarillo
  • Contenido para pestaña Rojo.

  • Contenido para pestaña Verde.

  • Contenido para pestaña Azul.

  • Contenido para pestaña Amarillo.

Pros y Contras

  • Se pueden crear infinitas pestañas dentro de cada grupo.
  • Se pueden crear múltiples grupos de pestañas en la misma página.
  • No se puede anidar un grupo de pestañas dentro de otro grupo de pestañas.

Demo

En Codepen podéis ver la demo a tamaño completo.

Compatibilidad en navegadores
GLOBAL

Datos de CANIUSE.COM