Tabelas

As tabelas HTML são usadas para mostrar dados tabulares com linhas e colunas. A decisão de usar um <table> precisa ser baseada no conteúdo que você está apresentando e nas necessidades dos usuários em relação a esse conteúdo. Se os dados estiverem sendo apresentados, comparados, classificados, calculados ou cruzados, <table> provavelmente é a escolha certa. Se você quiser apenas organizar conteúdo não tabular de maneira organizada, como um grande grupo de imagens em miniatura, as tabelas não são adequadas. Em vez disso, crie uma lista de imagens e estilize a grade com CSS.

Nesta seção, vamos discutir todos os elementos que compõem a tabela, além de alguns recursos de acessibilidade e usabilidade que você deve considerar ao apresentar dados tabulares. Embora o curso "Aprenda HTML" não seja sobre CSS e tenhamos um curso inteiro dedicado a aprender CSS, vamos abordar algumas propriedades CSS específicas de tabelas.

Elementos da tabela, em ordem

A tag <table> envolve o conteúdo da tabela, incluindo todos os elementos dela. O papel ARIA implícito de um <table> é table. As tecnologias adaptativas sabem que esse elemento é uma estrutura de tabela que contém dados organizados em linhas e colunas. Se a tabela mantiver um estado de seleção, tiver navegação bidimensional ou permitir que o usuário reorganize a ordem das células, defina role="grid". Se as linhas da grid puderem ser expandidas e recolhidas, use role="treegrid".

Dentro do <table>, você encontra os cabeçalhos de tabela (<thead>), os corpos de tabela (<tbody>) e, opcionalmente, os rodapés de tabela (<tfoot>). Cada um deles é composto por linhas de tabela (<tr>). As linhas contêm células de cabeçalho de tabela (<th>) e dados de tabela (<td>), que, por sua vez, contêm todos os dados. No DOM, antes de tudo isso, você pode encontrar dois recursos adicionais: o título da tabela (<caption>) e os grupos de colunas (<colgroup>). Dependendo se o <colgroup> tem ou não um atributo span, ele pode conter elementos de coluna de tabela aninhada (<col>).

Os filhos da tabela são, em ordem:

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

Vamos abordar os elementos filhos de <table>, que são todos opcionais, mas recomendados. Em seguida, vamos analisar linhas, células de cabeçalho de tabela e células de dados de tabela. O <colgroup> será abordado por último.

Legenda da tabela

Por ser um elemento semântico nativo, o <caption> é o método preferido para dar um nome a uma tabela. O <caption> fornece um título de tabela descritivo e associado programaticamente. Ela fica visível e disponível para todos os usuários por padrão.

O elemento <caption> precisa ser o primeiro elemento aninhado no elemento <table>. A inclusão permite que todos os usuários saibam o propósito da tabela imediatamente, sem precisar ler o texto ao redor. Como alternativa, use aria-label ou aria-labelledby no <table> para fornecer um nome acessível como a legenda. O elemento <caption> não tem atributos específicos.

A legenda aparece fora da tabela. O local da legenda pode ser definido com a propriedade CSS caption-side, que é uma prática melhor do que usar o atributo align descontinuado. Isso pode definir a legenda na parte de cima e de baixo. O posicionamento do lado esquerdo e direito, com inline-start e inline-end, ainda não tem suporte total. A parte de cima é a apresentação padrão do navegador.

De preferência, as tabelas de dados devem ter cabeçalhos claros e uma legenda, além de serem simples o suficiente para serem quase autoexplicativas. Tenha em mente que nem todos os usuários têm as mesmas habilidades cognitivas. Quando a tabela "faz um ponto" ou precisa de interpretação, forneça um breve resumo do ponto ou da função principal da tabela. O local onde o resumo é colocado depende da duração e da complexidade. Se for breve, use como texto interno da legenda. Se for mais longo, resuma na legenda e forneça o resumo no parágrafo anterior à tabela, associando os dois com o atributo aria-describedby. Outra opção é colocar a tabela em um <figure> e o resumo no <figcaption>.

Seção de dados

O conteúdo das tabelas é composto por até três seções: zero ou mais cabeçalhos de tabela (<thead>), corpos de tabela (<tbody>) e rodapés de tabela (<tfoot>). Todos são opcionais, e é possível usar zero ou mais de cada um.

Esses elementos não ajudam nem dificultam a acessibilidade da tabela, mas são úteis em termos de usabilidade. Eles fornecem hooks de estilo. Por exemplo, o conteúdo do cabeçalho pode ser fixado, enquanto o conteúdo do <tbody> pode ser rolado. As linhas que não estão aninhadas em um desses três elementos de contenção são implicitamente encapsuladas em um <tbody>. Os três compartilham o mesmo papel implícito rowgroup. Nenhum desses três elementos tem atributos específicos.

O que temos até agora:

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

O elemento <tfoot> foi originalmente especificado para aparecer logo após o <thead> e antes do <tbody> por motivos de acessibilidade. É por isso que você pode encontrar essa ordem de origem não intuitiva em bases de código legados.

Conteúdo da tabela

As tabelas podem ser divididas em cabeçalhos, corpos e rodapés, mas nenhuma delas faz nada se as tabelas não contiverem linhas, células e conteúdo. Cada linha da tabela, <tr>, contém uma ou mais células. Se uma célula for de cabeçalho, use <th>. Do contrário, use <td>.

As folhas de estilo do user-agent geralmente mostram o conteúdo em uma célula de cabeçalho de tabela <th> como centralizado e em negrito. Esses estilos padrão, e todos os estilos, são melhor controlados com CSS em vez dos atributos descontinuados que costumavam estar disponíveis em células, linhas e até mesmo no <table>.

Havia atributos para adicionar padding entre e dentro das células, para bordas e alinhamento de texto. O preenchimento e o espaçamento de células, que definem o espaço entre o conteúdo de uma célula e a borda dela, e entre as bordas de células adjacentes, precisam ser definidos com as propriedades CSS border-collapse e border-spacing, respectivamente. Border-spacing não terá efeito se border-collapse: collapse estiver definido. Se border-collapse: separate; for definido, será possível ocultar completamente as células vazias com empty-cells: hide;. Para saber mais sobre a estilização de tabelas, confira este slideshow interativo de estilos CSS relacionados a tabelas.

Nos exemplos, adicionamos uma borda à tabela e a cada célula individual com CSS para tornar alguns recursos mais aparentes:

Neste exemplo, temos uma legenda, um cabeçalho e um corpo de tabela. O cabeçalho tem uma linha com três células <th>, criando três colunas. O corpo contém três linhas de dados: a primeira célula é uma célula de cabeçalho da linha, então usamos <th> em vez de <td>.

A célula <th> tem significado semântico, com papéis ARIA implícitos de columnheader ou cabeçalho de linha. Ele define a célula como o cabeçalho da coluna ou linha de células da tabela, dependendo do valor do atributo scope enumerado. O padrão do navegador será col ou row se scope não for definido explicitamente. Como usamos a marcação semântica, a célula 1956 tem dois cabeçalhos: "Ano" e "Lou Minious". Essa associação nos diz que "1956" é o "ano" de formatura de "Lou Minious". Neste exemplo, como podemos ver a tabela inteira, a associação é visualmente aparente. O uso de <th> fornece a associação mesmo quando a coluna ou linha de cabeçalho não está visível. Poderíamos definir explicitamente <th scope="col">Year</th> e <th scope="row">Lou Minious</th>, mas com uma tabela simples como essa, os valores padrão enumerados funcionam. Outros valores para scope incluem rowgroup e colgroup, que são úteis com tabelas complexas.

Mesclar células

Assim como no MS Excel, nas Planilhas Google e no Numbers, é possível mesclar várias células em uma só. Isso é feito com HTML. O atributo colspan é usado para mesclar duas ou mais células adjacentes em uma única linha. O atributo rowspan é usado para mesclar células em linhas, sendo colocado na célula da linha de cima.

Neste exemplo, o cabeçalho da tabela contém duas linhas. A primeira linha de cabeçalho contém três células que abrangem quatro colunas: a célula do meio tem colspan="2". Isso mescla duas células adjacentes. As primeiras e últimas células incluem rowspan="2". Isso mescla a célula com a célula na linha adjacente, imediatamente abaixo dela.

A segunda linha do cabeçalho da tabela contém duas células: as células da segunda e terceira colunas na segunda linha. Nenhuma célula é declarada para a primeira ou a última coluna, porque a célula nas primeiras e últimas colunas da primeira linha abrange duas linhas.

Nos casos em que uma célula é definida por várias células de cabeçalho com associações que não podem ser definidas apenas pelos atributos scope, inclua o atributo headers com uma lista separada por espaços dos cabeçalhos associados. Como este exemplo é uma tabela mais complexa, definimos explicitamente o escopo dos cabeçalhos com o atributo scope. Para ficar ainda mais claro, adicionamos o atributo headers a cada célula.

Os atributos headers talvez não fossem necessários em um caso de uso tão simples, mas são importantes para ter no seu conjunto de ferramentas à medida que as tabelas ficam mais complexas. Tabelas com estruturas complexas, como tabelas em que os cabeçalhos ou células são mesclados ou com mais de dois níveis de cabeçalhos de coluna ou linha, exigem a identificação explícita das células de cabeçalho associadas. Em tabelas complexas, associe explicitamente cada célula de dados à célula de cabeçalho correspondente com uma lista de valores id separados por espaços de todos os cabeçalhos associados como o valor do atributo headers.

O atributo headers é mais comum em elementos <td>, mas também é válido em <th>.

No entanto, estruturas de tabelas complexas podem ser difíceis de entender para todos os usuários, não apenas para usuários de leitores de tela. Do ponto de vista cognitivo e em termos de suporte a leitores de tela, tabelas mais simples, com poucas ou nenhuma célula estendida, mesmo sem adicionar escopo e cabeçalhos, são mais fáceis de entender. Eles também são mais fáceis de gerenciar.

Definir o estilo das tabelas

Há dois elementos relativamente obscuros que foram mencionados brevemente: o grupo de colunas, elemento <colgroup>, e o único descendente, o elemento de coluna vazio <col>. O elemento <colgroup> é usado para definir grupos de colunas ou elementos <col> em uma tabela.

Se usado, o agrupamento de colunas precisa ser aninhado no <table>, imediatamente após o <caption> e antes de qualquer dado da tabela. Se eles abrangerem mais de uma coluna, use o atributo span.

A ordem do esboço de conteúdo de uma tabela geralmente é a seguinte, com <table> e <caption> sendo os dois elementos que precisam ser incluídos:

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

Nem <colgroup> nem <col> têm significado semântico em termos de ajudar a tornar a tabela mais acessível, mas permitem estilização limitada de colunas, incluindo a definição de uma largura para a coluna com CSS.

Os estilos <col> vão estilizar uma coluna desde que não haja estilos <td> ou <th> que substituam esse estilo. Por exemplo, quando <colspan> é usado para mesclar células em algumas linhas de uma tabela, mas não em todas, não é possível ter certeza de que um seletor como tr > *:nth-child(8), que seleciona a oitava criança de cada linha, vai destacar a oitava coluna por completo ou vai destacar a oitava coluna para várias linhas, mas com algumas células da nona e da décima coluna, dependendo de quais células de linha ou coluna foram mescladas.

Infelizmente, apenas algumas propriedades são aceitas, os estilos não são herdados nas células, e a única maneira de usar o elemento <col> em células de segmentação é com um seletor complexo que inclui o seletor relacional :has().

Renderização em camadas dos elementos usados para projetar tabelas HTML.

Se <table> e <colgroup> tiverem uma cor de plano de fundo, o background-color do <colgroup> vai ficar por cima. A ordem de exibição é: tabela, grupos de colunas, colunas, grupos de linhas, linhas, com as células por último e na parte de cima, conforme mostrado no esquema de camadas de tabela. Os elementos <td> e <th> não são descendentes de elementos <colgroup> ou <col> e não herdam o estilo deles.

Para criar uma tabela, os seletores estruturais do CSS são úteis. Por exemplo, tbody tr:nth-of-type(odd) {background-color: rgba(0 0 0 / 0.1);} adiciona um preto translúcido a cada linha ímpar no corpo da tabela, permitindo que todos os efeitos de plano de fundo definidos em <colgroup> apareçam.

As tabelas não são responsivas por padrão. Em vez disso, eles são dimensionados de acordo com o conteúdo por padrão. Medidas extras são necessárias para que o estilo de layout de tabela funcione de maneira eficaz em vários dispositivos. Se você mudar a propriedade de exibição CSS dos elementos de tabela, inclua os atributos ARIA role. Embora isso possa parecer redundante, a propriedade CSS display pode afetar a árvore de acessibilidade em alguns navegadores.

Como apresentar dados

Os elementos de tabela têm significados semânticos que são usados por tecnologias adaptativas para permitir a navegação pelas linhas e colunas sem se perder. O elemento <table> não deve ser usado para apresentação. Se você precisar de um título sobre uma lista, use um cabeçalho e uma lista. Se você quiser definir o layout do conteúdo em várias colunas, use o layout de várias colunas. Se você quiser organizar o conteúdo em uma grade, use a grade CSS. Use uma tabela apenas para dados. Pense assim: se os dados exigem uma planilha para serem apresentados em uma reunião, use <table>. Se você quiser usar os recursos disponíveis em softwares de apresentação, como Keynote ou PowerPoint, provavelmente precisará de uma lista de descrição.

Se você não estiver apresentando dados tabulares, não use um <table>. Se você usar uma tabela para apresentação, defina role="none".

Muitos desenvolvedores usam tabelas para organizar formulários, mas isso não é necessário. Mas você precisa saber sobre formulários HTML, então vamos abordar isso em seguida.

Teste seu conhecimento

Teste seus conhecimentos sobre tabelas.

Qual elemento é usado para marcar células que são títulos?

<header>
Tente novamente.
<caption>
Tente novamente.
<th>
Correto!

Quais informações são adequadas para um layout com uma tabela?

Alguns termos científicos e a descrição deles.
Tente de novo. Isso é mais adequado para um <dl>.
Uma planilha de informações com detalhes sobre os estudantes e as notas deles em três semestres.
Correto!
Ingredientes de uma receita.
Tente de novo. Isso é mais adequado para um <ul>.