Таблица в HTML: теги table, tr, td и th, объединение ячеек

Таблицу в HTML собирают из тега table, строк tr и ячеек td, а заголовки столбцов делают через th.

Разбираем все теги таблицы с примерами кода, объединение ячеек через colspan и rowspan, оформление в CSS и ошибки, которые находит валидатор W3C.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 2837 статей автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3491 экспертное мнение Подписаться на Телеграм-канал
Обложка: Таблица в HTML: теги table, tr, td и th, объединение ячеек

Таблицу в HTML собирают из трёх тегов: контейнер <table>, строки <tr> и ячейки <td>. Для ячеек-заголовков вместо <td> ставят <th>. Таблица строится по строкам: сначала открываете строку, потом перечисляете её ячейки слева направо.

<table>
  <tr>
    <th>Модуль</th>
    <th>Уроков</th>
  </tr>
  <tr>
    <td>HTML</td>
    <td>8</td>
  </tr>
</table>

Названия тегов пришли из английского: tr означает table row, то есть строка таблицы, td расшифровывается как table data (ячейка с данными), th как table header (ячейка-заголовок). Если вы только начинаете, сначала прочитайте, что такое HTML и как устроены теги.

Ниже разбираем все теги таблицы, объединение ячеек через colspan и rowspan, оформление в CSS и ошибки, на которых спотыкаются новички. Каждый пример мы открыли в Chrome и прогнали через валидатор W3C. Вёрстку с проверкой домашних заданий преподавателем дают курсы из каталога по HTML.

CheckroiCheckroiПодборка курсов по HTML209 курсов • 43 школыСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Как сделать таблицу в HTML: пошагово

Рой собирает таблицу из строк и ячеек в редакторе кода

Порядок одинаковый для таблицы любого размера.

  1. Откройте контейнер <table>.
  2. Если у таблицы есть название, сразу после <table> поставьте <caption>.
  3. Первую строку с названиями столбцов оберните в <thead>, а её ячейки сделайте через <th>.
  4. Строки с данными положите в <tbody>. Каждая строка начинается с <tr>, внутри идут ячейки <td>.
  5. Проверьте, что в каждой строке одинаковое число ячеек.
  6. Закройте </table> и задайте рамки и отступы в CSS.

Вот таблица по этим шагам: учебный план из трёх модулей с итогом в подвале.

<table>
  <caption>Учебный план курса</caption>
  <thead>
    <tr><th>Модуль</th><th>Тема</th><th>Уроков</th></tr>
  </thead>
  <tbody>
    <tr><td>1</td><td>HTML</td><td>8</td></tr>
    <tr><td>2</td><td>CSS</td><td>12</td></tr>
    <tr><td>3</td><td>JavaScript</td><td>15</td></tr>
  </tbody>
  <tfoot>
    <tr><td colspan="2">Всего</td><td>35</td></tr>
  </tfoot>
</table>

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

%

Таблица учебного плана в HTML без CSS в браузере Chrome: подпись, шапка, три строки и итог
Так Chrome показывает таблицу учебного плана без CSS. Рамок нет, заголовки в th жирные и стоят по центру, подпись caption над таблицей

%

Теги таблицы HTML и за что они отвечают

Обязательных тегов три: <table>, <tr> и <td>. Остальные описывают смысл частей таблицы, и без них её хуже понимают поисковики и программы экранного доступа.

Тег Что делает Где стоит
<table> создаёт таблицу внешний контейнер
<caption> подпись (название) таблицы первым внутри table
<colgroup>, <col> описывают столбцы, чтобы задать им ширину или фон после caption, до строк
<thead> шапка, строки с названиями столбцов до tbody
<tbody> тело таблицы с данными после thead, групп может быть несколько
<tfoot> подвал: итоги, примечания последним, после tbody
<tr> строка внутри thead, tbody, tfoot или прямо в table
<th> ячейка-заголовок внутри tr
<td> обычная ячейка с данными внутри tr

Порядок частей задан в спецификации HTML жёстко: caption, затем colgroup, thead, tbody или строки, и в самом конце tfoot. Отдельного тега для столбца с ячейками в HTML нет: столбец складывается из ячеек с одинаковым номером в разных строках.

Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

Тег tr: строка таблицы

