Tablas

Las tablas HTML se usan para mostrar datos tabulares con filas y columnas. La decisión de usar un <table> debe basarse en el contenido que presentes y las necesidades de los usuarios en relación con ese contenido. Si se presentan, comparan, ordenan, calculan o se hacen referencias cruzadas, es probable que <table> sea la opción correcta. Si solo quieres diseñar el contenido no tabular de forma prolija, como un grupo grande de imágenes en miniatura, no es recomendable usar tablas. En cambio, crea una lista de imágenes y ajusta el diseño de la cuadrícula con CSS.

En esta sección, analizaremos todos los elementos que conforman la tabla, junto con algunas funciones de accesibilidad y usabilidad que debes tener en cuenta cuando presentes datos tabulares. Si bien Learn HTML no se trata en esencia sobre CSS, y hay un curso completo dedicado a aprender CSS, veremos algunas propiedades de CSS específicas de la tabla.

Elementos de la tabla, en orden

La etiqueta <table> une el contenido de la tabla, incluidos todos sus elementos. La función de ARIA implícita de un <table> es table. Las tecnologías de accesibilidad saben que este elemento es una estructura de tablas que contiene datos organizados en filas y columnas. Si la tabla mantiene un estado de selección, tiene navegación bidimensional o permite que el usuario reorganice el orden de las celdas, configura role="grid". Si las filas de grid se pueden expandir y contraer, utiliza role="treegrid" en su lugar.

Dentro de <table>, encontrarás los encabezados de la tabla (<thead>), los cuerpos de la tabla (<tbody>) y, de forma opcional, los pies de página (<tfoot>). Cada uno de estos elementos se compone de filas de tabla (<tr>). Las filas contienen celdas de encabezado de tabla (<th>) y datos de tabla (<td>) que, a su vez, contienen todos los datos. En el DOM, antes de esto, es posible que encuentres dos características adicionales: la leyenda de la tabla (<caption>) y los grupos de columnas (<colgroup>). Según si <colgroup> tiene o no un atributo span, puede contener elementos de columnas de tabla anidadas (<col>).

Los elementos secundarios de la tabla están en orden:

  1. Elemento <caption>
  2. Elementos <colgroup>
  3. Elementos <thead>
  4. Elementos <tbody>
  5. Elementos <tfoot>

Abordaremos los elementos secundarios de los elementos <table>, que son opcionales, pero recomendados, y, luego, analizaremos las filas, las celdas de encabezado de la tabla y las celdas de datos de la tabla. <colgroup> se tratará en último lugar.

Leyenda de la tabla

Como es un elemento semántico nativo, <caption> es el método preferido para darle un nombre a una tabla. El elemento <caption> proporciona un título de tabla descriptivo asociado de manera programática. Es visible y está disponible para todos los usuarios de forma predeterminada.

El elemento <caption> debe ser el primer elemento anidado en el elemento <table>. Incluirla permite a todos los usuarios conocer el propósito de la tabla de inmediato, sin tener que leer el texto circundante. De manera alternativa, puedes usar aria-label o aria-labelledby en <table> para proporcionar un nombre accesible como subtítulo. El elemento <caption> no tiene atributos específicos para cada elemento.

La leyenda aparecerá fuera de la tabla. La ubicación de la leyenda se puede establecer con la propiedad caption-side de CSS, lo que es una mejor práctica que usar el atributo align obsoleto. Esto puede hacer que la leyenda aparezca en la parte superior e inferior. El posicionamiento del lado izquierdo y derecho, con inline-start y inline-end, aún no es totalmente compatible. La parte superior es la presentación del navegador predeterminada.

Preferentemente, las tablas de datos deben tener encabezados y leyendas claros, y ser lo suficientemente simples como para ser casi claras. Ten en cuenta que no todos los usuarios tienen las mismas habilidades cognitivas. Cuando la tabla esté "explicando un argumento" o necesite interpretación, brinda un breve resumen del punto o la función principal de la tabla. La ubicación de ese resumen depende de su longitud y complejidad. Si es breve, úsala como texto interno del subtítulo. Si es más larga, resúmelo en el subtítulo y proporciona el resumen en el párrafo anterior a la tabla, y asocia ambos con el atributo aria-describedby. Otra opción es colocar la tabla en un <figure> y colocar el resumen en <figcaption>.

