HTML-таблица — это способ вывести данные строками и столбцами с помощью тега <table> и вложенных в него строк <tr> и ячеек <td> (данные) или <th> (заголовки). Таблица нужна именно для табличных данных — расписаний, прайсов, сравнений, — а не для верстки макета страницы: раскладку страницы делают через CSS (flexbox, grid).
Содержание
Ниже — минимальный рабочий пример, затем разбор каждого тега, объединение ячеек через colspan/rowspan, доступность для скринридеров и стилизация через CSS. Сквозной пример один — прайс на смартфоны.
Минимальная таблица целиком
Начнем с законченного примера, который можно скопировать в .html-файл и открыть в браузере. Тег <table> — контейнер всей таблицы, <tr> (table row) задает строку, <td> (table data) — ячейку с данными.
<table>
<tr>
<td>iPhone 15</td>
<td>80000</td>
</tr>
<tr>
<td>Xiaomi 14</td>
<td>65000</td>
</tr>
</table>
В браузере это две строки по две ячейки: слева модель, справа цена. Столбцов отдельного тега нет — колонка возникает из того, что во всех строках ячейки идут в одном порядке. Поэтому число ячеек в строках держат одинаковым, иначе таблица «поедет».
Важно различать роли: <tr> задает строку, а колонку никакой тег не создает напрямую — она складывается из ячеек на одной позиции во всех строках.
Заголовки ячеек: th вместо td
Первая строка тут — обычные данные, а не заголовки. Для заголовка столбца или строки есть отдельный тег <th> (table header). Браузер по умолчанию делает текст в <th> жирным и центрирует его, но главное — не оформление, а смысл: <th> помечает ячейку как заголовок.
<table>
<tr>
<th>Модель</th>
<th>Цена, руб</th>
</tr>
<tr>
<td>iPhone 15</td>
<td>80000</td>
</tr>
</table>
Разница <td> и <th> не косметическая: скринридер объявляет <th> как заголовок и связывает его с ячейками данных, поэтому подписи колонок и строк всегда делают через <th>, а не через <td> с жирным шрифтом.
Структурные секции: thead, tbody, tfoot, caption
Кроме строк и ячеек у таблицы есть секции, которые группируют строки по смыслу. Они не рисуют новых ячеек — они делят таблицу на шапку, тело и итог, чтобы разметка читалась и корректно обрабатывалась.
<thead>— шапка со строками заголовков;<tbody>— основное тело с данными (их может быть несколько — под разные смысловые блоки);<tfoot>— строка итогов («подвал»);<caption>— подпись-название всей таблицы, ставится сразу после<table>.
<table>
<caption>Цены на флагманы, сентябрь 2026</caption>
<thead>
<tr>
<th scope="col">Модель</th>
<th scope="col">Цена, руб</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">iPhone 15</th>
<td>80000</td>
</tr>
<tr>
<th scope="row">Xiaomi 14</th>
<td>65000</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row">Средняя цена</th>
<td>72500</td>
</tr>
</tfoot>
</table>
По порядку в разметке <tfoot> в современном HTML ставят последним, после <tbody>. Если секции не писать вовсе, браузер сам оборачивает строки в неявный <tbody> — но явные секции полезны на сложных таблицах: они разделяют шапку, данные и итоги и помогают ассистивным технологиям.
Атрибут scope в примере — для доступности, о нем ниже.
Объединение ячеек: colspan и rowspan
Две ячейки объединяют атрибутами. Здесь легко перепутать направление: colspan растягивает ячейку по горизонтали на несколько столбцов, rowspan — по вертикали на несколько строк.
colspan="N"— ячейка занимает N столбцов (одна общая шапка над группой колонок);rowspan="N"— ячейка занимает N строк (общий заголовок для нескольких строк подряд).
Разнесем прайс на производителя и модели: ячейка «Apple» через rowspan="2" накрывает две строки моделей.
<table>
<thead>
<tr>
<th scope="col">Производитель</th>
<th scope="col">Модель</th>
<th scope="col">Цена, руб</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="rowgroup" rowspan="2">Apple</th>
<td>iPhone 15</td>
<td>80000</td>
</tr>
<tr>
<td>iPhone 15 Pro</td>
<td>110000</td>
</tr>
<tr>
<th scope="rowgroup" rowspan="2">Xiaomi</th>
<td>Xiaomi 14</td>
<td>65000</td>
</tr>
<tr>
<td>Xiaomi 14 Pro</td>
<td>85000</td>
</tr>
</tbody>
</table>
Обратите внимание: в строках после объединения ячеек меньше, чем колонок. Во второй строке всего две <td>, потому что первый столбец уже занят растянутой ячейкой «Apple». Это нормально — главное, чтобы суммарная сетка сходилась. Если посчитать ячейки с учетом span и они не складываются в прямоугольник, браузер отрисует «дыры» или лишние клетки.
Для горизонтального объединения возьмем colspan — одна шапка над двумя колонками характеристик:
<tr>
<th scope="col" rowspan="2">Модель</th>
<th scope="colgroup" colspan="2">Характеристики</th>
</tr>
<tr>
<th scope="col">Экран</th>
<th scope="col">Память</th>
</tr>
По умолчанию у любой ячейки colspan и rowspan равны 1 — писать их без объединения не нужно.
Доступность таблиц
Таблица с данными без разметки доступности — это набор ячеек, в котором незрячий пользователь теряется. Три приема закрывают большинство случаев:
<caption>дает таблице название, которое скринридер зачитывает при входе в нее — что это за данные;<th>помечает заголовки, а атрибутscopeговорит, к чему заголовок относится:scope="col"— к столбцу,scope="row"— к строке,scope="colgroup"/scope="rowgroup"— к группе подcolspan/rowspan;- заголовки строк тоже делают через
<th scope="row">, а не обычным<td>.
Со scope скринридер при переходе по ячейкам называет и заголовок столбца, и заголовок строки — пользователь понимает, что «80000» относится к строке «iPhone 15» и столбцу «Цена». Для очень сложных таблиц с многоуровневой шапкой есть связка атрибутов headers (на ячейке) и id (на заголовках) — но для типичного прайса хватает scope.
Отдельно: не верстайте таблицами макет страницы. Раньше <table> использовали для колоночной раскладки — сегодня это делают через CSS (flexbox, grid), а <table> оставляют строго под табличные данные. Табличная разметка макета путает скринридеры и ломает адаптивность.
Стилизация через CSS
У таблицы нет встроенных рамок — по умолчанию ячейки без границ, и соседние рамки задваиваются. Границы, отступы и заливку задают через CSS. Ключевое свойство — border-collapse: collapse: оно схлопывает двойные рамки соседних ячеек в одну линию.
table {
border-collapse: collapse;
width: 100%;
}
th,
td {
border: 1px solid #ccc;
padding: 8px 12px;
text-align: left;
}
thead th {
background: #f2f2f2;
}
tbody tr:nth-child(even) {
background: #fafafa;
}
caption {
caption-side: top;
font-weight: bold;
margin-bottom: 8px;
}
Здесь border рисует линии ячеек, padding — внутренние отступы, nth-child(even) подсвечивает четные строки для читаемости. Рамку логично вешать на <th>/<td>: секции <thead>, <tbody>, <tfoot> и строки <tr> можно красить фоном, но границы ячеек управляются на уровне самих ячеек.
Адаптивность на мобильных
Ширина таблицы по умолчанию подстраивается под содержимое. На узком экране широкая таблица не сожмется — она вылезет за экран. Надежный прием — обернуть таблицу в контейнер с горизонтальной прокруткой, чтобы прокручивалась таблица, а не вся страница.
.table-wrap {
overflow-x: auto;
}
<div class="table-wrap">
<table>
<!-- ... строки таблицы ... -->
</table>
</div>
Альтернатива для очень узких экранов — перестроить таблицу в карточки через CSS (display: block на строках в media-запросе) или скрыть второстепенные колонки. Прокрутка проще и не ломает семантику, поэтому начинают обычно с нее.
Выводы
- Таблица — это
<table>со строками<tr>и ячейками<td>(данные) и<th>(заголовки); колонок отдельного тега нет, они складываются из ячеек на одной позиции. - Секции
<thead>,<tbody>,<tfoot>и подпись<caption>группируют строки по смыслу и улучшают читаемость разметки и доступность. colspanобъединяет ячейки по столбцам (горизонталь),rowspan— по строкам (вертикаль); после объединения ячеек в строке меньше, но сетка должна сходиться в прямоугольник.- Доступность держится на трех приемах:
<caption>, заголовки через<th>и атрибутscope(col/row/colgroup/rowgroup). - Границ по умолчанию нет — их и остальное оформление задают через CSS (
border-collapse,border,padding); таблицы только для данных, макет — через flexbox/grid.
Где применяется / связь с практикой
Таблицы — базовый навык верстки: прайсы, спецификации товаров, расписания, сравнительные блоки в статьях. На реальных проектах к ним сразу добавляются CSS-оформление и адаптивность, а семантика и доступность — требование, которое проверяют на код-ревью.
Освойте тему на практике
Собрать это в цельный навык верстки помогает курс HTML/CSS — он идет первой ступенью FullStack-направления и разбирает разметку и стилизацию на практике. Посмотреть формат и темы вживую можно на открытых уроках до записи на курс.
Смежные темы: Введение в основы HTML для новичков, Работа с изображениями HTML через CSS.
FAQ
Можно ли сделать таблицу без tbody и thead?
Да. Если написать только <tr> с <td> внутри <table>, браузер сам обернет строки в неявный <tbody>, и таблица отобразится. Явные секции нужны для читаемости разметки, стилизации и доступности, а не для того, чтобы таблица заработала.
Чем colspan отличается от rowspan?
colspan растягивает ячейку по горизонтали на несколько столбцов, rowspan — по вертикали на несколько строк. Мнемоника: col — column (столбец), row — строка. Оба по умолчанию равны 1.
Почему таблица без CSS показывается без рамок?
У элемента <table> нет встроенных границ ячеек. Их добавляют через CSS: свойство border на <th>/<td> плюс border-collapse: collapse на <table>, чтобы рамки соседних ячеек не задваивались.