Строку таблицы задаёт тег <tr>. Внутри него разрешены только ячейки <td> и <th>, а ещё теги скриптов вроде <script> и <template>. Текст, картинку или ссылку кладут внутрь ячейки, а не прямо в строку.

В ячейке может стоять любая разметка: несколько абзацев, список, кнопка. Как устроены абзацы, мы разбирали в статье про тег p в HTML, а маркированные и нумерованные перечни в разборе тегов ul, ol и li.

Строку можно поставить прямо в <table>, без <tbody>. Мы проверили это в Chrome: браузер сам дописывает tbody вокруг таких строк. Это видно в инструментах разработчика, и это важно для CSS:

<!-- в коде -->
<table><tr><td>1</td></tr></table>

<!-- в DOM после загрузки -->
<table><tbody><tr><td>1</td></tr></tbody></table>

Отсюда частая загадка: селектор table > tr в CSS ничего не находит, хотя строки на месте. Между ними теперь стоит tbody, поэтому пишите table tr или tbody > tr.

У самого tr атрибутов почти нет. Старые align, valign, bgcolor и height браузеры пока понимают, но спецификация относит их к устаревшим, а валидатор на каждый выдаёт ошибку «… is obsolete. Use CSS instead». Цвет строки, высоту и выравнивание задают стилями.

Ячейки td и th: в чём разница

Обе создают ячейку, разница в смысле. <td> хранит данные, <th> подписывает столбец или строку. Программа экранного доступа зачитывает слепому пользователю заголовок перед значением ячейки. Без th она прочитает «35» и не скажет, что это число уроков.

Внешне браузер тоже их различает. Мы замерили стили по умолчанию в Chrome:

  • в <th> текст жирный и выровнен по центру;
  • в <td> текст обычный и прижат к левому краю;
  • у обеих ячеек внутренний отступ 1 px, между ячейками промежуток 2 px.

Эти значения прописаны в таблице стилей браузера из спецификации, поэтому в Firefox и Safari картина та же.

Когда заголовки стоят и сверху, и в первом столбце, добавьте th атрибут scope. Значение col относит заголовок к столбцу, row к строке. Так советует и руководство W3C по доступным таблицам.

<tr>
  <th scope="row">Понедельник</th>
  <td>HTML</td>
  <td>CSS</td>
</tr>

Шапка, тело и подвал: thead, tbody, tfoot и caption

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

  • Стили. Шапку красят селектором thead th, и стиль не цепляет строки с данными.
  • Печать. Если длинная таблица уходит на несколько страниц, браузер повторяет thead вверху каждой страницы. Мы распечатали в PDF таблицу на 150 строк из Chrome: шапка стояла на всех четырёх листах.
  • Скрипты. Новые строки добавляют в tbody, и шапка с итогом остаются на своих местах.

С tfoot связана ловушка из старых учебников. По правилам HTML 4 подвал писали до tbody, и в части статей так до сих пор и учат. Мы проверили такой порядок на валидаторе W3C: сейчас это ошибка «Element tbody not allowed as child of element table in this context». Подвал ставят последним, после tbody.

Подпись <caption> браузер выводит над таблицей по центру. Её место первым тегом внутри table: caption после строк валидатор тоже считает ошибкой.

Как объединить ячейки: colspan и rowspan

Сетка таблицы, где одна ячейка растянута на два ряда, а другая на три столбца

Ячейки в HTML объединяют двумя атрибутами, которые ставят td или th.

  • colspan="N" растягивает ячейку вправо на N столбцов.
  • rowspan="N" растягивает ячейку вниз на N строк.

В текстовых редакторах ячейки объединяют кнопкой на панели, и таблица сама пересчитывает сетку. Если нужна таблица в документе, а не на сайте, смотрите наш разбор, как выровнять таблицу в Word. В HTML сетку пересчитываете вы.

Главное правило: ячейки, которые закрыла объединённая, в коде не пишут. Если ячейка в первой строке растянута на две строки вниз, во второй строке этого столбца уже занято, и ячеек там на одну меньше.

Пример ниже расписание на неделю. Практикум по HTML в понедельник занимает два занятия подряд, поэтому у него rowspan="2". Разбор домашних заданий идёт сразу во все три дня, у него colspan="3".

