En este ejemplo vamos a crear un TabSheet utilizando jQuery. Lo bueno del tabsheet que vamos a realizar es que podrémos agregar cuantos queramos en una página y hasta vamos a poder anidarlos.
Resultado – Prueba el demo
Paso 1 – Crear la estructura
Lo primero que vamos a hacer es crear la estructura de nuestro tabsheet.
<div id="ts1" class="tabsheet" > <ul class="pestanas"> <li><a id="ts1_ps1" class="actual">Pestaña 1</a></li> <li><a id="ts1_ps2">Pestaña 2</a></li> <li><a id="ts1_ps3">Pestaña 3</a></li> </ul> <div id="ts1_ps1co" class="contenido">Contenido 1</div> <div id="ts1_ps2co" class="contenido">Contenido 2</div> <div id="ts1_ps3co" class="contenido">Contenido 3</div> </div>
Como puedes notar, todo está encerrado en un div con clase tabsheet. Este es el contenedor de todo mi tabsheet (pestañas y contenidos).
Dentro del tabsheet hay una lista ul con las pestañas. Dentro de cada elemento li de la lista he colocado un link que no tiene destino. Este link lo usaré para detectar el movimiento del mouse sobre la pestaña y además detectar el click en la pestaña. También puedes notar que solo uno de estos links tiene la clase actual, esto se debe a que esta será la pestaña seleccionada por defecto.
Dentro del tabsheet hay 3 contenedores div con la clase contenido, cada uno será asociado a la pestaña correspondiente.
Si colocas dicha estructura en el body tag de tu página deberías ver algo como esto:
Paso 2 – Decorando el tabsheet
Definitivamente esto no se parece en nada al resultado final, es más las pestañas aparecen de forma vertical en lugar de horizontal. Pero aunque no parezca estamos bastante cerca, ahora con solo aplicar un poco de CSS podemos modificar la apariencia.
Para agregar los estilos te recomiendo crear un archivo llamado estilos.css y enlazarlo a tu página. Si no sabes como hacer esto te recomiendo leer Todo lo que necesitas saber acerca de HTML.
Voy a ir agregando los estilos poco a poco para que veas como afecta cada uno al tabsheet.
La hoja de estilos completa es la siguiente:
.tabsheet {
background-color:#636d76;
border:1px solid #494e52;
font-family:Helvetica, Arial, sans-serif;
font-size:11px;
padding:10px;
}
.tabsheet ul.pestanas li {
display:inline;
list-style-type:none;
}
.tabsheet ul.pestanas {
margin:0;
padding:5px 0 5px 0;
}
.tabsheet ul.pestanas li a {
background-color: #484c55;
border:1px solid #464c54;
color:#ffebb5;
cursor:pointer;
padding:5px 8px 5px 8px;
}
.tabsheet ul.pestanas li a:hover {
border-color:#2f343a;
}
.tabsheet ul.pestanas li a.actual {
background-color: #fff;
border-color:#464c54;
color:#000;
}
.tabsheet .contenido {
background-color:#fff;
border:1px solid #464c54;
padding:10px 15px 10px 15px;
}
Ocultando los contenidos no seleccionados
Muchas implementaciones de tabsheets ocultan todos los contenidos que no están activos utilizando estilos css (display:none;) y luego con JavaScript los muestran. El problema es que si el usuario cuenta con CSS pero no Javascript, el contenido se quedará oculto y no se mostrará nunca. Es por esta razón que yo prefiero ocultarlo y mostrarlo con Javascript, de esta forma si el usuario no cuenta con JavaScript el contenido nunca se ocultará y podrá ser visible a pesar de que no funcione como un tabsheet.
Más adelante voy a mostrar como ocultar y mostrar el contenido con Javascript.
Paso 3 – Asignando IDs a cada objeto
Si miras con detenimiento el tabsheet puedes ver que hemos colocado el atributo ID en algunos tags.
El tabsheet tiene id ts1 indicando que es el tabsheet 1 (si hubiera otro tabsheet en la pagina sería ts2 y así sucesivamente). Las pestañas tienen como id la combinación del id del tabsheet y psX donde X representa el número de la pestaña. Los contenidos tienen como id la combinación del id de la pestaña seguido por co.
Bajo este principio es bastante sencillo determinar que contenido está asociado a que pestaña y a que tabsheet pertenecen.
Por ejemplo si encontramos el id ts54_p32co podemos saber que es el contenido de la pestaña 32 del tabsheet 54.
El problema es el siguiente: Si mi página tiene 100 tabsheets, cada uno con 30 pestañas y cada pestaña con 5 tabsheets anidados o algo así de complicado, el trabajo de poner los IDs va a ser muy tedioso y propenso a errores.
Para evitar colocar los IDs manualmente voy a implementar una función en Javascript que llene los IDs de todos los tabsheets de la página. Si todavía no has configurado tu página para que use jQuery debes hacerlo ya. Si no sabes como agregar jQuery te recomiendo leer jQuery, un nuevo tipo de librería Javascript.
function asignarIDS()
{
var tabsheetNum = 1;
// Recorro todos los tabsheets de la pagina
jQuery(".tabsheet").each(function()
{
// Le asigno un id a cada tabsheet ejem: ts1, ts2, ts3
var tsID = "ts" + tabsheetNum;
jQuery(this).attr("id", tsID);
tabsheetNum++;
var pestanasNum = 1;
// Recorro todas las pestañas dentro del tabsheet
var pestanas = jQuery(this).children("ul.pestanas").first();
pestanas.find("li a").each(function()
{
// Le asigno un id a cada pestana ejem: ts1_ps1, ts1_ps2, ts1_ps3
var psID = tsID + "_ps" + pestanasNum;
jQuery(this).attr("id", psID);
pestanasNum++;
});
pestanasNum = 1;
// Recorro todos los contenidos dentro del tabsheet
jQuery(this).children(".contenido").each(function()
{
// Le asigno un id a cada contenido ejem: ts1_ps1co, ts1_ps2co, ts1_ps3co
var coID = tsID + "_ps" + pestanasNum + "co";
jQuery(this).attr("id", coID);
pestanasNum++;
});
});
}
Esta función se debe ejecutar a penas carga la página así que la llamaremos en el evento ready de jQuery.
jQuery(document).ready(function(){
asignarIDS();
});
Ahora ya no necesitamos los atributos id en cada tag por lo que nuestra estructura quedaría así:
<div class="tabsheet"> <ul class="pestanas"> <li><a class="actual">Pestaña 1</a></li> <li><a>Pestaña 2</a></li> <li><a>Pestaña 3</a></li> </ul> <div class="contenido">Contenido 1</div> <div class="contenido">Contenido 2</div> <div class="contenido">Contenido 3</div> </div>
Como puedes ver, ya no necesitamos los IDs haciendo que nuestro código sea más fácil de mantener. No importa si mi página tiene 1 o 2 o 100 tabsheets todos se pueden agregar usando la misma estructura.
Paso 4 – Inicializando los tabsheet
Hasta ahora los tabsheet muestran todos los contenidos a pesar de que una de las pestañas se está mostrando como la seleccionada. En esta función primero voy a ocultar todos los contenidos. Luego voy a recorrer cada una de las pestañas que tengan la clase actual y voy a guardar el ID de dicha pestaña en el tabsheet correspondiente. Finalmente voy a mostrar todos los contenidos que correspondan con las pestañas seleccionadas.
function inicializarTabSheets()
{
// Ocultamos todos los contenidos
jQuery(".tabsheet .contenido").css("display", "none");
// Recorremos todas las pestañas seleccionadas
jQuery(".tabsheet ul.pestanas li a.actual").each(function(){
// Le asigno al tabsheet el nombre de la pestana actual
var psID = jQuery(this).attr("id");
var tsID = psID.substring(0, psID.indexOf("_", 0));
jQuery("#" + tsID).data("pestanaActual", psID);
// Calculo el ID del contenido y lo muestro
var coID = jQuery(this).attr("id") + "co";
jQuery("#" + coID).css("display", "block");
});
}
Como esta función utiliza la definición de class="actual" para determinar cual es la pestaña seleccionada, es posible que muestres la pestaña 3 al inicio con simplemente pasar la instrucción class="actual" desde la pestaña 1 a la pestaña 3. Obviamente, si en dos pestañas dejas el atributo class="actual" se mostrarán dos contenidos al inicio así que no lo hagas. También puedes escoger que ninguna pestaña tenga el atributo class de tal forma que no aparecerá ningún contenido hasta que el usuario haga clic sobre alguna pestaña.
Esta función también debe ser ejecutada a penas carga la página así que la agregaremos al evento ready de jQuery.
jQuery(document).ready(function(){
asignarIDS();
inicializarTabSheets();
});
Paso 5 – Configurar el clic de las pestañas
Al inicio de la página necesitamos programar lo que pasará cuando se le haga clic a cada una de las pestañas, es por eso que voy a programar el evento clic de cada pestaña en el evento ready de jQuery.
jQuery(document).ready(function(){
asignarIDS();
inicializarTabSheets();
// Programa el evento click de cada pestaña de cada tabsheet
jQuery(".tabsheet ul.pestanas li a").click(function()
{
// Si ya esta seleccionado salimos sin hacer nada
if (jQuery(this).hasClass("actual")) return;
// Obtengo los id de la pestaña, contenido, tabsheet, pestana anterior
var psID = jQuery(this).attr("id");
var coID = psID + "co";
var tsID = psID.substring(0, psID.indexOf("_", 0));
var psAntID = jQuery("#" + tsID).data("pestanaActual");
// Quito la selección a la pestaña anterior
jQuery("#" + psAntID).removeClass("actual");
// Agrego la selección a la pestaña actual
jQuery("#" + psID).addClass("actual");
// Oculto el contenido anterior
jQuery("#" + psAntID + "co").hide();
// Muestro el nuevo contenido
jQuery("#" + coID).show();
// Actualizo el valor de la pestaña actual del tabsheet
jQuery("#" + tsID).data("pestanaActual", psID);
});
});
Listo!! el tabsheet ya funciona!! El código Javascript completo lo coloco a continuación:
function asignarIDS()
{
var tabsheetNum = 1;
// Recorro todos los tabsheets de la pagina
jQuery(".tabsheet").each(function()
{
// Le asigno un id a cada tabsheet ejem: ts1, ts2, ts3
var tsID = "ts" + tabsheetNum;
jQuery(this).attr("id", tsID);
tabsheetNum++;
var pestanasNum = 1;
// Recorro todas las pestañas dentro del tabsheet
var pestanas = jQuery(this).children("ul.pestanas").first();
pestanas.find("li a").each(function()
{
// Le asigno un id a cada pestana ejem: ts1_ps1, ts1_ps2, ts1_ps3
var psID = tsID + "_ps" + pestanasNum;
jQuery(this).attr("id", psID);
pestanasNum++;
});
pestanasNum = 1;
// Recorro todos los contenidos dentro del tabsheet
jQuery(this).children(".contenido").each(function()
{
// Le asigno un id a cada contenido ejem: ts1_ps1co, ts1_ps2co, ts1_ps3co
var coID = tsID + "_ps" + pestanasNum + "co";
jQuery(this).attr("id", coID);
pestanasNum++;
});
});
}
function inicializarTabSheets()
{
// Ocultamos todos los contenidos
jQuery(".tabsheet .contenido").css("display", "none");
// Recorremos todas las pestañas seleccionadas
jQuery(".tabsheet ul.pestanas li a.actual").each(function(){
// Le asigno al tabsheet el nombre de la pestana actual
var psID = jQuery(this).attr("id");
var tsID = psID.substring(0, psID.indexOf("_", 0));
jQuery("#" + tsID).data("pestanaActual", psID);
// Calculo el ID del contenido y lo muestro
var coID = jQuery(this).attr("id") + "co";
jQuery("#" + coID).css("display", "block");
});
}
jQuery(document).ready(function(){
asignarIDS();
inicializarTabSheets();
// Programa el evento click de cada pestaña de cada tabsheet
jQuery(".tabsheet ul.pestanas li a").click(function()
{
// Si ya esta seleccionado salimos sin hacer nada
if (jQuery(this).hasClass("actual")) return;
// Obtengo los id de la pestaña, contenido, tabsheet, pestana anterior
var psID = jQuery(this).attr("id");
var coID = psID + "co";
var tsID = psID.substring(0, psID.indexOf("_", 0));
var psAntID = jQuery("#" + tsID).data("pestanaActual");
// Quito la selección a la pestaña anterior
jQuery("#" + psAntID).removeClass("actual");
// Agrego la selección a la pestaña actual
jQuery("#" + psID).addClass("actual");
// Oculto el contenido anterior
jQuery("#" + psAntID + "co").hide();
// Muestro el nuevo contenido
jQuery("#" + coID).show();
// Actualizo el valor de la pestaña actual del tabsheet
jQuery("#" + tsID).data("pestanaActual", psID);
});
});
Agregando efectos visuales
Agregar efectos visuales cuando se cambia de pestaña es bastante simple gracias a jQuery. Lo único que tienes que hacer es reemplazar las líneas que ocultan y muestran el contenido en el evento click, es decir, reemplaza las líneas:
// Oculto el contenido anterior
jQuery("#" + psAntID + "co").hide();
// Muestro el nuevo contenido
jQuery("#" + coID).show();
por las siguientes líneas:
// Oculto el contenido anterior
jQuery("#" + psAntID + "co").slideUp("slow");
// Muestro el nuevo contenido
jQuery("#" + coID).slideDown("slow");
Si te das cuenta lo único que hemos hecho es modificar el hide y show por slideUp y slideDown. Ten cuidado con utilizar esta opción ya que los navegadores antiguos fallan en esta parte al momento de anidar tabsheets.
Cambiando el estilo de tabsheets anidados
En el ejemplo mostrado al comienzo el contenido de la tercera pestaña contiene a un tabsheet, a esto se le conoce como tabsheet anidado.
Si colocas un tabsheet anidado en tu página como por ejemplo:
<div class="tabsheet" > <ul class="pestanas"> <li><a>Pestaña 1</a></li> <li><a>Pestaña 2</a></li> <li><a class="actual">Pestaña 3</a></li> </ul> <div class="contenido">Contenido 1</div> <div class="contenido">Contenido 2</div> <div class="contenido"> <div class="tabsheet" > <ul class="pestanas"> <li><a class="actual">Sub Pestaña 1</a></li> <li><a>Sub Pestaña 2</a></li> <li><a>Sub Pestaña 3</a></li> </ul> <div class="contenido">Sub Contenido 1</div> <div class="contenido">Sub Contenido 2</div> <div class="contenido">Sub Contenido 3</div> </div> </div> </div>
puedes notar que obtiene el mismo estilo haciendo un poco confusa la lectura de la página:
Para modificar el estilo basta con agregar un poco más de CSS. En este caso, el CSS será igual al que hicimos para el primer tabsheet con la excepción de que ahora atacaremos a un tabsheet que está dentro de otro.
Ten en cuenta que solo necesito cambiar algunas cosas como colores y otros más, ya que todo el resto ya lo está tomando por defecto del CSS de arriba.
Agrégale lo siguiente a tu hoja de estilos:
.tabsheet .tabsheet {
background-color:#f6f6f6;
border-color:#e0e0e0;
}
.tabsheet .tabsheet ul.pestanas li a {
background-color:#f6f6f6;
border-color:#e9e9e9;
color:#000;
font-weight:bold;
}
.tabsheet .tabsheet ul.pestanas li a.actual {
color:#69a817;
background-color:#fff;
}
.tabsheet .tabsheet .contenido{
border-color:#e9e9e9;
}
Ahora deberías ver que el tabsheet anidado se ve diferente:
Conclusión
Crear un tabsheet no es complicado, simplemente tienes que saber bien como manejar el CSS y el jQuery. Te recomiendo colocar todo este código dentro de una clase para que puedas reutilizarla en todas tus páginas.
Espero que te sirva en tus futuras aplicaciones.

excelente articulo