Tabelas

  1. Estrutura básica
  2. Colspan e rowspan
  3. Col e colgroup
  4. Legendas
  5. Acessibilidade

Estrutura básica

No passado, tabelas foram muito usadas para criar layouts de páginas web, por causa da facilidade de alinhamento das suas células. Mas as tabelas só devem ter dados tabulares. Não é semântico usá-las para criar layouts.

Tabelas eram muito usadas numa época em que o CSS tinha poucos recursos. Hoje, o CSS possui várias formas nativas para definir o layout da página. Ele permite inclusive que elementos tenham o layout de tabelas e seus elementos sem que seja preciso usar elementos de tabelas. Por isso, sites com layout baseado em tabelas que estão online hoje em dia quase sempre são sites antigos que não foram atualizados.

Tabelas são criadas com o elemento <table>. Tabelas contém linhas, colunas e células. As linhas são criadas com <tr>. As células são criadas com <td>. Porém, se você quiser marcar células que pertencem ao cabeçalho da tabela, você deve marcá-las com <th> ao invés de <td>. Veja abaixo um exemplo de tabela:

<table>
  <tr>
    <th>Nome</th>
    <th>Idade</th>
    <th>Sexo</th>
  </tr>
  <tr>
    <td>Lorraine</td>
    <td>25</td>
    <td>Feminino</td>
  </tr>
  <tr>
    <td>Max</td>
    <td>19</td>
    <td>Masculino</td>
  </tr>
  <tr>
    <td>Talita</td>
    <td>22</td>
    <td>Feminino</td>
  </tr>
</table>

Veja que a tabela acima é bem simples. Ela tem quatro linhas, três colunas e doze células, três em cada linha. As células da primeira linha são marcadas com o elemento <th>, porque pertencem ao cabeçalho da tabela.

Note que o cabeçalho da tabela como um todo não foi marcado. Apenas as células de cabeçalho foram marcadas. Em casos onde todas as colunas de uma ou mais linhas representam o cabeçalho da tabela, você pode marcar o cabeçalho da tabela com o elemento <thead>. Vamos alterar a tabela anterior marcando o cabeçalho dela:

<table>
  <thead>
    <tr>
      <th>Nome</th>
      <th>Idade</th>
      <th>Sexo</th>
    </tr>
  </thead>
  <tr>
    <td>Lorraine</td>
    <td>25</td>
    <td>Feminino</td>
  </tr>
  <tr>
    <td>Max</td>
    <td>19</td>
    <td>Masculino</td>
  </tr>
  <tr>
    <td>Talita</td>
    <td>22</td>
    <td>Feminino</td>
  </tr>
</table>

Nesse caso, dá pra marcar o cabeçalho da tabela, porque ele é representado por todas as células da primeira linha, e somente por elas. Porém, há tabelas em que o cabeçalho pode ser representado de outra forma, como por exemplo, na primeira coluna e nas células da primeira linha. Veja uma tabela com dados financeiros de uma empresa, divididos pelo ano:

<table>
  <tr>
    <td></td>
    <th>2016</th>
    <th>2017</th>
    <th>2018</th>
  </tr>
  <tr>
    <th>Receitas</th>
    <td>R$ 280.000, 00</td>
    <td>R$ 230.000, 00</td>
    <td>R$ 250.000, 00</td>
  </tr>
  <tr>
    <th>Despesas</th>
    <td>R$ 210.000, 00</td>
    <td>R$ 230.000, 00</td>
    <td>R$ 190.000, 00</td>
  </tr>
  <tr>
    <th>Ganhos</th>
    <td>R$ 70.000, 00</td>
    <td>R$ 0, 00</td>
    <td>R$ 60.000, 00</td>
  </tr>
</table>

Também é possível marcar o corpo e o rodapé da tabela. O corpo pode ser marcado com o elemento <tbody>. O rodapé pode ser marcado com o elemento <tfoot>. Esses elementos não tornam a tabela mais acessível para usuários de leitores de tela. Porém, usá-los deixa a tabela mais semântica e também mais fácil de estilizar. O elemento <tbody> é adicionado de forma implícita, caso você não o adicione explicitamente. Veja a tabela dos dados das pessoas com o seu corpo marcado:

<table>
  <thead>
    <tr>
      <th>Nome</th>
      <th>Idade</th>
      <th>Sexo</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Lorraine</td>
      <td>25</td>
      <td>Feminino</td>
    </tr>
    <tr>
      <td>Max</td>
      <td>19</td>
      <td>Masculino</td>
    </tr>
    <tr>
      <td>Talita</td>
      <td>22</td>
      <td>Feminino</td>
    </tr>
  </tbody>
</table>

Colspan e rowspan

Existem casos em que uma célula deve ocupar múltiplas linhas ou múltiplas colunas. Você pode usar o atributo colspan para que uma célula ocupe múltiplas colunas e o atributo rowspan para que uma célula ocupe múltiplas linhas. Os dois atributos aceitam um valor inteiro que é o número de colunas ou linhas que a célula deve ocupar. Veja um exemplo de tabela com dados de lutadores de MMA que usa esses dois atributos:

<table>
  <tr>
    <td></td>
    <th colspan="2">Dados básicos</th>
    <th colspan="3">Cartel</th>
  </tr>
  <tr>
    <td></td>
    <th>Nome</th>
    <th>Data de nascimento</th>
    <th>Vitórias</th>
    <th>Derrotas</th>
    <th>Sem resultado</th>
  </tr>
  <tr>
    <th rowspan="2">Pesos meio-pesados</th>
    <td>Jon Jones</td>
    <td>19/07/1987</td>
    <td>23</td>
    <td>1</td>
    <td>1</td>
  </tr>
  <tr>
    <td></td>
    <td>Alexander Gustafsson</td>
    <td>15/01/1987</td>
    <td>18</td>
    <td>5</td>
    <td>0</td>
  </tr>
  <tr>
    <th rowspan="2">Pesos pesados</th>
    <td>Cain Velásquez</td>
    <td>28/07/1982</td>
    <td>14</td>
    <td>3</td>
    <td>0</td>
  </tr>
  <tr>
    <td></td>
    <td>Derrick Lewis</td>
    <td>07/02/1985</td>
    <td>21</td>
    <td>6</td>
    <td>1</td>
  </tr>
</table>

Col e colgroup

Se todas as células de uma ou mais colunas da sua tabela tem atributos em comum (atributos como class ou o style), você pode definir os atributos dessa coluna apenas uma vez usando o elemento <col>. Esse elemento é colocado dentro de um <colgroup>. Se você quiser aplicar o mesmo estilo à várias colunas, você pode usar o atributo span. Vou modificar a tabela anterior incluindo o <colgroup> para aplicar os mesmos atributos para as células das colunas dos dados básicos e do cartel.

<table>
  <colgroup>
    <col>
    <col span="2" class="dados-basicos">
    <col span="3" class="cartel">
  </colgroup>
  <tr>
    <td></td>
    <th colspan="2">Dados básicos</th>
    <th colspan="3">Cartel</th>
  </tr>
  <tr>
    <td></td>
    <th>Nome</th>
    <th>Data de nascimento</th>
    <th>Vitórias</th>
    <th>Derrotas</th>
    <th>Sem resultado</th>
  </tr>
  <tr>
    <th rowspan="2">Pesos meio-pesados</th>
    <td>Jon Jones</td>
    <td>19/07/1987</td>
    <td>23</td>
    <td>1</td>
    <td>1</td>
  </tr>
  <tr>
    <td></td>
    <td>Alexander Gustafsson</td>
    <td>15/01/1987</td>
    <td>18</td>
    <td>5</td>
    <td>0</td>
  </tr>
  <tr>
    <th rowspan="2">Pesos pesados</th>
    <td>Cain Velásquez</td>
    <td>28/07/1982</td>
    <td>14</td>
    <td>3</td>
    <td>0</td>
  </tr>
  <tr>
    <td></td>
    <td>Derrick Lewis</td>
    <td>07/02/1985</td>
    <td>21</td>
    <td>6</td>
    <td>1</td>
  </tr>
</table>

Nesse exemplo, todas as células de dados básicos terão a classe dados-basicos e todas as células de cartel terão a classe cartel. Isso poupa especificar a classe em cada célula. Eu também coloquei um <col> sem nada. Isso é porque eu precisava especificar a primeira coluna, mesmo ela não definindo nenhum atributo para as suas células.

Legendas

Tabelas podem ter legendas. Elas servem para resumir o conteúdo de uma tabela. Elas são uma boa prática de acessibilidade, pois como elas informam do que a tabela trata, os usuários de leitores de tela podem decidir se querem conhecer os dados da tabela ou não depois de ouvir o conteúdo dela.

Legendas são marcadas com o elemento <caption>. Ele deve ser a primeira coisa da tabela. Vou adicionar uma legenda à tabela dos lutadores de MMA:

<table>
  <caption>Lutadores de MMA</caption>
  <!-- ... -->
</table>

Acessibilidade

Até agora, comentei brevemente sobre algumas práticas na marcação de tabelas que são recomendadas para melhorar a acessibilidade da página. Porém, esse tópico é dedicado para falar de algumas boas práticas de acessibilidade que ainda não foram citadas.

Há pessoas que marcam células de cabeçalho com o elemento <td>. Além dessa não ser uma boa escolha por motivos semânticos, ela é uma má escolha também por causa da acessibilidade. O elemento <th> permite que o leitor de tela reconheça bem melhor a estrutura da tabela, permitindo que o usuário entenda melhor a estrutura da tabela. Portanto, sempre marque células de cabeçalho com <th>.

Além de usar o elemento <th>, podemos usar o atributo scope nesse elemento. Ele é usado em células de cabeçalho e serve para informar se o cabeçalho se refere a uma linha (valor row), a uma coluna (valor col), a um grupo de linhas (valor rowgroup) ou a um grupo de colunas (valor colgroup). Veja como ficaria a tabela dos lutadores de MMA com o atributo scope:

<table>
  <tr>
    <td></td>
    <th colspan="2" scope="colgroup">Dados básicos</th>
    <th colspan="3" scope="colgroup">Cartel</th>
  </tr>
  <tr>
    <td></td>
    <th scope="col">Nome</th>
    <th scope="col">Data de nascimento</th>
    <th scope="col">Vitórias</th>
    <th scope="col">Derrotas</th>
    <th scope="col">Sem resultado</th>
  </tr>
  <tr>
    <th rowspan="2" scope="rowgroup">Pesos meio-pesados</th>
    <td>Jon Jones</td>
    <td>19/07/1987</td>
    <td>22</td>
    <td>1</td>
    <td>1</td>
  </tr>
  <tr>
    <td></td>
    <td>Alexander Gustafsson</td>
    <td>15/01/1987</td>
    <td>18</td>
    <td>4</td>
    <td>0</td>
  </tr>
  <tr>
    <th rowspan="2" scope="rowgroup">Pesos pesados</th>
    <td>Cain Velásquez</td>
    <td>28/07/1982</td>
    <td>13</td>
    <td>2</td>
    <td>0</td>
  </tr>
  <tr>
    <td></td>
    <td>Derrick Lewis</td>
    <td>07/02/1985</td>
    <td>18</td>
    <td>5</td>
    <td>1</td>
  </tr>
</table>