Como crear pestañas con HTML

En este post voy a explicar como crear pestañas o tabs con HTML, CSS y JavaScript/JQuery que es un proceso realmente sencillo.

La estructura de la pagina, que tendrá las pestañas es realmente sencilla. Hacen falta 2 divisiones, una en la que estarán las pestañas y otra en la que estarán los contenidos de las pestañas.


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" type="text/css" href="css/estilo.css"/>
    <script type="text/javascript" src="js/cambiarPestanna.js"></script>
    <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
    <title></title>
</head>
<body>
    <div class="contenedor">
        <div class="titulo">¿Sobre que escribiré en el blog?</div>
        <div id="pestanas">
            <ul id=lista>
                <li id="pestana1"><a href='javascript:cambiarPestanna(pestanas,pestana1);'>HTML</a></li>
                <li id="pestana2"><a href='javascript:cambiarPestanna(pestanas,pestana2);'>CSS</a></li>
            </ul>
        </div>

        <body onload="javascript:cambiarPestanna(pestanas,pestana1);">

        <div id="contenidopestanas">
            <div id="cpestana1">
                Contenido de la pestaña 1
            </div>
            <div id="cpestana2">
                Contenido de la pestaña 2
            </div>
    </div>
</body>
</html>
</pre>

En el anterior código, esta la estructura HTML completa. Además de las divisiones comentadas anteriormente, dentro de ellas para las pestañas se ha optado por crear una lista y para el contenido de cada pestaña una división. Con esto ya esta la estructura ahora solo falta darle estilo para que parezcan pestañas y crear una función para poder cambiar de pestaña.

El estilo obviamente es una cosa bastante personal y al cambiar alguna cosa puede que sea necesario cambiar otras para volver a reajustarlo todo bien. Me parece que las hojas de estilo son bastante sencillas de entender, lo único notar que en las esquinas superiores de las pestañas se las da un efecto redondeado pero a las inferiores obviamente no y que de la misma forma la esquina superior izquierda de la división que contiene las pestañas no sea redondeada porque habrá una pestaña justo encima.


body {
    background: darkgrey;    
}

.contenedor{
    width: 1080px;
    margin: auto;
    background: black;
    color: bisque;
    padding: 20px 15px 50px 50px;
    border-radius: 10px;
    box-shadow: 0 10px 10px 0px rgba(0, 0, 0, 0.8);
}

.contenedor .titulo{
    font-size: 3.5ex;
    font-weight: bold;
    margin-left: 10px;
    margin-bottom: 10px;
}

#pestanas {
    float: top;
    font-size: 3ex;
    font-weight: bold;
}

#pestanas ul{
    margin-left: -40px;    
}

#pestanas li{
    list-style-type: none;
    float: left;
    text-align: center;
    margin: 0px 2px -2px -0px;
    background: darkgrey;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    border: 2px solid bisque;
    border-bottom: dimgray;
    padding: 0px 20px 0px 20px;
}

#pestanas a:link{
    text-decoration: none;
    color: bisque;
}

#contenidopestanas{
    clear: both;  
    background: dimgray;
    padding: 20px 0px 20px 20px;
    border-radius: 5px;
    border-top-left-radius: 0px;
    border: 2px solid bisque;
    width: 1025px;
}

Con esto ya tenemos las pestañas creadas, pero aun no hacen nada y el contenido de todas las pestañas se muestra uno debajo de otro.

La solución es una sencilla función que modifique la hoja de estilos a la que le pasaremos la división que contiene todas las pestañas (en nuestro caso pestanas) y la pestaña que se quiere mostrar (pestana1, pestana2,…).

Esta función actúa en 2 pasos, en el primero recorre todas pestañas, ocultando su contenido y restaurando el color de fondo de la pestaña y el padding inferior y en el segundo paso muestra el contenido de la pestaña que se quería mostrar y cambia el color de la pestaña y aumenta el padding de la pestaña para que tape el borde de lo que será el contenido de las pestañas, que queda justo debajo y así quede pestaña y contenido del mismo color y todo continuo.


// Dadas la division que contiene todas las pestañas y la de la pestaña que se 
// quiere mostrar, la funcion oculta todas las pestañas a excepcion de esa.
function cambiarPestanna(pestannas,pestanna) {
    
    // Obtiene los elementos con los identificadores pasados.
    pestanna = document.getElementById(pestanna.id);
    listaPestannas = document.getElementById(pestannas.id);
    
    // Obtiene las divisiones que tienen el contenido de las pestañas.
    cpestanna = document.getElementById('c'+pestanna.id);
    listacPestannas = document.getElementById('contenido'+pestannas.id);
    
    i=0;
    // Recorre la lista ocultando todas las pestañas y restaurando el fondo 
    // y el padding de las pestañas.
    while (typeof listacPestannas.getElementsByTagName('div')[i] != 'undefined'){
        $(document).ready(function(){
            $(listacPestannas.getElementsByTagName('div')[i]).css('display','none');
            $(listaPestannas.getElementsByTagName('li')[i]).css('background','');
            $(listaPestannas.getElementsByTagName('li')[i]).css('padding-bottom','');
        });
        i += 1;
    }

    $(document).ready(function(){
        // Muestra el contenido de la pestaña pasada como parametro a la funcion,
        // cambia el color de la pestaña y aumenta el padding para que tape el  
        // borde superior del contenido que esta juesto debajo y se vea de este 
        // modo que esta seleccionada.
        $(cpestanna).css('display','');
        $(pestanna).css('background','dimgray');
        $(pestanna).css('padding-bottom','2px'); 
    });

}

Y aquí puedes ver también el código completo, el resultado, realizar modificaciones y ver el resultado.
He cambiado de jsfiddle a codepen para mostrar el ejemplo porque carga infinitamente más rapido pero no se porque razón no se ejecuta el javascript automaticamente al cargarlo (es cosa de codepen y no del ejemplo) y por lo tanto no se selecciona automaticamente la primera pestaña pero si haces click en alguna pestaña ya funciona o si le das a edit on codepen hay si funciona como debe.

See the Pen Tabs HTML by Ivan Salas (@isc7) on CodePen

Y a petición de Alex Schenck pues os pongo como crear pestañas en vertical de una forma muy simple porque solo es necesario añadir 4 líneas al CSS.

See the Pen Vertical Tabs HTML by Ivan Salas (@isc7) on CodePen

Edito el post nuevamente para añadir una nueva modificación para que cada pestaña sea de un color diferente. Los cambios son extremadamente sencillos, basicamente es añadir el CSS necesario para darle un color distinto a cada pestaña y cambiar el padding del contenedor de las pestañas y meterlo directamente en las propias pestañas y quitar un par de lineas del javascript para que no se cambien los colores de fondo al elegir una pestaña porque en este caso no tiene sentido.

See the Pen Tabs HTML by Ivan Salas (@isc7) on CodePen.

Y para terminar, como siempre el código completo (de los 3 tipos de pestañas) lo puedes descargar aquí.