Таблицы в HTML и CSS: разметка и стилизация

Таблицы в HTML и CSS: разметка и стилизация Полезное

Таблица в HTML — это блок разметки на теге <table>, который выводит данные сеткой из строк и столбцов. Строку задает <tr>, ячейку данных — <td>, ячейку-заголовок — <th>. Внешний вид (границы, отступы, цвета) задается не тегами, а через CSS. Ниже — минимальный рабочий пример, разбор тегов и атрибутов, объединение ячеек, стилизация и доступность.

Важно сразу развести две вещи. Разметка (HTML) отвечает за структуру и смысл: где строка, где заголовок, где данные. Оформление (CSS) отвечает за вид: рамки, отступы, чередование фона. Старые атрибуты border, cellpadding, cellspacing, align у <table> в HTML5 не используются — их заменил CSS.

Минимальная рабочая таблица

Начнем с законченного примера, который можно скопировать и открыть в браузере.

<table>
  <caption>Цены на канцтовары</caption>
  <thead>
    <tr>
      <th scope="col">Товар</th>
      <th scope="col">Цена, руб.</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Карандаш</th>
      <td>20</td>
    </tr>
    <tr>
      <th scope="row">Линейка</th>
      <td>30</td>
    </tr>
  </tbody>
</table>

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

Разберем теги по ролям:

  • <table> — контейнер всей таблицы, все остальные теги лежат внутри него.
  • <caption> — подпись таблицы, ставится сразу после <table>; выводится над таблицей.
  • <thead>, <tbody>, <tfoot> — секции: шапка, тело и подвал (итоги). Они группируют строки по смыслу.
  • <tr> — строка таблицы (table row); число строк равно числу пар <tr>.
  • <th> — ячейка-заголовок; по умолчанию текст в ней жирный и по центру.
  • <td> — ячейка данных (table data).

Число <td> и <th> в одной строке задает количество столбцов. Строки должны быть согласованы по числу ячеек, иначе разметка «поедет».

Секции thead, tbody, tfoot

Секции нужны для семантики и стилей, а не для внешнего вида сами по себе. <thead> — строки заголовков, <tbody> — основные данные, <tfoot> — итоговые строки (сумма, всего). Порядок в коде: <caption>, затем <thead>, <tfoot> или <tbody> — современные браузеры отрисуют подвал внизу независимо от места в коде, но по стандарту его принято ставить после <thead>.

Раньше ожидалось, что при длинной таблице браузер зафиксирует шапку и подвал при прокрутке, а при печати повторит их на каждой странице. На практике браузеры так делают не всегда — фиксацию шапки обычно решают через CSS (position: sticky), а не расчетом на поведение секций.

<tbody> можно использовать несколько раз — это удобно, чтобы разбить длинные данные на логические группы, сохранив одну таблицу.

Объединение ячеек: colspan и rowspan

Две частые задачи — растянуть ячейку на несколько столбцов или строк. Для этого есть атрибуты colspan (по горизонтали) и rowspan (по вертикали).

<table>
  <tbody>
    <tr>
      <th scope="row">Итого</th>
      <td colspan="2">1168,80 руб.</td>
    </tr>
    <tr>
      <th scope="row" rowspan="2">Овощи</th>
      <td>Томаты</td>
      <td>69,00</td>
    </tr>
    <tr>
      <td>Огурцы</td>
      <td>48,00</td>
    </tr>
  </tbody>
</table>

Здесь colspan="2" слил две ячейки в одну по ширине, а rowspan="2" растянул заголовок «Овощи» на две строки. Правило простое: если ячейка перекрывает соседнюю по строке или столбцу через span, эту соседнюю ячейку в коде уже не пишут — иначе появится лишний столбец. Оба атрибута принимают целое число от 1 и выше.

Стилизация таблицы через CSS

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

table {
  border-collapse: collapse;
  width: 100%;
}

th, td {
  border: 1px solid #ccc;
  padding: 8px 12px;
  text-align: left;
}

tbody tr:nth-child(even) {
  background: #f5f5f5;
}

caption {
  caption-side: top;
  padding: 6px;
  font-weight: 600;
}

Ключевые свойства:

  • border-collapse: collapse схлопывает двойные рамки соседних ячеек в одну линию. Значение по умолчанию — separate, при нем между ячейками остается зазор, а его размер задает border-spacing (работает только при separate).
  • padding у <th>/<td> — внутренний отступ между содержимым и границей ячейки. У <table> его задавать смысла нет, он ставится на ячейки.
  • nth-child(even) красит четные строки тела — получаются «полосатые» строки (zebra), их проще читать глазами.
  • caption-side двигает подпись: top — над таблицей (по умолчанию), bottom — под ней.