<table>
  <caption>Расписание на неделю</caption>
  <thead>
    <tr>
      <th>Время</th><th>Понедельник</th><th>Вторник</th><th>Среда</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">10:00</th>
      <td rowspan="2">Практикум по HTML</td>
      <td>CSS</td><td>JavaScript</td>
    </tr>
    <tr>
      <th scope="row">12:00</th>
      <td>Вёрстка макета</td><td>Git</td>
    </tr>
    <tr>
      <th scope="row">14:00</th>
      <td colspan="3">Разбор домашних заданий</td>
    </tr>
  </tbody>
</table>

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

%

Расписание на неделю в HTML-таблице с объединёнными ячейками: rowspan на две строки и colspan на три столбца
Практикум по HTML растянут на два занятия через rowspan, разбор домашних заданий занимает три дня через colspan. Рамки добавлены через CSS, иначе объединение не видно

%

Есть и пределы. По спецификации colspan может быть от 1 до 1000, rowspan до 65 534. Мы задали в Chrome colspan="5000", и браузер молча урезал его до 1000. Значение rowspan="0" растягивает ячейку до конца своей группы строк, то есть до конца tbody.

Проверка перед сохранением: сложите в каждой строке ячейки с учётом colspan и тех, что сверху закрыл rowspan. Сумма в каждой строке должна совпасть с числом столбцов в шапке.

Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

Как оформить таблицу через CSS

Рамки, отступы и цвета задают в CSS. Атрибут border="1" у table из старых примеров ещё работает, но валидатор помечает его как устаревший, а линии выходят объёмными, как в девяностые.

Минимальный набор, после которого таблица выглядит аккуратно:

table {
  border-collapse: collapse;   /* одна линия между ячейками вместо двойной */
  width: 100%;
}
th, td {
  border: 1px solid #d0d7de;
  padding: 8px 12px;
  text-align: left;
}
thead th {
  background: #f3f4f6;
}
tbody tr:nth-child(even) {
  background: #fafafa;         /* «зебра»: каждая вторая строка */
}
tbody tr:hover {
  background: #eef6ff;         /* подсветка строки под курсором */
}

Самое заметное свойство здесь border-collapse: collapse. По умолчанию у каждой ячейки своя рамка, и между соседями получаются две линии с зазором. Свойство склеивает их в одну. Остальные свойства таблиц, от ширины столбцов до выравнивания чисел, проходят на курсах по CSS.

%

Таблица учебного плана с оформлением через CSS: рамки, фон шапки, зебра и подсветка строки под курсором
Та же таблица после CSS из примера. Первая строка подсвечена, потому что над ней курсор, вторая получила фон зебры

%

Как сделать таблицу адаптивной

Широкая таблица на телефоне вылезает за край экрана и тянет за собой всю страницу. Простое решение: обернуть её в блок с горизонтальной прокруткой.

<div style="overflow-x: auto;">
  <table>...</table>
</div>

Таблица прокручивается пальцем внутри своего блока, а страница стоит на месте. Чтобы шапка не уезжала при вертикальной прокрутке длинной таблицы, ячейкам thead дают position: sticky; top: 0; и фон. Остальные приёмы под телефоны, от резиновых сеток до медиазапросов, описаны в статье о видах вёрстки.

Как добавить строку в таблицу через JavaScript

У таблиц в браузере есть свои методы: insertRow() добавляет строку, insertCell() добавляет в неё ячейку. Это короче, чем собирать элементы через createElement.

const tbody = document.querySelector('#plan tbody');
const row = tbody.insertRow();          // новая строка в конце tbody
row.insertCell().textContent = '2';
row.insertCell().textContent = 'CSS';
row.insertCell().textContent = '12';

Строки таблицы лежат в коллекции table.rows, ячейки строки в row.cells. Удалить строку можно методом row.remove(). Код мы запускали в Chrome на таблице учебного плана из начала статьи.

Когда таблица не нужна

Раньше на таблицах собирали весь макет сайта: шапку, колонки, подвал. Так верстали в конце девяностых и начале двухтысячных, и в коде старых сайтов это встречается до сих пор. Сегодня таблица нужна только для табличных данных: прайсов, расписаний, сравнений, результатов.

Макет страницы собирают на CSS Grid и Flexbox. Табличная вёрстка ломается на телефонах, а программы экранного доступа зачитывают такой макет как набор строк и ячеек. Отказаться от табличного макета стоит и ради поисковиков: им проще разобрать страницу, где таблица означает именно данные.

Обратный случай тоже бывает. Если данные по смыслу табличные, но разложены в div, читатель теряет связь «заголовок и значение». А для перечня без столбцов таблица избыточна, хватит обычного списка.

Частые ошибки в разметке таблиц

Рой радуется зелёной галочке валидатора на ровной таблице

Каждую ошибку из списка мы воспроизвели и проверили валидатором W3C. В скобках его сообщение.

  1. Текст между ячейками. Слово, написанное прямо в tr или table, браузер выносит перед таблицей, и оно появляется над ней. Валидатор отмечает это ошибкой: «Misplaced non-space characters inside a table».
  2. Разное число ячеек в строках. Строка с лишней ячейкой торчит вправо, строка с недостающей обрывается. Валидатор пишет предупреждение «A table row was 3 columns wide and exceeded the column count established by the first row».
  3. Лишняя ячейка после rowspan. Ячейку, которую закрыла объединённая сверху, всё равно написали, и строка съехала на столбец.
  4. rowspan больше, чем строк в группе. Ячейка обрезается по краю tbody («Table cell spans past the end of its row group»).
  5. tfoot перед tbody или caption в конце. Правило из HTML 4 сейчас даёт ошибку, порядок частей описан выше.
  6. Оформление атрибутами. bgcolor, align, width у ячеек получают пометку «obsolete. Use CSS instead».

Если ячейка пустая, оставьте <td></td> без содержимого. Так столбец не сломается, а с border-collapse рамка у пустой ячейки тоже нарисуется.

Где освоить HTML и вёрстку системно

Таблицы, списки и абзацы относятся к первым темам курсов вёрстки. Следом идут сетки на Grid, адаптивность под телефоны и перенос макета из Figma в код. Как пройти этот путь до первой работы, мы расписали в статье как стать фронтенд-разработчиком. Чем занят на проекте верстальщик, рассказывает обзор профессии HTML-верстальщик.

Если удобнее учиться с наставником и проверкой заданий, вот курсы по HTML из нашего каталога:

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
HTML и CSS с нуля
Перейти на сайт курса
SkillboxSkillbox91 626 ₽7635 ₽/мес.11 месяцевОбзор курса
HTML и CSS. Адаптивная вёрстка и автоматизация
Перейти на сайт курса
HTMLAcademyHTML Academy23 400 ₽3900 ₽/мес.2 месяцаОбзор курса
Основы вёрстки HTML и CSS
Перейти на сайт курса
Академия СинергияАкадемия Синергия32 676 ₽2723 ₽/мес.3 месяцаОбзор курса
HTML и CSS с нуляSkyproSkypro195 160 ₽7972 ₽/мес.12 месяцевОбзор курса
Frontend-разработчик: сайты на HTML/CSS/JavaScript
Перейти на сайт курса
CoddyCoddy9200 ₽ - 3 месяцаОбзор курса

Больше программ — в полном каталоге курсов по HTML

Часто задаваемые вопросы

Что такое tr в HTML?

Тег <tr> (от table row) задаёт строку таблицы. Внутри него стоят ячейки: <td> для данных и <th> для заголовков. Текст прямо в tr писать нельзя, браузер вынесет его за пределы таблицы.

Какой тег задаёт строку таблицы, а какой столбец?

Строку задаёт <tr>. Отдельного тега для столбца с ячейками нет: столбец складывается из ячеек с одинаковым номером в разных строках. Теги <colgroup> и <col> только описывают столбцы, чтобы задать им ширину или фон.

Чем td отличается от th?

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

Как объединить ячейки в таблице HTML?

Атрибутом colspan="N" ячейка растягивается вправо на N столбцов, атрибутом rowspan="N" вниз на N строк. Ячейки, которые закрыла объединённая, в коде не пишут, иначе строка съедет на столбец.

Как сделать рамку у таблицы в HTML?

Через CSS: задайте ячейкам th и td свойство border: 1px solid, а таблице border-collapse: collapse, чтобы линии между ячейками не двоились. Атрибут border="1" у table валидатор W3C помечает как устаревший.

Обязательно ли писать tbody?

Нет. Если строки стоят прямо в <table>, браузер сам добавит <tbody> вокруг них. Учитывайте это в CSS: селектор table > tr такие строки уже не найдёт.

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!