Код
#Руководства

Как правильно верстать HTML-таблицы

Учимся верстать таблицы так, чтобы их верно понимали браузеры, поисковики и люди с ограниченными возможностями.

: colette / respawn entertainment, oculus

Практика показывает, что большинство разработчиков верстают таблицы HTML неверно — используют только теги строк и ячеек (<tr>, <td>).

Из этой статьи вы узнаете, как верстать таблицы с учётом не только синтаксиса, но и семантики — то есть обозначать нужные части таблицы тегами, которые отражают их содержание.

Знакомство с семантической вёрсткой

Семантический подход к вёрстке подразумевает использование HTML-тегов в соответствии с их семантикой (предназначением), а его суть заключается в верности выбора тегов и их взаимного расположения.

Семантические теги передают смысл (или обозначают важность) содержащегося в них контента.

Семантический подход — противоположность визуальному, при котором важно только то, как HTML-страница выглядит.

Почему семантика так важна

Она повышает доступность контента. Тогда его лучше понимают:

  • поисковые роботы (чем понятнее для них контент сайта, тем корректнее он представлен в поисковой выдаче и тем проще его найти пользователям);
  • браузеры и помощники для пользователей с ограниченными возможностями (например, программы, которые читают информацию с экрана, — скринридеры).

Семантически верно размеченный контент может выглядеть абсолютно так же, как и свёрстанный без учёта семантики. Это касается любых элементов на HTML-странице.

Так, можно использовать для всех них тег <div>, но он не обладает семантикой, никак не обозначает смысл своего содержимого. Поэтому мы применяем для заголовков теги H1H6, для таблицы — <table>, <caption>, <thead>, <tbody>, <tfoot>, <th>. И так далее.

Для оформления страниц при семантической вёрстке применяют каскадные таблицы стилей (CSS).

Рассмотрим, какие теги отвечают за вёрстку таблиц, когда и зачем нужен каждый.

Строки и ячейки таблицы

Каждая таблица состоит из строк и ячеек, а задаётся тегом <table> — это контейнер для остальных тегов таблицы.

Тег <tr> образует контейнер для создания строки таблицы. Каждая ячейка в такой строке устанавливается с помощью тега <td> (хотя первая может быть задана и тегом <th>).

Важно понимать. Дочерними элементами строки могут быть только ячейки <td> (и заголовочная ячейка <th>). А сама строка <tr> дочерним элементом ячейки быть не может. Это ограничивает возможную вложенность тегов.

Рассмотрим пример:

Мы видим три строки (элементы <tr>). В каждой из строк по три ячейки (<td>). Представим это HTML-кодом:

 <table>
        <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
    </table>

Объединение ячеек

Ячейки можно объединять (растягивать по горизонтали и вертикали) с помощью специальных атрибутов. При этом поглощаемые ячейки задавать своими тегами уже не придётся.

Столбцы таблицы объединяются атрибутом colspan, а строки — атрибутом rowspan.

И тут важно не запутаться:

Атрибут colspan тегов <td> и <th> объединяет ячейки по горизонтали (то есть ячейки одной строки). Значение colspan указывает, сколько столбцов пересекает ячейка.

Атрибут rowspan тегов <td> и <th> объединяет ячейки по вертикали (то есть ячейки разных строк). Значение rowspan задаёт, через сколько строк проходит ячейка.

Рассмотрим пару примеров:

12
12
123
12

Вторая ячейка первой строки пересекает два столбца. То есть она растянулась по горизонтали и приняла в себя третью ячейку первой строки. Третья ячейка второй строки пересекает две строки, то есть растянулась по вертикали, заняв и третью ячейку третьей строки.

Поэтому третьи ячейки для первой и третьей строк задавать не нужно. Они уже поглощены другими. Теперь к коду:

  <table>
        <tr>
            <td>1</td>
            <td colspan="2">2</td>
        </tr>
        <tr>
            <td>1</td>
            <td>2</td>
            <td rowspan="2">3</td>
        </tr>
        <tr>
            <td>1</td>
            <td>2</td>
        </tr>
    </table>

Ещё один пример:

123
123
12
1

Как такое сверстать:

  <table>
        <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr>
            <td>1</td>
            <td colspan="2" rowspan="2">2</td>
        </tr>
        <tr>
            <td>1</td>
        </tr>
    </table>

Здесь вторая ячейка второй строки занимает два столбца и две строки. Обратите внимание, что во второй строке нет третьей ячейки и в третьей строке нет второй и третьей ячеек. Теперь места этих ячеек занимает вторая ячейка второй строки.

Заголовок таблицы <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

thth
tdtdtdtdtd
tdtdtdtdtd
 <table>
        <caption>Caption</caption>
        <thead>
            <tr>
                <th>th</th>
                <th colspan="4">th</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>td</td>
                <td>td</td>
                <td>td</td>
                <td>td</td>
                <td>td</td>
            </tr>
            <tr>
                <td>td</td>
                <td>td</td>
                <td>td</td>
                <td>td</td>
                <td>td</td>
            </tr>        
        </tbody>
    </table>

Из примера видно, что первая строка объединяет две ячейки <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>.

Пример:

Таблица чисел

НечётноеЧётное
12
34
56
Вы узнали, что такое чётные и нечётные числа
<table>
        <caption>Таблицa чисел</caption>
        <thead>
            <tr>
                <th>Нечётное</th>
                <th>Чётное</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>2</td>
            </tr>
            <tr>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>5</td>
                <td>6</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="2">
                   Вы узнали, что такое чётные и нечётные числа
                </td>
            </tr>
        </tfoot>
    </table>

Последняя строка нашего примера — это по смыслу итог таблицы. Поэтому её вполне уместно обернуть тегом <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

thth
123
123
123
  <table class="table">
        <caption>Caption</caption>
 
        <col class="col-first">
        <col>
        <col>
 
        <thead>
            <tr>
                <th>th</th>
                <th colspan="2">th</th>
            </tr>
        </thead>
        
        <tbody>
  
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
            </tr>
        </tbody>
    </table>

У нас три ячейки и, следовательно, три столбца. Поэтому мы используем три тега <col>.

Для группировки тегов <col> применяют специальный тег <colgroup>:

<colgroup>
        <col class="col-first">
        <col>
        <col>
</colgroup>

<colgroup> позволяет задать стиль сразу для группы столбцов, а тег <col> внутри <colgroup> — переопределить его для отдельных столбцов в группе.

Располагать теги <colgroup>, <col> нужно перед тегами <thead>, <tbody>, <tfoot>, а если у таблицы есть тег <caption>, то после него.

Атрибут span

У тега <col> есть атрибут span, который распространяет стиль на несколько столбцов.

Например:

Caption

thththth
1234
<table class="table">
        <caption>Caption</caption>
 
        <colgroup>
            <col>
            <col span="2" class="col-second">
            <col>
        </colgroup>
 
        <thead>
            <tr>
                <th>th</th>
                <th>th</th>
                <th>th</th>
                <th>th</th>
            </tr>
        </thead>
 
        <tbody>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
        </tbody>
    </table>

Первый тег <col> — это первый столбец, а второй тег <col> — второй, но из-за атрибута span, в котором мы указали значение "2", его стиль распространяется и на третий.

Это удобно, когда нужно одинаково стилизовать несколько столбцов. Например, чтобы не создавать много тегов <col> с одними и теми же классами, мы используем атрибут span. Этот атрибут работает и для тега <colgroup>.

Атрибут scope тега <th>

Когда таблица хорошо структурирована, достаточно беглого взгляда, чтобы понять, какие где данные: мигом возникают визуальные ассоциации между основной информацией в таблице и заголовками её колонок и/или строк.

Но что, если наши пользователи не могут провести такую визуальную параллель. Например, они слабовидящие. Как им прочитать сложную таблицу?

Люди с ослабленным зрением часто применяют скринридеры — программы, которые читают для них веб-страницы. С обычным текстом скринридер справляется хорошо, но интерпретировать сложную таблицу для него проблема.

Поэтому разработчики должны позаботиться об этом и дополнить визуальные ассоциации в таблице программными, которые скринридер сможет понять.

Чаще всего это делают с помощью тега <th> и атрибута scope, который сообщает скринридеру, какие ячейки точно являются заголовками — например, заголовок строки, в которой программа находится, или же заголовок столбца.

Благодаря им все пользователи могут интерпретировать таблицу так же, как и зрячие люди.

Пример

Вернёмся к нашей таблице чётности чисел:

Таблица чисел

НечётноеЧётное
12
34
56
Вы узнали, что такое чётные и нечётные числа

Чтобы однозначно указать заголовки столбцов, делаем вот так:

<table>
        <caption>Таблицa чисел</caption>
        <thead>
            <tr>
                <th scope="col">Нечётное</th>
                <th scope="col">Чётное</th>
            </tr>
        </thead>
        <tbody>
            <!--HTML-код-->
        </tbody>
        <tfoot>
            <!--HTML-код-->
        </tfoot>
    </table>

И у каждой строки тоже можно определить заголовок (если в таблице есть не только заголовки столбцов). Слегка изменим для этого наш пример:

Таблица чисел

Пара №НечётноеЧётное
112
234
356
Вы узнали, что такое чётные и нечётные числа

И снова к HTML:

<table>
        <caption>Таблицa чисел</caption>
        <thead>
            <tr>
                <th scope="col">Пара №</th>
                <th scope="col">Нечётное</th>
                <th scope="col">Чётное</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th scope="row">1</th>
                <td>1</td>
                <td>2</td>
            </tr>
            <tr>
                <th scope="row">2</th>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <th scope="row">3</th>
                <td>5</td>
                <td>6</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="3">
                   Вы узнали, что такое чётные и нечётные числа
                </td>
            </tr>
        </tfoot>
    </table>

Скринридер распознаёт такую семантическую разметку и позволяет пользователям прочесть весь столбец или строку целиком.

У атрибута scope есть ещё два значения — colgroup и rowgroup. Они используются для таблиц с двумя и более уровнями заголовков (заголовки, которые группируют подзаголовки).

Так заголовок верхнего уровня получает scope="colgroup", а у его подзаголовков scope="col", и аналогично для строк.

Подытожим

  • Таблица состоит из строк <tr> и ячеек (<td> и <th>). Дочерними элементами строки <tr> могут быть только ячейки, но не наоборот.
  • Таблице нужен заголовок <caption>. Он увеличивает доступность веб-содержимого. Если дизайнер не учёл этого, верстальщик сам придумывает заголовок и скрывает его с помощью CSS.
  • За логическое структурирование таблицы, помимо заголовка <caption>, отвечают теги <thead>, <tbody> и <tfoot>. Также они полезны при стилизации секций таблицы.
  • Внутри <thead> ячееки задают тегом <th> (он семантический), внутри <tfoot> — <td>, а внутри <tbody> допустимы оба.
  • Для стилизации столбцов в таблице применяют тег <col>.

Заботьтесь обо всех пользователях — верстайте таблицы семантически верно.

Изучайте IT на практике — бесплатно

Курсы за 2990 0 р.

Я не знаю, с чего начать
Освойте топовые нейросети за три дня. Бесплатно
Знакомимся с ChatGPT-4, DALLE-3, Midjourney, Stable Diffusion, Gen-2 и нейросетями для создания музыки. Практика в реальном времени. Подробности — по клику.
Узнать больше
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована