Как правильно верстать HTML-таблицы
Учимся верстать таблицы так, чтобы их верно понимали браузеры, поисковики и люди с ограниченными возможностями.
: colette / respawn entertainment, oculus
Практика показывает, что большинство разработчиков верстают таблицы HTML неверно — используют только теги строк и ячеек (<tr>, <td>).
Из этой статьи вы узнаете, как верстать таблицы с учётом не только синтаксиса, но и семантики — то есть обозначать нужные части таблицы тегами, которые отражают их содержание.
Знакомство с семантической вёрсткой
Семантический подход к вёрстке подразумевает использование HTML-тегов в соответствии с их семантикой (предназначением), а его суть заключается в верности выбора тегов и их взаимного расположения.
Семантические теги передают смысл (или обозначают важность) содержащегося в них контента.
Семантический подход — противоположность визуальному, при котором важно только то, как HTML-страница выглядит.
Почему семантика так важна
Она повышает доступность контента. Тогда его лучше понимают:
- поисковые роботы (чем понятнее для них контент сайта, тем корректнее он представлен в поисковой выдаче и тем проще его найти пользователям);
- браузеры и помощники для пользователей с ограниченными возможностями (например, программы, которые читают информацию с экрана, — скринридеры).
Семантически верно размеченный контент может выглядеть абсолютно так же, как и свёрстанный без учёта семантики. Это касается любых элементов на HTML-странице.
Так, можно использовать для всех них тег <div>, но он не обладает семантикой, никак не обозначает смысл своего содержимого. Поэтому мы применяем для заголовков теги H1… H6, для таблицы — <table>, <caption>, <thead>, <tbody>, <tfoot>, <th>. И так далее.
Для оформления страниц при семантической вёрстке применяют каскадные таблицы стилей (CSS).
Рассмотрим, какие теги отвечают за вёрстку таблиц, когда и зачем нужен каждый.
Строки и ячейки таблицы
Каждая таблица состоит из строк и ячеек, а задаётся тегом <table> — это контейнер для остальных тегов таблицы.
Тег <tr> образует контейнер для создания строки таблицы. Каждая ячейка в такой строке устанавливается с помощью тега <td> (хотя первая может быть задана и тегом <th>).
Важно понимать. Дочерними элементами строки могут быть только ячейки <td> (и заголовочная ячейка <th>). А сама строка <tr> дочерним элементом ячейки быть не может. Это ограничивает возможную вложенность тегов.
Рассмотрим пример:
Мы видим три строки (элементы <tr>). В каждой из строк по три ячейки (<td>). Представим это HTML-кодом:
Объединение ячеек
Ячейки можно объединять (растягивать по горизонтали и вертикали) с помощью специальных атрибутов. При этом поглощаемые ячейки задавать своими тегами уже не придётся.
Столбцы таблицы объединяются атрибутом colspan, а строки — атрибутом rowspan.
И тут важно не запутаться:
Атрибут colspan тегов <td> и <th> объединяет ячейки по горизонтали (то есть ячейки одной строки). Значение colspan указывает, сколько столбцов пересекает ячейка.
Атрибут rowspan тегов <td> и <th> объединяет ячейки по вертикали (то есть ячейки разных строк). Значение rowspan задаёт, через сколько строк проходит ячейка.
Рассмотрим пару примеров:
1 | 2 | |
---|---|---|
1 | 2 | |
1 | 2 | 3 |
1 | 2 |
Вторая ячейка первой строки пересекает два столбца. То есть она растянулась по горизонтали и приняла в себя третью ячейку первой строки. Третья ячейка второй строки пересекает две строки, то есть растянулась по вертикали, заняв и третью ячейку третьей строки.
Поэтому третьи ячейки для первой и третьей строк задавать не нужно. Они уже поглощены другими. Теперь к коду:
Ещё один пример:
1 | 2 | 3 |
---|---|---|
1 | 2 | 3 |
1 | 2 | |
1 |
Как такое сверстать:
Здесь вторая ячейка второй строки занимает два столбца и две строки. Обратите внимание, что во второй строке нет третьей ячейки и в третьей строке нет второй и третьей ячеек. Теперь места этих ячеек занимает вторая ячейка второй строки.
Заголовок таблицы <caption>
Этот тег следует включать в любую таблицу. Где бы вы его ни разместили, его содержимое будет выведено перед таблицей. Изменить это можно с помощью свойства caption-side (значение top — для вывода до таблицы, и bottom — после).
Для единообразия и доступности тег заголовка размещают в самом начале — сразу после тега <table>.
Тег <caption> по умолчанию выравнивает своё содержимое по центру. Чтобы установить выравнивание по левому или правому краю, достаточно поменять значение свойства text-align.
Зачем нужен заголовок?
- Чтобы пользователям было проще ориентироваться на странице — например, когда таблиц много.
- Тег <caption> помогает людям с ограниченными возможностями. По заголовку они получают краткое представление о содержимом таблицы и решают, полезна ли она для них и стоит ли читать её целиком.
- Этот тег влияет на оптимизацию, его любят поисковики.
Примечание. Если дизайнер не предусмотрел заголовок таблицы, то хороший разработчик придумает его, добавит в разметку и скроет через CSS. Это повысит доступность контента.
Даже скрытый заголовок всё равно доступен при навигации по странице с помощью клавиатуры. И речевой браузер для людей с ограниченными возможностями тоже понимает тег <caption> — читая текст в этом теге, он меняет интонацию, темп речи, повышает громкость голоса и тому подобное.
Структура таблиц
Структура таблиц очень похожа на структуру HTML-страницы. Только для страницы мы используем теги <header>, <main> и <footer>, а для таблицы — <thead>, <tbody> и <tfoot>.
Согласно стандарту HTML5, в таблице может быть только по одной секции thead и tfoot, а вот tbody — несколько.
Эти элементы полезны не только для доступности, но и для стилизации (как логичные точки добавления CSS к таблице).
Шапка таблицы <thead>
Этим тегом задают заголовочную секцию таблицы. Чаще всего речь идёт о первой строке — содержащей заголовки столбцов.
Браузер и поисковики считают эту часть заголовочным колонтитулом таблицы. Например, при печати колонтитулы таблицы будут на каждой напечатанной странице — и благодаря такой шапке вы не забудете, что значат данные каждого столбца.
В <thead> для ячеек используют тег <th>. Контент в ячейке th браузер выравнивает по центру, а текст к тому же отображает жирным шрифтом.
Например:
Сaption
th | th | |||
---|---|---|---|---|
td | td | td | td | td |
td | td | td | td | td |
Из примера видно, что первая строка объединяет две ячейки <th>. Первая ячейка первой строки — это заголовок для других ячеек первого столбца, а вторая ячейка первой строки — это заголовок четырёх оставшихся столбцов.
Заголовки столбцов и строк. Тег <th>
Тег <th> задаёт особые ячейки, с которых начинаются строки или столбцы. В такой ячейке обычно хранится атрибут для всех данных строки или столбца.
Как мы и говорили выше, к содержимому таких ячеек применяется определённый стиль: по умолчанию это выделение жирным шрифтом и выравнивание по центру ячейки.
Благодаря заголовочным ячейкам таблица выглядит лучше, а искать данные в ней становится проще.
Важно. Не применяйте <th> для визуального форматирования — только для выделения ячейки-заголовка. Этот принцип касается всех элементов разметки, которые обладают семантикой.
Тег <th> даёт ещё одно преимущество: вместе с атрибутом scope он связывает каждый заголовок со всеми данными строки или столбца. То есть добавляет к интуитивной, визуально считываемой связи такую, которую понимают и программы.
К тегу <th> и атрибуту scope мы вернёмся ближе к концу статьи, где подробнее поговорим о доступности таблиц для пользователей с ограниченными возможностями.
Тело таблицы <tbody>
Секция <tbody> содержит основную часть информации и группирует главные части таблицы. То есть можно использовать <tbody> сколько угодно раз, чтобы разбивать основной контент таблицы на части, данные которых связаны общей логикой.
Тег <tbody> семантически важен: браузер, поисковые роботы и помощники для людей с ограниченными возможностями благодаря ему понимают, где находится основное содержимое таблицы.
Тело таблицы располагается после заголовка <caption> и шапки <thead>.
Пример:
Месяц | Дни недели | Оплата(тыс. р.) |
---|---|---|
Январь | Понедельник | 50 |
Вторник | 40 | |
Среда | 35 | |
Четверг | 40 | |
Пятница | 15 | |
Суббота | 60 | |
Воскресенье | 30 | |
Февраль | Понедельник | 20 |
Вторник | 25 | |
Среда | 15 | |
Четверг | 70 | |
Пятница | 77 | |
Суббота | 63 | |
Воскресенье | 30 |
Здесь нет заголовка <caption>, поэтому нужно его придумать и скрыть с помощью CSS (для доступности веб-содержимого).
Данные основной части таблицы надо сгруппировать по смыслу. У нас сначала идёт январь, затем февраль. Значит, для данных каждого месяца логично использовать свой <tbody>:
- в первом <tbody> будут январские строки;
- во втором <tbody> — февральские.
Подвал таблицы <tfoot>
Секция <tfoot> используется для группировки содержимого нижней части таблицы.
Семантически это итог таблицы (например, результат подсчёта сумм по столбцам).
А ещё это нижний колонтитул таблицы, браузер выводит его после <tbody>, а при печати таблицы содержимое <tfoot> может быть как на каждой напечатанной странице, так и только на последней (это зависит от браузера).
Важно. Чтобы предотвратить проблемы с доступностью (клавиатурная навигация и специальные возможности), размещать <tfoot> следует после <tbody>.
Для ячеек в секции <tfoot> следует использовать тег <td>.
Пример:
Таблица чисел
Нечётное | Чётное |
---|---|
1 | 2 |
3 | 4 |
5 | 6 |
Вы узнали, что такое чётные и нечётные числа |
Последняя строка нашего примера — это по смыслу итог таблицы. Поэтому её вполне уместно обернуть тегом <tfoot>, превратив в нижний колонтитул.
Важно помнить!
Теги <thead> и <tfoot> нужны не всегда. Бывают таблицы без шапки и подвала.
Если нет смысла группировать основную часть таблицы, то можно обойтись и без тега <tbody>, но мы рекомендуем не делать так. Тег даёт больше контроля над структурой таблицы и стилизацией, а также приучает действовать последовательно.
К тому же браузер всё равно подставит этот тег сам, а всегда полагаться на браузеры — значит оставить место для возможных ошибок.
Пример:
1 | Мавзалеев И. В. | 10.09.1992 |
2 | Киреева А. Ю. | 02.05.1996 |
3 | Корнеев И. Ю. | 09.10.1990 |
4 | Тресков В. А. | 25.03.1993 |
5 | Ибрагимов А. Е. | 15.10.1994 |
6 | Борисенко Д. С. | 10.10.1991 |
В таблице выше шесть строк, каждая из которых содержит три ячейки. Здесь нет важных для смысла признаков, по которым можно сгруппировать содержимое таблицы. Поэтому будет достаточно тега <caption> (придумаем его и скроем) и тега <tbody>, а вот теги <thead> и <tfoot> можно опустить.
Теги <col> и <colgroup>
C помощью тега <col> удобно стилизовать столбцы таблицы через CSS (не приходится писать классы для каждой ячейки в разных строках). Это крутая фишка для любого разработчика.
Как это работает:
Caption
th | th | |
---|---|---|
1 | 2 | 3 |
1 | 2 | 3 |
1 | 2 | 3 |
У нас три ячейки и, следовательно, три столбца. Поэтому мы используем три тега <col>.
Для группировки тегов <col> применяют специальный тег <colgroup>:
<colgroup> позволяет задать стиль сразу для группы столбцов, а тег <col> внутри <colgroup> — переопределить его для отдельных столбцов в группе.
Располагать теги <colgroup>, <col> нужно перед тегами <thead>, <tbody>, <tfoot>, а если у таблицы есть тег <caption>, то после него.
Атрибут span
У тега <col> есть атрибут span, который распространяет стиль на несколько столбцов.
Например:
Caption
th | th | th | th |
---|---|---|---|
1 | 2 | 3 | 4 |
Первый тег <col> — это первый столбец, а второй тег <col> — второй, но из-за атрибута span, в котором мы указали значение "2", его стиль распространяется и на третий.
Это удобно, когда нужно одинаково стилизовать несколько столбцов. Например, чтобы не создавать много тегов <col> с одними и теми же классами, мы используем атрибут span. Этот атрибут работает и для тега <colgroup>.
Атрибут scope тега <th>
Когда таблица хорошо структурирована, достаточно беглого взгляда, чтобы понять, какие где данные: мигом возникают визуальные ассоциации между основной информацией в таблице и заголовками её колонок и/или строк.
Но что, если наши пользователи не могут провести такую визуальную параллель. Например, они слабовидящие. Как им прочитать сложную таблицу?
Люди с ослабленным зрением часто применяют скринридеры — программы, которые читают для них веб-страницы. С обычным текстом скринридер справляется хорошо, но интерпретировать сложную таблицу для него проблема.
Поэтому разработчики должны позаботиться об этом и дополнить визуальные ассоциации в таблице программными, которые скринридер сможет понять.
Чаще всего это делают с помощью тега <th> и атрибута scope, который сообщает скринридеру, какие ячейки точно являются заголовками — например, заголовок строки, в которой программа находится, или же заголовок столбца.
Благодаря им все пользователи могут интерпретировать таблицу так же, как и зрячие люди.
Пример
Вернёмся к нашей таблице чётности чисел:
Таблица чисел
Нечётное | Чётное |
---|---|
1 | 2 |
3 | 4 |
5 | 6 |
Вы узнали, что такое чётные и нечётные числа |
Чтобы однозначно указать заголовки столбцов, делаем вот так:
И у каждой строки тоже можно определить заголовок (если в таблице есть не только заголовки столбцов). Слегка изменим для этого наш пример:
Таблица чисел
Пара № | Нечётное | Чётное |
---|---|---|
1 | 1 | 2 |
2 | 3 | 4 |
3 | 5 | 6 |
Вы узнали, что такое чётные и нечётные числа |
И снова к HTML:
Скринридер распознаёт такую семантическую разметку и позволяет пользователям прочесть весь столбец или строку целиком.
У атрибута scope есть ещё два значения — colgroup и rowgroup. Они используются для таблиц с двумя и более уровнями заголовков (заголовки, которые группируют подзаголовки).
Так заголовок верхнего уровня получает scope="colgroup", а у его подзаголовков scope="col", и аналогично для строк.
Подытожим
- Таблица состоит из строк <tr> и ячеек (<td> и <th>). Дочерними элементами строки <tr> могут быть только ячейки, но не наоборот.
- Таблице нужен заголовок <caption>. Он увеличивает доступность веб-содержимого. Если дизайнер не учёл этого, верстальщик сам придумывает заголовок и скрывает его с помощью CSS.
- За логическое структурирование таблицы, помимо заголовка <caption>, отвечают теги <thead>, <tbody> и <tfoot>. Также они полезны при стилизации секций таблицы.
- Внутри <thead> ячееки задают тегом <th> (он семантический), внутри <tfoot> — <td>, а внутри <tbody> допустимы оба.
- Для стилизации столбцов в таблице применяют тег <col>.
Заботьтесь обо всех пользователях — верстайте таблицы семантически верно.