Олег Марков
Ячейка таблицы HTML td - полное руководство по верстке таблиц
Введение
Элемент td в HTML отвечает за отображение одной ячейки в строке таблицы. С его помощью вы задаете структуру табличных данных, размещаете текст, числа, картинки, формируете сложные табличные отчеты и даже макеты (хотя для макетов таблицы сегодня почти не используют).
Смотрите, я покажу вам, как это работает, на простых примерах, а потом мы постепенно перейдем к более продвинутым вариантам использования. По сути, td — это такой же важный элемент, как div, только со строгой привязкой к табличной структуре и семантике.
Вы разберетесь:
- как правильно строить таблицу с использованием td;
- какие атрибуты у td есть в современном HTML;
- как управлять шириной, высотой, выравниванием и переносами строк;
- как объединять ячейки по горизонтали и вертикали;
- как стилизовать td с помощью CSS;
- какие есть нюансы доступности и адаптивности.
Теперь давайте по шагам разберем, как устроена ячейка таблицы и как с ней эффективно работать.
Структура таблицы и место td в ней
Базовая схема таблицы
Чтобы td работал корректно, он должен находиться в правильной иерархии тегов. Общая структура выглядит так:
- table — корневой элемент таблицы;
- tr — строка таблицы;
- td — ячейка данных;
- th — заголовочная ячейка (аналог td, но с другой семантикой).
Давайте разберемся на простом примере:
<table>
<tr>
<td>Ячейка 1</td> <!-- Первая ячейка первой строки -->
<td>Ячейка 2</td> <!-- Вторая ячейка первой строки -->
</tr>
<tr>
<td>Ячейка 3</td> <!-- Первая ячейка второй строки -->
<td>Ячейка 4</td> <!-- Вторая ячейка второй строки -->
</tr>
</table>Как видите, каждая строка tr состоит из набора ячеек td. Браузер автоматически выстраивает их в колонку по индексу: первые td в строках образуют первый столбец, вторые — второй и так далее.
Разница между td и th
Хотя статья про td, очень важно понимать, чем он отличается от th.
- td — обычная ячейка с данными.
- th — ячейка-заголовок (например, название колонки или строки).
Под капотом это влияет на:
- семантику (помогает вспомогательным технологиям, скринридерам);
- стили по умолчанию (th обычно жирный и выровнен по центру);
- поведение атрибута scope и связку с заголовками.
Пример для наглядности:
<table>
<tr>
<th>Товар</th> <!-- Заголовок колонки -->
<th>Цена</th> <!-- Заголовок колонки -->
</tr>
<tr>
<td>Яблоки</td> <!-- Обычная ячейка с данными -->
<td>100 ₽</td> <!-- Обычная ячейка с данными -->
</tr>
</table>Если вы выводите данные, почти всегда используете td. th оставляете для заголовков.
Базовое использование td
Простейший пример с текстом и числами
Начнем с самого простого: текст и числа внутри ячеек.
<table border="1">
<tr>
<td>Имя</td> <!-- Текст -->
<td>Возраст</td> <!-- Текст -->
</tr>
<tr>
<td>Анна</td> <!-- Текст -->
<td>29</td> <!-- Число, но для HTML это все равно текст -->
</tr>
</table>Здесь важно понимать: для HTML содержимое td — это потоковый контент. Вы можете размещать внутри:
- текст;
- числа;
- теги форматирования (strong, em, span, br и т. д.);
- блочные элементы (div, p, ul, img и т. д.).
Браузер не ограничивает вас только текстом.
Вложенные элементы в td
Давайте посмотрим, что происходит, когда вы вкладываете в td более сложную разметку:
<table border="1">
<tr>
<td>
<strong>Тариф Стандарт</strong> <!-- Выделенный текст -->
<p>Подходит для малого бизнеса</p> <!-- Абзац -->
<ul>
<li>До 10 проектов</li> <!-- Маркированный список -->
<li>Поддержка по email</li>
</ul>
</td>
<td>
<img src="plan.png" alt="Схема тарифа"> <!-- Картинка -->
</td>
</tr>
</table>Браузер нормально воспримет и списки, и абзацы, и картинки внутри td. С точки зрения HTML это такой же контейнер, как div, просто привязанный к строке и столбцу таблицы.
Сколько td должно быть в строке
Внутри одной строки желательно держать одинаковое количество ячеек (если не используются colspan/rowspan). Иначе браузер попытается «догадаться», как выровнять структуру, и вы можете получить неожиданную сетку.
<table border="1">
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<!-- Здесь мы забыли второй td -->
</tr>
</table>В этом случае вторая строка будет иметь только одну видимую ячейку, а таблица станет «ломаной». Чтобы избежать неожиданностей, проверяйте количество td в каждой строке или явно используйте объединение ячеек.
Основные атрибуты td
Современный HTML оставляет у td очень мало «прямых» атрибутов. Большинство старых (align, valign, bgcolor, width, height) признаны устаревшими и заменены на CSS. Но есть два ключевых, которые особенно важны:
- colspan — объединение ячеек по горизонтали;
- rowspan — объединение ячеек по вертикали.
Давайте разберем их подробнее.
Объединение ячеек по горизонтали — colspan
colspan задает, на сколько столбцов должна растянуться текущая ячейка.
<table border="1">
<tr>
<td colspan="2">Заголовок таблицы</td> <!-- Одна ячейка вместо двух -->
</tr>
<tr>
<td>Левая</td>
<td>Правая</td>
</tr>
</table>Комментарии к примеру:
- В первой строке теоретически должно быть две ячейки, чтобы совпасть со второй строкой.
- Но мы говорим браузеру: эта единственная ячейка td занимает два столбца.
- В итоге по ширине она равна сумме двух обычных ячеек.
Несколько важных моментов:
- Значение colspan должно быть положительным целым числом.
- Браузеры обычно ведут себя терпимо, даже если структура таблицы становится несимметричной, но лучше следить за логикой сетки.
- Если вы задаете colspan="3", а в строке вообще только 2 столбца, браузер будет корректировать таблицу на свое усмотрение.
Объединение ячеек по вертикали — rowspan
rowspan объединяет ячейки по вертикали — между разными строками.
<table border="1">
<tr>
<td rowspan="2">Общий параметр</td> <!-- Одна ячейка на две строки -->
<td>Значение A</td>
</tr>
<tr>
<!-- Здесь не нужно второй td на месте объединенной ячейки -->
<td>Значение B</td>
</tr>
</table>Как это работает:
- В первой строке мы говорим, что ячейка занимает две строки.
- Во второй строке мы уже не добавляем td под ней, иначе структура «поедет».
- Браузер растягивает эту ячейку по вертикали так, чтобы она занимала высоту двух строк.
К rowspan действуют те же правила, что и к colspan: целые положительные значения, аккуратное отношение к структуре.
Сочетание rowspan и colspan
Вы можете комбинировать эти атрибуты и получать сложные табличные структуры. Например, таблица с общим заголовком и объединенными ячейками:
<table border="1">
<tr>
<td rowspan="2" colspan="2">Итого</td> <!-- Одна крупная ячейка -->
<td>Квартал 1</td>
</tr>
<tr>
<td>Квартал 2</td>
</tr>
</table>Здесь я специально показываю не самый жизненный пример, а концепцию: вы можете одновременно растягивать ячейку и по строкам, и по столбцам, но при этом должны внимательно продумывать расположение остальных td, чтобы таблица оставалась логичной.
Управление размером и выравниванием содержимого td
Ширина и высота ячейки
У td нет «родных» атрибутов width и height в современном HTML, вместо этого используется CSS.
Пример управления шириной:
<table border="1">
<tr>
<td style="width: 200px;">Фиксированная ширина 200px</td> <!-- Ширина через встроенный стиль -->
<td>Автоматическая ширина</td>
</tr>
</table>Лучше выносить стили в CSS:
<style>
td.fixed-width {
width: 200px; /* Фиксированная ширина */
}
td.fixed-height {
height: 80px; /* Желаемая высота ячейки */
}
</style>
<table border="1">
<tr>
<td class="fixed-width fixed-height">
Ячейка с заданными шириной и высотой
</td>
<td>
Обычная ячейка
</td>
</tr>
</table>Обратите внимание:
- Высота ячейки не всегда будет точной, если содержимое больше заданного значения — блок может растянуться.
- Ширина делится между соседними ячейками, и таблица реагирует на ширину всего контейнера.
Выравнивание текста по горизонтали
Горизонтальное выравнивание тоже делается через CSS.
<style>
td.left { text-align: left; } /* Выровнять по левому краю */
td.center { text-align: center; } /* Выровнять по центру */
td.right { text-align: right; } /* Выровнять по правому краю */
</style>
<table border="1">
<tr>
<td class="left">Лево</td>
<td class="center">Центр</td>
<td class="right">Право</td>
</tr>
</table>Раньше для этого использовали атрибут align у td, но он устарел. Сейчас вам достаточно свойства text-align.
Выравнивание содержимого по вертикали
За вертикальное выравнивание отвечает свойство vertical-align.
<style>
td.top { vertical-align: top; } /* Вверх */
td.middle { vertical-align: middle; } /* По центру по вертикали */
td.bottom { vertical-align: bottom; } /* Вниз */
td.demo-height { height: 80px; } /* Чтобы был запас по высоте */
</style>
<table border="1">
<tr>
<td class="top demo-height">Сверху</td>
<td class="middle demo-height">По центру</td>
<td class="bottom demo-height">Снизу</td>
</tr>
</table>Если вы не зададите высоту, может быть неочевидно, что что-то выравнивается, поэтому я добавляю фиксированную высоту в примере.
Стилизация td с помощью CSS
Границы, отступы и фон
Стилизация ячеек делает таблицу гораздо нагляднее. Давайте посмотрим, как управлять рамками, фоном и внутренними отступами:
<style>
table.prices {
border-collapse: collapse; /* Объединяем границы ячеек */
}
table.prices td {
border: 1px solid #ccc; /* Серая рамка вокруг каждой ячейки */
padding: 8px; /* Внутренний отступ для текста */
background-color: #fafafa; /* Светлый фон */
}
table.prices td.highlight {
background-color: #ffe0b2; /* Подсветка важной ячейки */
font-weight: bold; /* Жирный текст */
}
</style>
<table class="prices">
<tr>
<td>Товар</td>
<td>Цена</td>
</tr>
<tr>
<td>Кофе</td>
<td class="highlight">250 ₽</td> <!-- Подсветим интересное значение -->
</tr>
</table>Обратите внимание на border-collapse: collapse. Без него каждая ячейка будет рисовать свои границы отдельно, и между ними могут появиться зазоры. С этим свойством границы схлопываются, и таблица выглядит аккуратнее.
Селекторы для разных состояний: четные и нечетные строки
Часто нужно подсвечивать строки «зеброй», чтобы таблица лучше читалась. Здесь вы можете использовать селекторы nth-child и стили для td:
<style>
table.zebra {
border-collapse: collapse;
width: 100%;
}
table.zebra td {
border: 1px solid #ddd;
padding: 6px;
}
table.zebra tr:nth-child(even) td {
background-color: #f2f2f2; /* Фон для четных строк */
}
table.zebra tr:nth-child(odd) td {
background-color: #ffffff; /* Фон для нечетных строк */
}
</style>
<table class="zebra">
<tr>
<td>Строка 1</td>
<td>Данные 1</td>
</tr>
<tr>
<td>Строка 2</td>
<td>Данные 2</td>
</tr>
<tr>
<td>Строка 3</td>
<td>Данные 3</td>
</tr>
</table>Здесь я показываю вам, как за счет селекторов tr:nth-child(...) менять стиль всех td в строке сразу.
Управление переносами строк и длинными словами
Если в ячейку попадает очень длинное слово или строка, таблица может «разъехаться». Чтобы контролировать переносы, используются CSS-свойства word-break и white-space.
<style>
table.wrap-demo {
width: 300px; /* Ограничим ширину таблицы */
border-collapse: collapse;
}
table.wrap-demo td {
border: 1px solid #ccc;
padding: 4px;
}
td.break-all {
word-break: break-all; /* Разрешаем переносить слово по любому символу */
}
td.normal {
word-break: normal; /* Стандартное поведение */
}
</style>
<table class="wrap-demo">
<tr>
<td class="normal">
Оченьдлинноесловобезпробеловкотороемустановитразметку <!-- Может растянуть ячейку -->
</td>
</tr>
<tr>
<td class="break-all">
Оченьдлинноесловобезпробеловкотороемустановитразметку <!-- Здесь слово перенесется -->
</td>
</tr>
</table>Так вы можете контролировать поведение таблицы при длинных значениях, которые часто встречаются в реальных данных (артикулы, длинные URL, коды).
Семантика и доступность td
Когда использовать td, а когда лучше другой элемент
Табличная верстка раньше использовалась для построения целых макетов страниц. Сейчас от этого подхода отказались, потому что:
- таблица несет семантику «табличных данных»;
- она сложнее адаптируется под мобильные устройства;
- скринридеры по-другому обрабатывают таблицы.
Используйте td только тогда, когда вы действительно представляете данные в табличном виде:
- расписание;
- отчеты;
- сравнение характеристик;
- финансовые таблицы;
- любые структуры, где есть четкие строки и столбцы данных.
Если вы просто строите сетку для блоков — выбирайте div, flex, grid.
Связка с заголовками th
Сам по себе td — просто ячейка. Чтобы таблица была доступной, важно связать ячейки с заголовками th. Простая таблица с заголовками колонок не требует дополнительных атрибутов — строка заголовка обычно распознается по тегам th.
Но если структура сложнее (многоуровневые заголовки или заголовки по строкам), добавляют:
- id в th;
- headers в td (список id соответствующих заголовков).
Пример:
<table border="1">
<tr>
<th id="product">Товар</th> <!-- Заголовок с уникальным id -->
<th id="price">Цена</th>
<th id="quantity">Количество</th>
</tr>
<tr>
<td headers="product price quantity">
Яблоки 100 ₽ 5 шт
</td>
</tr>
</table>В реальных проектах для сложных таблиц обычно делают более аккуратную структуру, разбивая значения на отдельные td, но принцип headers остается тем же: вы явно говорите, к каким заголовкам относится ячейка.
Атрибут scope и его влияние на td
Атрибут scope применяется только к th, но косвенно влияет и на понимание td скринридерами. Например:
- scope="col" — заголовок колонки;
- scope="row" — заголовок строки.
td такой атрибут не принимает, но зная это, вы сможете правильно строить таблицы, чтобы ваши ячейки данных были связаны с нужными заголовками.
Адаптивность и поведение td на мобильных устройствах
Проблема: таблица не помещается по ширине
Таблицы часто выходят за пределы экрана на мобильных устройствах. Сам td здесь не управляет адаптивностью, но то, как вы стилизуете таблицу и ячейки, сильно влияет на поведение.
Один из распространенных подходов — добавлять горизонтальную прокрутку:
<style>
.table-wrapper {
overflow-x: auto; /* Разрешаем горизонтальную прокрутку */
max-width: 100%; /* Не выходим за пределы контейнера */
}
table.responsive {
border-collapse: collapse;
min-width: 400px; /* Минимальная ширина таблицы */
}
table.responsive td {
border: 1px solid #ccc;
padding: 6px;
}
</style>
<div class="table-wrapper"> <!-- Оборачиваем таблицу в блок с прокруткой -->
<table class="responsive">
<tr>
<td>Заголовок 1</td>
<td>Заголовок 2</td>
<td>Заголовок 3</td>
<td>Заголовок 4</td>
</tr>
<tr>
<td>Данные 1</td>
<td>Данные 2</td>
<td>Данные 3</td>
<td>Данные 4</td>
</tr>
</table>
</div>Здесь сама ячейка td ничего «не знает» про адаптивность, но ее размер и отображение зависят от ширины таблицы и контейнера.
Перестройка таблицы в «карточки» через CSS
Более сложный подход — выводить таблицу в виде карточек на мобильных устройствах. Это уже больше про CSS, но td становится частью этого преобразования.
Схема простая:
- на больших экранах таблица выглядит как обычно;
- на маленьких — ячейки td становятся блоками, а подписи берутся из data-атрибутов.
Небольшой концептуальный пример:
<style>
table.adaptive {
width: 100%;
border-collapse: collapse;
}
table.adaptive td {
border: 1px solid #ccc;
padding: 6px;
}
@media (max-width: 600px) {
table.adaptive,
table.adaptive tr,
table.adaptive td {
display: block; /* Показываем элементы как блочные */
width: 100%;
}
table.adaptive td::before {
content: attr(data-label); /* Берем подпись из data-атрибута */
font-weight: bold;
display: block;
margin-bottom: 4px;
}
}
</style>
<table class="adaptive">
<tr>
<td data-label="Товар">Яблоки</td> <!-- Подпись для мобильного вида -->
<td data-label="Цена">100 ₽</td>
</tr>
</table>Покажу вам, как это реализовано: на мобильных td превращаются в «строчки карточки», где перед значением выводится подпись из data-label. Таким образом вы сохраняете семантику таблицы, но улучшаете восприятие на узких экранах.
Частые практические паттерны с td
Таблица «ключ–значение»
Классический пример — таблица характеристик товара:
<table border="1">
<tr>
<td>Производитель</td>
<td>Acme Corp</td>
</tr>
<tr>
<td>Модель</td>
<td>X100</td>
</tr>
<tr>
<td>Гарантия</td>
<td>2 года</td>
</tr>
</table>Здесь:
- первый td в строке — название параметра;
- второй td — значение.
Часто первый столбец делают визуально отличающимся:
<style>
table.specs {
border-collapse: collapse;
}
table.specs td {
border: 1px solid #ccc;
padding: 6px;
}
table.specs td:first-child {
font-weight: bold; /* Выделяем названия параметров */
background-color: #f5f5f5; /* Слегка тонируем */
width: 30%;
}
</style>Ячейки как «кнопки» или элементы управления
Иногда td используют как оболочку для кликабельных элементов: ссылок, кнопок, чекбоксов. Сама td не является элементом управления, но может содержать их.
<style>
td.action {
text-align: center; /* Центрируем содержимое */
}
td.action a {
display: inline-block;
padding: 4px 8px;
background-color: #1976d2;
color: #fff;
text-decoration: none;
border-radius: 4px;
font-size: 14px;
}
td.action a:hover {
background-color: #1565c0;
}
</style>
<table border="1">
<tr>
<td>Пользователь 1</td>
<td class="action">
<a href="#edit">Редактировать</a> <!-- Кнопка-ссылка внутри ячейки -->
</td>
</tr>
</table>Обратите внимание: клик-обработчики (JavaScript) навешивают на кнопку или ссылку, а td всего лишь держит контент.
colspan для заголовков секций в таблице
Когда таблица большая, удобно разбивать ее на логические блоки при помощи объединенных по ширине ячеек.
<table border="1">
<tr>
<td colspan="3">Личные данные</td> <!-- Заголовок блока -->
</tr>
<tr>
<td>Имя</td>
<td>Фамилия</td>
<td>Возраст</td>
</tr>
<tr>
<td>Анна</td>
<td>Иванова</td>
<td>29</td>
</tr>
<tr>
<td colspan="3">Контакты</td> <!-- Еще один заголовок блока -->
</tr>
<tr>
<td>Email</td>
<td>Телефон</td>
<td>Город</td>
</tr>
</table>Здесь я показываю удобный прием: вы можете использовать td (или th) с colspan, чтобы визуально разделять таблицу на логические разделы.
Типичные ошибки при работе с td и как их избежать
Несогласованное количество ячеек в строках
Ошибка:
- в строке 1 — 3 td;
- в строке 2 — 2 td без объединения;
- таблица становится «кривой».
Как исправить:
- либо добавляете недостающие td;
- либо правильно используете colspan/rowspan;
- либо пересматриваете структуру таблицы.
Использование устаревших атрибутов оформления
Старый подход:
<td align="center" bgcolor="#ff0000">Текст</td>Вместо этого:
<style>
td.center-red {
text-align: center; /* Горизонтальное выравнивание */
background-color: #ff0000; /* Цвет фона */
}
</style>
<td class="center-red">Текст</td>Так вы отделяете структуру (HTML) от оформления (CSS) и делаете код поддерживаемым.
Использование таблиц вместо современных сеток
Если вы строите адаптивный макет страницы (колонки, блоки, карточки), старайтесь не использовать td. Таблицы тяжело адаптировать, и они несут неверную семантику. Для таких задач подойдут flexbox и CSS grid.
td же оставьте для случаев, когда данные логически представимы в виде строк и столбцов.
Семантически td — это элемент для представления одной ячейки данных в таблице. Он должен находиться внутри tr, а строка — внутри table. Внутрь td можно помещать почти любые элементы — от простого текста до сложной разметки с картинками, списками и кнопками.
Основные возможности td:
- объединение по горизонтали и вертикали через colspan и rowspan;
- управление размером и выравниванием при помощи CSS;
- стилизация границ, фона и отступов;
- участие в построении доступных таблиц за счет связки с th и грамотной структуры.
Давайте подытожим главное:
- используйте td для табличных данных, а не для общего макета страницы;
- не применяйте устаревшие атрибуты оформления, все решается через CSS;
- следите за согласованностью структуры: одинаковое количество ячеек в строках или явное объединение;
- не забывайте про адаптивность и поведение таблиц на маленьких экранах;
- думайте о доступности — правильно расставленные заголовки и логичная структура помогают и пользователям, и поисковым системам.
Если вам нужно вывести данные в виде таблицы, td остается основным и незаменимым инструментом.
Частозадаваемые технические вопросы по теме статьи и ответы на них
Как сделать так, чтобы вся ячейка td была кликабельной как ссылка
Оберткой делаем ссылку, а не наоборот:
<a href="/user/1">
<table>
<tr>
<td>Пользователь 1</td> <!-- Вся ячейка внутри ссылки -->
</tr>
</table>
</a>Либо стилизуем содержимое внутри td как кнопку на всю ширину:
<td>
<a href="/user/1" style="display:block; width:100%; height:100%;">
Пользователь 1
</a>
</td>Почему padding на td не работает как ожидалось
Частая причина — включен border-collapse: collapse и задана общая высота строки. Проверьте:
- нет ли жестких height у tr/td;
- нет ли стилей line-height, перезаписывающих высоту строки.
Лучше убрать фиксированную высоту и работать через padding и min-height на td.
Как задать минимальную ширину столбца через td
Используйте min-width для td или th в первой строке:
<style>
td.col-1 {
min-width: 150px; /* Минимальная ширина столбца */
}
</style>
<tr>
<td class="col-1">...</td>
<td>...</td>
</tr>Браузер учтет min-width при распределении ширины таблицы.
Как запретить перенос строки внутри td
Примените white-space: nowrap:
<td style="white-space: nowrap;">
Текст без переноса на другую строку
</td>Учтите, что при очень длинной строке таблица может выйти за границы экрана, поэтому используйте это осмотрительно.
Как выровнять несколько элементов внутри td по разным краям
Оберните содержимое в flex-контейнер:
<td>
<div style="display:flex; justify-content:space-between; align-items:center;">
<span>Название</span> <!-- Слева -->
<span>100 ₽</span> <!-- Справа -->
</div>
</td>Так вы сможете гибко управлять расположением элементов внутри одной ячейки.
Постройте личный план изучения Html до уровня Middle — бесплатно!
Html — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Все гайды по Html
Лучшие курсы по теме

HTML и CSS
Антон Ларичев
TypeScript с нуля
Антон Ларичев