Tabelas

As tabelas HTML são usadas para exibir 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, então <table> é provavelmente a escolha certa. Se você quer apenas apresentar um conteúdo não tabular de maneira elegante, como um grande grupo de imagens em miniatura, as tabelas não são apropriadas. 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ê precisa considerar ao apresentar dados tabulares. Embora o curso "Aprenda HTML" não seja basicamente sobre CSS e há um curso inteiro dedicado ao aprendizado de CSS, vamos abordar algumas propriedades CSS específicas para tabelas.

Elementos da tabela, em ordem

A tag <table> envolve o conteúdo da tabela, incluindo todos os elementos dela. A função ARIA implícita de um <table> é table. As tecnologias adaptativas sabem que esse elemento é uma estrutura de tabela contendo dados organizados em linhas e colunas. Se a tabela manter 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 de <table>, você encontra os cabeçalhos (<thead>), o corpo da tabela (<tbody>) e, opcionalmente, os rodapés (<tfoot>). Cada um é composto por linhas da tabela (<tr>). As linhas contêm o cabeçalho da tabela (<th>) e as células de dados da tabela (<td>), que, por sua vez, contêm todos os dados. No DOM, antes de qualquer uma dessas opções, você pode encontrar dois recursos adicionais: a legenda da tabela (<caption>) e os grupos de colunas (<colgroup>). Dependendo se <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 filhos dos elementos <table>, que são opcionais, mas recomendados, e depois analisar as linhas, as células de cabeçalho e de dados da tabela. O <colgroup> vai ser abordado por último.

Legenda da tabela

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

O elemento <caption> precisa ser o primeiro aninhado no <table>. Incluí-la permite que todos os usuários saibam a finalidade da tabela imediatamente, sem precisar ler o texto ao redor. Como alternativa, você pode usar aria-label ou aria-labelledby na <table> para fornecer um nome acessível como 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, o que é uma prática melhor do que usar o atributo align descontinuado. Isso pode definir a legenda para cima e para baixo. As posições esquerda e direita, com inline-start e inline-end, ainda não são totalmente compatíveis. A parte de cima é a apresentação padrão do navegador.

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

Seção de dados

O conteúdo das tabelas é composto de até três seções: zero ou mais cabeçalhos de tabela (<thead>), corpo da tabela (<tbody>) e rodapés de tabela (<tfoot>). Todas são opcionais, com suporte a 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 ganchos de estilo. Por exemplo, o conteúdo do cabeçalho pode ser fixo, enquanto o conteúdo de <tbody> pode ser feito para rolagem. As linhas não aninhadas em um desses três elementos contidos 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 vir logo após <thead> e antes de <tbody> por motivos de acessibilidade. É por isso que você pode encontrar essa ordem de origem não intuitiva em bases de código legadas.

Conteúdo da tabela

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

As folhas de estilo do user agent geralmente exibem o conteúdo centralizado e em negrito em uma célula de cabeçalho da tabela <th>. É melhor controlar esses estilos padrão e todos os estilos com CSS em vez dos atributos descontinuados que estavam disponíveis em células, linhas e até mesmo <table>.

Havia atributos para adicionar padding entre células e dentro das células, para bordas e para alinhamento de texto. O padding e o espaçamento das células, que definem o espaço entre o conteúdo e a borda de uma célula e entre as bordas das 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; estiver definido, é possível ocultar completamente células vazias com empty-cells: hide;. Para saber mais sobre como estilizar tabelas, confira uma apresentação interativa de estilos CSS relacionados a tabelas.

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

Neste exemplo, temos uma legenda, um cabeçalho de tabela e um corpo de tabela. O cabeçalho tem uma linha contendo três células <th> de cabeçalho, criando três colunas. O corpo contém três linhas de dados: a primeira célula é uma célula de cabeçalho para a 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 rowheader. 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: Year e Lou Minious. Essa associação nos diz que "1956" é o "ano" de graduação de "Lou Minious". Nesse 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 saiu da visualização. Poderíamos ter definido 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 de scope incluem rowgroup e colgroup, que são úteis com tabelas complexas.

Mesclar células

Assim como no Excel, no Planilhas Google e no Numbers, é possível juntar 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 superior.

Neste exemplo, o cabeçalho da tabela contém duas linhas. A primeira linha do 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. A primeira e a última células incluem rowspan="2". Isso mescla a célula com a célula da linha adjacente, imediatamente abaixo dela.

A segunda linha no cabeçalho da tabela contém duas células; estas são as células da segunda e terceira colunas da segunda linha. Nenhuma célula é declarada para a primeira ou a última coluna como a célula na primeira e na última coluna da primeira linha abrangendo 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 esse exemplo é uma tabela mais complexa, definimos explicitamente o escopo dos cabeçalhos com o atributo scope. Para deixar ainda mais claro, adicionamos o atributo headers a cada célula.

Os atributos headers podem não ser necessários em um caso de uso tão simples, mas é importante tê-los em seu conjunto de ferramentas à medida que suas tabelas ficam mais complexas. Tabelas com estruturas complexas, como aquelas em que 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. Nessas tabelas complexas, associe explicitamente cada célula de dados a cada célula de cabeçalho correspondente a 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 comumente encontrado em elementos <td>, mas também é válido em <th>.

Dito isso, pode ser difícil para todos os usuários, não apenas usuários de leitores de tela, entender estruturas de tabela complexas. Em termos de suporte a leitores de tela, tabelas mais simples, com poucas ou nenhuma célula, mesmo sem a adição de escopo e cabeçalhos, são mais facilmente entendidas. Além disso, são mais fáceis de gerenciar.

Como definir o estilo de tabelas

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

Se usado, o agrupamento de colunas precisará ser aninhado no <table>, imediatamente após a <caption> e antes dos dados da tabela. Se elas abrangem mais de uma coluna, use o atributo span.

A ordem de descrição do conteúdo para 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 eles permitem um estilo limitado de coluna, incluindo a configuraçã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 garantir que um seletor como tr > *:nth-child(8), que seleciona o oitavo filho de cada linha, destacará a oitava coluna na íntegra ou destacará a oitava coluna em várias linhas, mas com uma cobertura das células da 9a e 10a coluna, dependendo de qual linha ou coluna foi mesclada.

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

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

Se a <table> e a <colgroup> tiverem uma cor de fundo, a background-color da <colgroup> vai ficar na parte de cima. A ordem do desenho é: 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 da tabela. Os elementos <td> e <th> não são descendentes de elementos <colgroup> ou <col> e não herdam o estilo.

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

Por padrão, as tabelas não são responsivas. Em vez disso, eles são dimensionados por padrão de acordo com seu conteúdo. São necessárias medidas extras para que o estilo do layout da tabela funcione de forma eficaz em vários dispositivos. Se você estiver alterando a propriedade de exibição CSS para elementos da tabela, inclua atributos role ARIA. Isso pode parecer redundante, mas a propriedade display do CSS pode afetar a árvore de acessibilidade em alguns navegadores.

Apresentar dados

Os elementos da 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. Não use o elemento <table> para a apresentação. Se precisar de um cabeçalho em uma lista, use um cabeçalho e uma lista. Se você quiser organizar o conteúdo em várias colunas, use o layout de várias colunas. Se você quiser posicionar o conteúdo em uma grade, use a grade CSS. Use apenas uma tabela para dados. Pense desta forma: se seus 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ções.

Embora a classificação das colunas da tabela seja da função do JavaScript, a marcação dos cabeçalhos para informar aos usuários que a coluna pode ser classificada é do HTML. Informe aos usuários que as colunas da tabela podem ser classificadas, com a iconografia mostrando em ordem crescente, decrescente ou não classificada. A coluna classificada no momento precisa incluir o atributo aria-sort com o valor enumerado da direção de classificação. O <caption> pode anunciar educadamente as atualizações na ordem de classificação via aria-live e um período que é atualizado dinamicamente e que fica visível para usuários de leitores de tela. Como a coluna pode ser classificada clicando no conteúdo do cabeçalho, esse conteúdo precisa ser um <button>.

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

Muitos desenvolvedores usam tabelas para criar formulários, mas isso não é necessário. Mas você precisa saber sobre formulários HTML, então falaremos sobre isso a seguir.

Teste seu conhecimento

Teste seu conhecimento sobre tabelas.

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

<header>
Tente de novo.
<caption>
Tente de novo.
<th>
Correto.

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

Alguns termos científicos e sua descrição.
Tente novamente. Esse recurso é mais adequado para um <dl>.
Uma planilha de informações detalhando os alunos e as notas deles ao longo de três semestres.
Correto.
Ingredientes de uma receita.
Tente novamente. Esse recurso é mais adequado para um <ul>.