División de datos

El contenido de las tablas se compone de hasta tres secciones: cero o más encabezados de tabla (<thead>), cuerpos de tabla (<tbody>) y pies de página de tabla (<tfoot>). Todas son opcionales y se admiten cero o más de cada una.

Estos elementos no ayudan ni entorpecen la accesibilidad de la tabla, pero son útiles en términos de usabilidad. Ofrecen enlaces de estilo. Por ejemplo, el contenido del encabezado puede volverse fijo, mientras que el contenido de <tbody> se puede hacer que se desplace. Las filas que no están anidadas en uno de los tres elementos que lo contienen se unen de forma implícita a un <tbody>. Los tres comparten el mismo rol implícito rowgroup. Ninguno de estos tres elementos tiene atributos específicos.

Qué tenemos hasta ahora:

<table>
  <caption>MLW Students</caption>
  <thead></thead>
  <tbody></tbody>
  <tfoot></tfoot>
</table>

Originalmente, se especificó el elemento <tfoot> para que aparezca justo después de <thead> y antes de <tbody> por motivos de accesibilidad, por lo que puedes encontrar este orden de origen no intuitivo en las bases de código heredadas.

Contenido de la tabla

Las tablas se pueden dividir en encabezados, cuerpos y pies de página, pero ninguno de estos realmente hace nada si las tablas no contienen filas, celdas ni contenido. Cada fila de la tabla, <tr>, contiene una o más celdas. Si una celda es una celda de encabezado, usa <th>. De lo contrario, usa <td>.

Las hojas de estilo del usuario-agente suelen mostrar el contenido en una celda de encabezado de tabla <th> centrado y en negrita. Estos estilos predeterminados, y todos los estilos, se controlan mejor con CSS en lugar de con los atributos obsoletos que estaban disponibles en celdas, filas y, también, <table> individuales.

Había atributos para agregar relleno entre las celdas y dentro de ellas, para los bordes y para la alineación del texto. El padding y el espacio de celdas, que definen el espacio entre el contenido de una celda y su borde, y entre los bordes de las celdas adyacentes, deben establecerse con las propiedades border-collapse y border-spacing de CSS, respectivamente. Border-spacing no tendrá efecto si se configura border-collapse: collapse. Si se configura border-collapse: separate;, es posible ocultar celdas vacías por completo con empty-cells: hide;. Para obtener más información sobre cómo aplicar diseño a las tablas, consulta una presentación interactiva de estilos de CSS relacionados con tablas.

En los ejemplos, agregamos un borde en la tabla y cada celda individual con CSS para que algunas características sean más evidentes:

En este ejemplo, tenemos una leyenda, un encabezado de tabla y un cuerpo de tabla. El encabezado tiene una fila que contiene tres celdas <th> de encabezado, lo que crea tres columnas. El cuerpo contiene tres filas de datos: la primera celda es una celda de encabezado para la fila, por lo que usamos <th> en lugar de <td>.

La celda <th> tiene un significado semántico, con funciones de ARIA implícitas de columnheader o rowheader. Define la celda como el encabezado de la columna o fila de celdas de la tabla, según el valor del atributo scope enumerado. El navegador usará col o row de forma predeterminada si scope no se establece de forma explícita. Como usamos lenguaje de marcado semántico, la celda 1956 tiene dos encabezados: Año y Lou Minious. Esta asociación nos dice que "1956" es el "año" de graduación de "Lou Minious". En este ejemplo, como podemos ver toda la tabla, la asociación es visualmente evidente. El uso de <th> proporciona la asociación incluso cuando la columna o fila del encabezado se desplazó fuera de la vista. Podríamos haber configurado <th scope="col">Year</th> y <th scope="row">Lou Minious</th> de forma explícita, pero con una tabla simple como esta, los valores predeterminados enumerados funcionan Otros valores para scope incluyen rowgroup y colgroup, que son útiles con tablas complejas.

Combinar celdas

Al igual que en Microsoft Excel, Google Sheets y Numbers, es posible unir múltiples celdas en una sola. Esto se hace con HTML. El atributo colspan se usa para combinar dos o más celdas adyacentes dentro de una sola fila. El atributo rowspan se usa para combinar celdas en filas y colocarlas en la celda de la fila superior.

En este ejemplo, el encabezado de la tabla contiene dos filas. La primera fila de encabezado contiene tres celdas que abarcan cuatro columnas: la celda del medio tiene colspan="2". Esto combina dos celdas adyacentes. La primera y la última celda incluyen rowspan="2". Esto combina la celda con la celda de la fila adyacente, justo debajo de ella.

La segunda fila del encabezado de la tabla contiene dos celdas, que son las celdas de la segunda y la tercera columna de la segunda fila. No se declara ninguna celda para la primera o la última columna, ya que la celda en la primera y la última columna de la primera fila abarca dos filas.

En los casos en que una celda esté definida por varias celdas de encabezado con asociaciones que no se puedan establecer solo con los atributos scope, incluye el atributo headers con una lista separada por espacios de los encabezados asociados. Como este ejemplo es una tabla más compleja, definimos explícitamente el alcance de los encabezados con el atributo scope. Para ser aún más claros, agregamos el atributo headers a cada celda.

Es posible que los atributos headers no sean necesarios en un caso de uso tan simple, pero es importante tenerlos en tu barra de herramientas a medida que aumenta la complejidad de tus tablas. Las tablas con estructuras complejas, como aquellas en las que se combinan encabezados o celdas, o con más de dos niveles de encabezados de columna o fila, requieren una identificación explícita de las celdas de encabezado asociadas. En tablas tan complejas, asocia explícitamente cada celda de datos con cada celda de encabezado correspondiente con una lista de valores id separados por espacios de todos los encabezados asociados como el valor del atributo headers.

El atributo headers se encuentra con más frecuencia en los elementos <td>, pero también es válido en <th>.

Dicho esto, las estructuras de tablas complejas pueden ser difíciles de entender para todos los usuarios, no solo para los usuarios de lectores de pantalla. A nivel cognitivo y en cuanto a la compatibilidad con lectores de pantalla, las tablas más simples, con pocas celdas distribuidas o ninguna, incluso sin agregar alcance ni encabezados, se comprenden con mayor facilidad. Además, son más fáciles de administrar.

Cómo dar estilo a las tablas

Hay dos elementos relativamente desconocidos que se mencionaron brevemente: el grupo de columnas, <colgroup>, el elemento y su único subordinado, el elemento de columna vacío <col>. El elemento <colgroup> se usa para definir grupos de columnas, o elementos <col>, dentro de una tabla.

Si se usa, la agrupación de columnas debe anidarse en <table>, inmediatamente después de <caption> y antes de cualquier dato de la tabla. Si abarcan más de una columna, usa el atributo span.

El orden del esquema de contenido de una tabla es, por lo general, de la siguiente manera, con <table> y <caption> los dos elementos que se deben incluir:

<table>
  <caption>Table Caption</caption>
  <colgroup>
    <col/>
  </colgroup>
  <thead>...

Ni <colgroup> ni <col> tienen un significado semántico para ayudar a que la tabla sea más accesible, pero permiten un estilo de columna limitado, incluida la configuración de un ancho para la columna con CSS.

Los estilos <col> definirán el diseño de una columna, siempre que no haya estilos <td> o <th> que anulen ese estilo. Por ejemplo, cuando se usa <colspan> para combinar celdas en algunas filas de una tabla, pero no para todas, no puedes estar seguro de que un selector como tr > *:nth-child(8), que elige el octavo elemento secundario de cada fila, resaltará la 8a columna por completo o la 8a columna en varias filas, pero con un pequeño fragmento de las celdas de la 9a y la 10a columna, según la fila o las celdas que se hayan combinado.

