soy Kseso y esto EsCSS

Tables & Responsive Times: scroll en Tbody y Thead fixed puro Css

Tabla reponsive con encabezado fijo y scroll al cuerpo (tbody) sin necesidad de añadir elementos extras en el marcado Html o de tener que descomponer la tabla. Sólo con Css

Tables & Responsive Times: scroll en Tbody y Thead fixed puro Css

·Por Kseso ✎ 5

Hace ya un tiempo publiqué un artículo recopilatorio de técnicas para hacer nuestras tablas con el encabezado Thead fijo y el cuerpo Tbody con scroll o desplazamiento en caso de superar cierto número de filas: tablas con scroll y encabezado fijo en puro Css

Métodos que requieren de ajustes complejos y finos para adaptarlos a las necesidades de cada caso. Adaptaciones que a muchos usuarios hacen desistir de lograrlo.

A la vez, estos últimos días me han llegado algunas consultas relativas a cómo hacer responsive tables. Esto es, que además de adaptarse al viewport se mantengan visibles los valores del encabezado thead de la tabla en tamaños pequeños para saber qué es cada dato.

Esto último, responsive table, es el tema que desarrolla en octuweb.com Martín Iglesias en su artículo. Y fue este post el que me hizo recordar que tenía pendiente la resolución de lo primero (encabezado fijo con scroll al tbody) para evitar tablas con altura infinita y ya puestos introducir lo segundo: RWD.

Responsive tables: Thead fixed and scroll on Tbody
Origen imagen: Internet Archive Book Images

Consideraciones de base

El elemento table y sus hijos,

  • encabezados
  • filas y grupos de filas
  • columnas y grupos de columnas
  • celdas

tienen asociado por defecto valores específicos para la propiedad display. Y dichos valores llevan aparejadas una serie de particularidades que los dotan de su comportamiento característico.

  • table
  • inline-table
  • table-row-group
  • table-column
  • table-column-group
  • table-header-group
  • table-footer-group
  • table-row
  • table-cell
  • table-caption

Encabezado fijo y scroll al cuerpo

Por el mismo motivo, el algoritmo usado para su composición hace que una serie de propiedades y/o valores css no surtan efecto en ellos. O que no sea el deseado al esperar que fuese el mismo que en otros elementos.

Por lo tanto, para lograr lo primero (encabezado fijo y cuerpo con scroll) hay que cambiar el valor asociado al display del Tbody y sus filas.

Al hacerlo así no es necesario ni descomponer la tabla ni añadir otros elementos.

La misma tabla en dos resoluciones diferentes
La misma tabla en dos resoluciones diferentes

Mi primera aproximación fue usar el modelo de caja del flexbox. Pero me encontré con cierto bug en Firefox. A la espera de poder dedicarle una segunda mirada terminé por replantearlo y recurrir a otras más "tradicionales".

tbody { display: block; height: 40vh; min-height: 200px; overflow-Y: scroll; } tr { display: block; overflow: hidden; }

La parte "responsive"

Por tabla responsive se suele entender aquella que al llegar a un tamaño tal del viewport pasa de mostrar el encabezado y debajo todas las celdas en una misma fila a colocar una celda por fila y a su lado indicar de alguna manera el tipo de valor que es (su valor en el th) ocultando el Thead.

Las dos acciones, como es lógico, deben ir en su @media query correspondiente. El valor de la misma dependerá de las particularidades de cada tabla y el punto de ruptura.

See the Pen RWD table by Kseso (@Kseso) on CodePen.

Una versión sencilla (sin scroll) de la tabla RWD

Ver Demo en Codepen

Nota del Editor: Tanto este pen como el siguiente que se incluyen en el artículo están en un elemento con la declaración resize:horizontal;. Sim embargo en Chrome no podrás hacer uso de ello ya que no permite redimensionar al elemento a un tamaño menor.

Lo primero, una celda por fila, es relativamente sencillo. Sólo es cuestión de cambiar, una vez más, el valor de su display: table-cell por otro que evite que nada más se posicione en su misma línea: block.

La segunda parte, mostrar junto a cada celda el tipo de dato que es se puede lograr de dos formas. Todo depende de cómo se genere la tabla.

  1. Tabla generada por programación
    Si la tabla va a ser generada a demanda mediante algún lenguaje de programación y de caso a caso variará, todo se reduce a añadir un atributo de autor a todas y cada una de las celdas td, en mi demo data-campo y cuyo valor coincida con el asignado en el thead.
  2. Tabla "manual", escrita "a mano"
    En este caso, y para evitar lo tedioso y propenso a errores que resultaría repetir para cada td dicho atributo de autor con su valor correspondiente se lo encomendamos a Css.

En el primer caso del marcado html generado por programación sería algo como el siguiente código:

<tr> <td data-campo='Nick'>Fulano</td> <td data-campo='Mail'>Fulano@gmail.com</td> <td data-campo='Web'>fulano.es</td> <td data-campo='Twitter'>@Fulano</td> <td data-campo='Id'>1</td> </tr>

Y para mostrarlo sólo se necesita de una regla Css:

td:before { content: attr(data-campo); /* resto de declaraciones */ }

En el segundo caso, evitar tener que añadir a mano el valor del falso Thead, le encomendamos a Css todo, generación y presentación:

td:nth-child(1):before {content: 'Nick';} td:nth-child(2):before {content: 'Mail';} td:nth-child(3):before {content: 'Web';} td:nth-child(4):before {content: 'Twitter';} td:nth-child(5):before {content: 'Id';} /* regla con las declaraciones comunes */

Sin demo... dragones en el garaje

Todo lo anterior, y un poco más de estilos por aquello de adornarlo algo, en especial contemplar el caso de necesitar que cada encabezado th necesite de distintas anchuras lo puedes ver en el siguiente pen. Juega con la anchura y altura de la ventana para ver las transformaciones que conllevan.

See the Pen Rwd table: Thead fixed & Tbody scrolled by Kseso (@Kseso) on CodePen.

Responsive table con scroll en el Tbody y encabezado fijo en puro Css

Ver Demo en Codepen

Disclaimer

pen picked en codepen
Pen portada en codepen

De los navegadores actuales, sólo he podido probar su correcto funcionamiento en Firefox y Chrome en su última versión estable.

Así que si pruebas y notas alguna cosilla que no acabe de funcionar, abajo, en los comentarios, puedes comentarla. Y si aportas alguna solución, mejor que mejor.

Alpiste para el ego: esta demo fue mostrada en portada de Codepen.io (picks) :-))

También en la misma página de la demo me avisan de un bug en IE9 y menores en un comentario.

Bug en IE9 y menores. Fixed

ACTUALIZACIÓN y BUG FIXED

Aviso de bug en IE9 y menores
Aviso de bug en IE9 y menores

Por diversos medios me comentan que en IE9 y menores presenta un malfuncionamiento la demo: los td presentan una altura desorbitada que la hacen inutilizable.

Ahora que lo he podido ver, creo que el problema estriba en que tanto las filas como celdas heredan la altura declarada en tbody.

Así que identificado el origen, la solución es sencilla: hacer que en esos navegadores antiguos no existan dichas alturas:

table * {height: auto; min-height: none;} tbody { height: calc(50vh - 1px); min-height: calc(200px + 1 px); /*resto declaraciones*/ }

En los IE9 y menores no tenemos scroll en el tbody pero la tabla ahora ya es usable. Actualización incluida en la demo.

Más sobre tablas y diseño "responsive"

Con el paso del del tiempo en el blog han ido apareciendo una serie de artículos dedicados a las tablas y diversos aspectos de ellas.

Algunos son demos puro CSS más o menos "extremas" pero usables y otros, obra de Furoya, dedicados a su manejo y tratamiento javascript mediante. Estos son algunos de ellos:

  1. Tablas Css. Display: table y asociadas. Su oportunidad en el responsive design
  2. Layouts Css. Pasado, presente y futuro
  3. Tablas con encabezado fijo de filas, 1ª columna fija y desplazamiento por datos
  4. Permutar el orden de elementos con display: table y asociadas
  5. Javascript con Furoya: filtrar filas por palabra clave contenida en sus celdas
  6. From table to tabs pure Css

avatar del Editor del blog

the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso