As tabelas HTML mostram dados tabulares com linhas e colunas. Escolha usar um <table> com base no conteúdo que você está mostrando e nas necessidades dos usuários em relação a esse conteúdo. Se os dados estiverem sendo apresentados, comparados, classificados, calculados ou com referências cruzadas, <table> provavelmente é a escolha certa.
Se você quiser organizar conteúdo não tabular, como um grande grupo de imagens em miniatura, as tabelas não são adequadas. Em vez disso, crie uma lista de imagens e defina o estilo da 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 a serem considerados ao apresentar dados tabulares. Embora o curso "Aprenda HTML" não se concentre em CSS, vamos abordar algumas propriedades de CSS específicas da tabela. Para saber mais sobre CSS, faça o curso Aprenda CSS.
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 assistivas 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 do grid puderem ser expandidas e recolhidas, use role="treegrid".
Dentro do <table>, você encontra os cabeçalhos (<thead>), os corpos (<tbody>) e, opcionalmente, os rodapés (<tfoot>) da tabela. Cada um deles é composto por linhas (<tr>), que contêm células de cabeçalho (<th>) e dados (<td>) da tabela, que, por sua vez, contêm todos os dados.
No DOM, antes de tudo isso, você pode encontrar dois recursos adicionais: a legenda da tabela (<caption>) e os grupos de colunas (<colgroup>). Dependendo se o <colgroup> tem ou não um atributo span, ele pode conter elementos aninhados de coluna da tabela (<col>).
Os filhos da tabela são, em ordem:
- Elemento
<caption> - Elementos
<colgroup> - Elementos
<thead> - Elementos
<tbody> - Elementos
<tfoot>
Vamos abordar os filhos dos elementos <table>, que são opcionais, mas recomendados. Depois, vamos analisar linhas, células de cabeçalho e de dados da tabela. O <colgroup> será abordado por último.
Legenda da tabela
O método preferido para nomear uma tabela é o elemento semântico,
<caption>.
O <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 elemento aninhado no elemento <table>. Incluir isso permite que todos os usuários saibam imediatamente a finalidade da tabela sem precisar ler o texto ao redor. Outra opção é usar aria-label ou aria-labelledby
no <table> para fornecer um nome acessível como legenda. O elemento <caption> não tem atributos específicos.
A legenda aparece fora da tabela. A localização da legenda pode ser definida 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 dos lados esquerdo e direito, com inline-start e inline-end, ainda não é totalmente compatível. A parte de cima é a apresentação padrão do navegador.
De preferência, as tabelas de dados precisam ter cabeçalhos e uma legenda claros e ser autoexplicativas. 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 dela. A posição do resumo depende do tamanho e da complexidade dele.
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 o resumo em um <figcaption>.
Seção de dados
O conteúdo das tabelas é composto por até três seções: zero ou mais cabeçalhos (<thead>), corpos (<tbody>) e rodapés (<tfoot>). Todas são opcionais, com suporte para zero ou mais de cada uma.
Esses elementos não ajudam nem prejudicam a acessibilidade da tabela, mas são úteis em termos de usabilidade. Eles fornecem hooks de estilização. Por exemplo, o conteúdo do cabeçalho pode ser fixado,
enquanto o conteúdo de <tbody> pode ser rolado. As linhas que não estão aninhadas em um desses três elementos contidos são implicitamente
encapsuladas em um <tbody>. Os três compartilham a mesma função implícita 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, 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 funciona se elas 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 de cabeçalho, use <th>.
Caso 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 toda a estilização são melhor controlados com CSS em vez dos atributos descontinuados que estavam 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 para alinhamento de texto. O cellpadding e o cellspacing, 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; estiver definido, será possível ocultar completamente as 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 à 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 de cabeçalho <th>, criando três colunas. O corpo contém três linhas de dados: a primeira célula é um cabeçalho da linha. Por isso, usamos <th> em vez de <td>.
A célula <th> tem significado semântico, com papéis ARIA implícitos de columnheader
ou rowheader. Ele define a célula como o cabeçalho da coluna ou linha de células da tabela,
dependendo do valor do atributo enumerado scope. O navegador vai usar col ou row como padrão 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 formatura de "Lou Minious". Neste exemplo, como podemos ver a tabela inteira, a associação é visualmente aparente.
Usar <th> fornece a associação mesmo quando a coluna ou linha de cabeçalho rola para fora da visualização. Poderíamos ter definido explicitamente <th scope="col">Year</th> e <th scope="row">Lou Minious</th>, mas com uma tabela 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, no Google Planilhas e no Numbers, é possível unir várias células em uma só. Isso pode ser feito com os atributos HTML colspan
e rowspan:
colspanmescla duas ou mais células adjacentes em uma única linha.- O
rowspanmescla células em várias linhas quando adicionado à célula na primeira das linhas mescladas.
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. A primeira e a última células incluem rowspan="2". Isso mescla a célula com a célula
na linha adjacente, logo abaixo dela.
A segunda linha no cabeçalho da tabela contém duas células, que são as células da segunda e terceira colunas na segunda linha. Nenhuma célula é declarada para a primeira ou a última coluna, já que a célula nas colunas primeira e última 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 deixar ainda mais claro, adicionamos o atributo headers a cada célula.
Os atributos headers podem não ter sido necessários neste caso, mas é importante lembrar deles à medida que suas tabelas aumentam em complexidade. Tabelas com estruturas complexas, como tabelas 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 identificação explícita das células de cabeçalho associadas. Em tabelas complexas, associe explicitamente cada célula de dados a cada 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 tabela complexas podem ser difíceis de entender para todos os usuários, não apenas para leitores de tela. Cognitivamente e em termos de suporte a leitores de tela, tabelas mais simples, com poucas ou nenhuma célula abrangida, são mais fáceis de entender, mesmo sem adicionar escopo e cabeçalhos. Além disso, eles são mais fáceis de gerenciar.
Definir o estilo das tabelas
Há dois elementos relativamente obscuros que foram mencionados brevemente: o elemento de grupo de colunas, <colgroup>, e o único descendente dele, 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 precisa ser aninhado no <table>,
imediatamente após o <caption> e antes dos dados da tabela.
Se eles abrangem mais de uma coluna, use o atributo span.
A ordem do contorno de 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>...
<colgroup> e <col> não têm significado semântico, o que afetaria a acessibilidade da tabela. No entanto, eles ajudam a estilizar colunas com CSS, como definir larguras.
Os estilos relacionados <td> e <th> substituem os estilos <col>. No CodePen, definimos o
colspan para mesclar algumas linhas da tabela, mas não todas. Se o seletor de CSS nth-child for aplicado a <tr>, dependendo da linha ou coluna mesclada, isso poderá afetar o estilo.
Infelizmente, apenas algumas propriedades são compatíveis. Os estilos não são herdados nas células, e a única maneira de segmentar células com <col> é usando um seletor complexo, como o seletor relacional :has().

Se <table> e <colgroup> tiverem uma cor de plano de fundo, o background-color de <colgroup> vai ficar na parte de cima. A ordem de desenho é:
tabela, grupos de colunas, colunas, grupos de linhas, linhas, com 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 dos elementos <colgroup> ou <col>
e não herdam o estilo deles.
Para criar listras em 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);} adiciona um preto translúcido a cada linha ímpar no corpo da tabela, permitindo que 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. São necessárias medidas extras para que o estilo de layout de tabela funcione de maneira eficaz em vários dispositivos. Se você estiver mudando a propriedade de exibição CSS para elementos de tabela, inclua atributos ARIA role. Embora isso possa parecer redundante, a propriedade CSS
display pode afetar a árvore de acessibilidade em alguns navegadores.
Apresentar dados
Os elementos de tabela têm significados semânticos usados por tecnologias assistivas para ajudar os usuários a navegar pelas linhas e colunas sem se perder. O elemento
<table> não deve ser usado para apresentação. Se você precisar de um cabeçalho acima de 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 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 Apresentações Google ou PowerPoint, provavelmente vai precisar
de uma lista de descrição.
Em resumo: 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 criar formulários, mas isso não é necessário. Você precisa saber sobre formulários HTML.
Teste seu conhecimento
Teste seus conhecimentos sobre tabelas.
Qual elemento é usado para marcar células que são cabeçalhos?
<header><caption><th>Quais informações são adequadas para um layout com uma tabela?
<dl>.<ul>.