Lamentablemente, solo se admiten algunas propiedades, los diseños no se heredan en las celdas y la única forma de usar el elemento <col> en las celdas de segmentación es con un selector complejo que incluya el selector relacional :has().

Renderización en capas de los elementos utilizados para diseñar tablas HTML.

Si <table> y <colgroup> tienen un color de fondo, el background-color de <colgroup> estará en la parte superior. El orden de dibujo es: tabla, grupos de columnas, columnas, grupos de filas, filas, con celdas al final y en la parte superior, como se muestra en el esquema de capas de tabla. Los elementos <td> y <th> no son descendientes de los elementos <colgroup> ni <col>, y no heredan su estilo.

Para segmentar una tabla, los selectores estructurales de CSS son útiles. Por ejemplo, tbody tr:nth-of-type(odd) {background-color: rgba(0 0 0 / 0.1);} agregará un negro translúcido a cada fila impar del cuerpo de la tabla, lo que permitirá que se muestren los efectos de fondo establecidos en <colgroup>.

Las tablas no responden de forma predeterminada. sino que se ajustan según su contenido de forma predeterminada. Se necesitan medidas adicionales para que el diseño de tabla funcione de manera eficaz en una variedad de dispositivos. Si cambias la propiedad de visualización de CSS para los elementos de la tabla, incluye los atributos role de ARIA. Si bien esto puede sonar redundante, la propiedad display de CSS puede afectar el árbol de accesibilidad en algunos navegadores.

Presentación de datos

Los elementos de las tablas tienen significados semánticos que usan las tecnologías de accesibilidad para permitir la navegación por las filas y columnas sin perderse. No se debe usar el elemento <table> para la presentación. Si necesitas un encabezado sobre una lista, usa un encabezado y una lista. Si deseas distribuir el contenido en muchas columnas, usa el diseño de varias columnas. Si deseas diseñar el contenido en una cuadrícula, usa la cuadrícula de CSS. Usa solo una tabla para los datos. Piénsalo de esta manera: si tus datos requieren una hoja de cálculo para presentarse en una reunión, usa <table>. Si deseas usar las funciones disponibles en los software de presentaciones, como Keynote o PowerPoint, es probable que necesites una lista de descripciones.

Si bien ordenar las columnas de la tabla es el campo de acción de JavaScript, el marcado de tus encabezados para que los usuarios sepan que la columna se puede ordenar es el campo de acción de HTML. Informa a los usuarios que las columnas de la tabla se pueden ordenar con iconografía que muestra ascendente, descendente o sin ordenar. La columna ordenada actualmente debe incluir el atributo aria-sort con el valor enumerado de la dirección de orden. El <caption> puede anunciar amablemente actualizaciones para ordenar a través de aria-live y un intervalo que se actualiza de forma dinámica y que es visible para los usuarios de lectores de pantalla. Como se puede ordenar la columna con un clic en el contenido del encabezado, este debe ser una <button>.

Si no presentas datos tabulares, no uses un <table>. Si usas una tabla para la presentación, configura role="none".

Muchos desarrolladores usan tablas para diseñar formularios, pero no es necesario hacerlo. Pero sí necesitas saber sobre los formularios HTML, así que lo veremos a continuación.

Verifica tus conocimientos

Pon a prueba tus conocimientos sobre tablas.

¿Qué elemento se usa para marcar celdas que son encabezados?

<header>
Vuelve a intentarlo.
<caption>
Vuelve a intentarlo.
<th>
Correcto.

¿Qué información es probable que sea adecuada para el diseño con una tabla?

Algunos términos científicos y su descripción.
Vuelve a intentarlo, más adecuado para una <dl>.
Una hoja de cálculo con información que detalla a los estudiantes y sus grados durante 3 semestres.
Correcto.
Ingredientes de una receta.
Vuelve a intentarlo, más adecuado para una <ul>.