Адаптивность: горизонтальный скролл

Широкая таблица на телефоне ломает верстку и вызывает горизонтальную прокрутку всей страницы. Надежный прием — обернуть таблицу в контейнер с прокруткой по горизонтали, тогда скроллится только сама таблица.

<div class="table-wrap">
  <table>
    <!-- строки таблицы -->
  </table>
</div>
.table-wrap {
  overflow-x: auto;
}

table {
  min-width: 480px;
}

overflow-x: auto добавляет полосу прокрутки контейнеру, когда таблица шире экрана, а min-width не дает столбцам схлопнуться в нечитаемую кашу. Это работает во всех современных браузерах и не требует JavaScript. Полностью перестраивать таблицу в «карточки» под мобильный тоже можно, но это более трудоемкий прием и оправдан не всегда.

Доступность: caption и scope

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

Первое — <caption> как краткое описание, о чем таблица. Скринридер зачитает его до содержимого, и пользователю не придется угадывать смысл по ячейкам. Если по дизайну подпись не нужна визуально, ее не удаляют из разметки, а скрывают классом (например, приемом visually-hidden) — для программы чтения она останется.

Второе — атрибут scope у заголовочных ячеек: scope="col" для заголовка столбца и scope="row" для заголовка строки. Он связывает данные с их заголовками, и скринридер читает ячейку вместе с нужным заголовком. Для сложных таблиц с многоуровневой шапкой есть более точная связка через id у <th> и headers у <td>, но для обычных таблиц достаточно scope.

Заголовки <th> не используют ради жирного шрифта: это семантический тег. Если нужен просто жирный текст в ячейке данных — это <td> плюс CSS, а не <th>.

Атрибуты для работы с таблицами

Атрибут На каком теге Что делает
colspan td, th Объединяет ячейки по горизонтали; целое число >= 1
rowspan td, th Объединяет ячейки по вертикали; целое число >= 1
scope th К чему относится заголовок: col, row, colgroup, rowgroup
headers td, th Связь ячейки с заголовками по их id (сложные таблицы)
span col, colgroup На сколько столбцов распространяется группа; по умолчанию 1

Атрибуты border, cellpadding, cellspacing, width, align, bgcolor у таблицы в HTML5 устарели — их роль полностью взял на себя CSS.

Выводы

  • Разметка задает структуру таблицы (table, tr, th, td, секции thead/tbody/tfoot), а весь внешний вид — рамки, отступы, цвета — задается через CSS.
  • <th> — это заголовок по смыслу, а не способ сделать текст жирным; <td> — ячейка данных.
  • colspan объединяет ячейки по горизонтали, rowspan — по вертикали; перекрытые ячейки в коде не дублируют.
  • Базовая стилизация: border-collapse: collapse, padding на ячейках, полосатые строки через nth-child(even).
  • Для мобильных — обертка с overflow-x: auto; для доступности — <caption> и scope у заголовков.

Где применяется / связь с практикой

Таблицы нужны везде, где данные удобнее показать сеткой: прайсы, сравнения тарифов, расписания, отчеты, спецификации товаров. Верстальщик и фронтенд-разработчик собирают их вручную и стилизуют под макет, поэтому уверенное владение тегами таблиц и CSS — базовый навык, который спрашивают на собеседованиях junior-уровня.

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

Разобрать разметку и стилизацию на практике, с проверкой кода наставником, помогает курс «HTML/CSS: Профессиональная веб-верстка». Посмотреть формат занятий и темы можно на открытых уроках Otus — они бесплатные и проходят регулярно.

FAQ

Чем <th> отличается от <td>?
<th> — заголовочная ячейка, она несет смысл «это шапка строки или столбца» и по умолчанию отрисовывается жирной. <td> — обычная ячейка данных. Разница не в шрифте, а в семантике: скринридеры и поисковые системы читают <th> как заголовок.

Как сделать так, чтобы широкая таблица не ломала верстку на телефоне?
Обернуть таблицу в блок с overflow-x: auto и задать таблице min-width. Тогда прокручиваться будет только таблица внутри своего контейнера, а не вся страница.

Нужны ли <thead>, <tbody> и <tfoot> в простой таблице?
Формально нет, таблица работает и без них. Но секции упрощают стилизацию (например, полосатые строки только для тела) и улучшают семантику, поэтому в реальном коде их обычно ставят.

OTUS Журнал
Скидка 5% 12-19 октября на курсы (popup)
Бесплатные открытые уроки (поп-ап)