Wextensible

Actualización Marzo 2014

Alguién me preguntó si podía incluirse un contenedor de pestañas dentro a su vez de otro de estos contenedores. Hice un prueba y vi que era posible sin hacer excesivas modificaciones. Y ya de paso también dar la posibilidad de contenedores con varias filas de pestañas. He actualizado este tema para incorporar esas mejoras.

Todos los ejemplos de contenedores de pestañas de esta página tienen el CSS necesario en un elemento <style> del <head> y el JS está en un <script> al pie de la página. Los que finalmente usaré en este sitio no serán estos sino lo que puede ver en el tema siguiente, versiones para este sitio, con algunas modificaciones cuyo motivación se explica en ese tema.

Si no tienes tiempo para leer el tema o quieres echar un vistazo rápido, aquí tienes una página de ejemplo con lo mínimo indispensable, en cuyo código fuente podrás ver como insertar el primer contenedor con pestañas del tema.

Contenedor de pestañas en dos filas de una tabla

El primer contenedor de pestañas que se presenta a continuación es el que se estructura en una tabla con dos filas. Pongo aquí un ejemplo con 3 pestañas:

Ejemplo: Una fila de pestañas

 Primera Segunda Tercera

id=tabdiv-0

Contenido de la Primera pestaña.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec sollicitudin libero id elit. Sed euismod nonummy neque. Nam dignissim urna vel urna. Nunc aliquet. Nunc vel dui mattis magna varius condimentum. Etiam lacus enim, aliquam ultricies, luctus ut, placerat id, lectus. Vestibulum laoreet commodo tortor. Nunc eget urna. Suspendisse ac orci. Vivamus quis tortor facilisis velit interdum blandit.

id=tabdiv-1

Otro contenido para la PESTAÑA 2ª

id=tabdiv-2

El último contenido de la Pestaña 3

Este es el código HTML de esta estructura:

Como vemos se trata de una tabla con 2 filas <tr>. En la primera ponemos las pestañas en celdas de título <th>, alternando una celda que hará de hueco (clase tabcks) y otra con el título de la pestaña (tabck). En la de los huecos ponemos un espacio no separable &nbsp; para forzar a que no se modifique el ancho del hueco. Las celdas que hacen de pestañas se identifican agregando el número al nombre de la clase con id="tabck-N" donde N es el número de esa pestaña. Cada una lleva un evento onclick="activarTab(this)" para activar esa pestaña.

La segunda fila tiene una única celda que abarca tantas celdas como hay en la primera fila con el atributo colspan="6", en general serán 2N pestañas contando con los huecos. Luego disponemos de N contenedores <div> con la clase tabdiv e identificados de la misma forma con id="tabdiv-N".

Con la actualización de este componente en Marzo 2014 he agregado los atributos data-min y data-max a la tabla. También he identificado el elemento <td> que contiene los <div class="tabdiv"> con id="tab-N". Las versiones anteriores seguirán funcionando aunque no contemplen estos cambios, que sirven para incluir contenedores de pestañas dentro de contenedores y también para contenedores con varias filas de pestañas como ser verá más abajo. Por ahora sólo diremos que se declara el rango de los ID de las pestañas en los data-min y data-max, mientras que la N de id="tab-N" será el primer índice de ese rango.

El estilo para conseguir esta estructura está en la cabecera de esta página:

La tabla, que tiene el modelo de bordes abiertos como hemos explicado, la hacemos con el fondo transparente para que actúe el efecto de los huecos entre pestañas sobre el fondo del contenedor donde se encuentre. Para los huecos, las pestañas y la celda inferior se tendrá en cuenta el orden en la sobreescritura de los bordes. Por supuesto, hay que mantener la consistencia en los colores usados. Así el color gray es el gris del borde mientras que el rgb(230,230,205) es el gris claro de los fondos.

Por último los contenedores div que finalmente disponen el contenido a presentar deberán ser adecuadamente dimensionados. El estilo anterior es genérico y sirve para todos los contenedores. Especificamos ancho 100% y el alto será auto. Luego para cada aplicación fijaremos las medidas que necesitemos. Así para el primer ejemplo anterior de esta página tenemos este estilo que sobrescribe al anterior:

Para activar una pestaña y desactivar las otras hemos de usar Javascript. Este código está en la cabecera de esta página:

En el bucle se itera por el total de pestañas. Por lo tanto empezamos declarando un máximo de pestañas MAXTABS que podríamos insertar y así no tenemos que estar cambiando con cada aplicación el límite superior del bucle interior en la función que activa la pestaña. Es decir, este script nos sirve sin tocarlo para cualquier número de pestañas igual o inferior a ese límite.

Tras la actualización de Marzo 2014 y para mantener la compatibilidad con contenedores ya existentes, conservamos el funcionamiento expuesto en el párrafo anterior para no tener que modificar el HTML de esos contenedores. Sin embargo usando los atributos data-max y data-min en la tabla ya no será necesario iterar por todos los elementos hasta ese límite máximo, por lo que podremos obviar la variable MAXTABS.

Con la carga de la página activamos la primera pestaña, o la que deseemos. Luego la función activarTab(unTab) nos ejecuta el evento onclick() ubicado en las pestañas. El argumento trae una referencia a la celda donde se hizo ese click. Obtenemos el identificador que es de la forma id="tabck-N" y extraemos el número N con split(). Localizamos el contenedor <div class="tabdiv-N"> para ese N. Luego iteramos por todas las pestañas activando la actual y desactivando las demás. Activamos con display = "block" y los colores de fondo, borde y letra deseados y desactivamos igualmente pero con valor none para display. La parte de pestañas en varias filas se explica más abajo.

Contenedor de pestañas dentro de una pestaña

La actualización de Marzo 2014 de este componente fue debida a la necesidad de meter un contenedor de pestañas en una pestaña de otro contenedor. En el siguiente ejemplo tenemos uno exterior con tres pestañas. En la primera metemos otro contenedor con dos pestañas.

Ejemplo:

 Primera Segunda Tercera
id=tabdiv-100
 Cuarta Quinta
id=tabdiv-200
id=tabdiv-201
id=tabdiv-101
id=tabdiv-102

Hacemos uso del rango data-min="100" y data-max="102" para especificar las tres pestañas de la tabla exterior. En el <div id="tabdiv-100"> de la primera pestaña metemos otra tabla interior con estructura de pestañas y usando el rango data-min="200" y data-max="201" de sus dos pestañas.

El mismo script expuesto en el apartado anterior se encarga de iterar por las pestañas de cada rango, limitándose a actuar sobre cada contenedor. Como en una página podemos tener muchos contenedores de pestañas, para organizarnos podemos usar rangos como 0..99, 100..199, 200..299, etc. para cada uno de los contenedores de la página. Particularizamos los anchos de los dos contenedores con este CSS (ubicado en la cabecera de esta página):

Contenedor con varias filas de pestañas

Y ya puestos con una actualización (Marzo 2014), porque no damos la posibilidad de tener varias filas de pestañas.

Ejemplo:

 Séptima Octava 
 Cuarta Quinta Sexta
 Primera Segunda Tercera
id=tabdiv-300
id=tabdiv-301
id=tabdiv-302
id=tabdiv-303
id=tabdiv-304
id=tabdiv-305
id=tabdiv-306
id=tabdiv-307

El código HTML para esto es así:

En primer lugar la tabla debe llevar un atributo data-filas sin ningún valor. Luego vemos que hay tres filas <tr> para pestañas. La penúltima fila de la tabla es la fila activa. Está antes de la fila con clase "filadiv" que incluye los contenidos que se muestran y ocultan. Cuando hagamos click en una pestaña de las filas superiores reubicamos esa fila para que pase a ser la fila activa. Este trozo de script se encuentra dentro de la función activarTab() expuesta en un apartado anterior:

Destacamos también que podemos poner menos pestañas en una fila. La primera fila tiene dos pestañas y las otras tienen tres. Esto se consigue agregando un th separador (clase "tabcks") con un colspan="2" para abarcar 2 columnas, pues el total de columnas en ese ejemplo debe ser 6.

Contenedor de pestañas en cuerpos de tabla

Esta segunda estructura es un poco más compleja que la anterior pues cada contenedor de cada pestaña se incluye en un cuerpo <tbody> de la tabla. Sabemos que una tabla siempre tiene uno al menos de estos elementos, aunque puede obviarse cuando se escribe el código. Así usamos una cabecera de tabla <thead> para ubicar las pestañas y 3 cuerpos <tbody> para los contenedores.

Ejemplo:

PrimeraSegundaTercera
Contenido de la Primera pestaña.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec sollicitudin libero id elit. Sed euismod nonummy neque. Nam dignissim urna vel urna. Nunc aliquet. Nunc vel dui mattis magna varius condimentum. Etiam lacus enim, aliquam ultricies, luctus ut, placerat id, lectus. Vestibulum laoreet commodo tortor. Nunc eget urna. Suspendisse ac orci. Vivamus quis tortor facilisis velit interdum blandit.

Otro contenido para la PESTAÑA 2ª
El último contenido de la Pestaña 3

El HTML de esta estructura es:

Las pestañas están en la cabecera de la tabla <thead>. Los eventos onclick="activarTabB(this, 'p-N') nos permitirán activar la pestaña N y desactivar el resto. Los contenidos están en los cuerpos <tbody>, donde podemos poner el número de filas <tr> que queramos. Pero cada fila tendrá sólo una celda <td> que abarcará tantas columnas como pestañas declarándose colspan="N" para N pestañas.

Este es el estilo que también está en la cabecera de este documento:

Este es el Javascript que también está en este documento:

El funcionamiento es similar al visto en el apartado anterior. Activamos la primera pestaña que deseemos con la carga de la página. Luego obtenemos el elemento <tbody>, buscamos su padre y luego obtenemos la colección de cuerpos de la tabla para iterar por ellos. El resto es lo mismo, activar la pestaña actual en este caso con tbs[i].style.display = "table-row-group" y desactivarla con el valor none.