skip to main content

Таблицы

html

Кратко 🔗

Иногда для простоты восприятия контент нужно разместить в виде таблицы.
Таблица состоит из строк и столбцов и предназначена для структурирования данных. Часто в таблицах размещают однотипные данные. Пример таблицы из школьных лет — классный журнал. Каждая строка это ученик. Колонки — даты. Напротив каждой фамилии можно проставить оценку за урок, прошедший в конкретную дату.

В HTML для создания таблиц существует набор семантических тегов:

  • <table>
  • <thead>
  • <tbody>
  • <tfoot>
  • <th>
  • <tr>
  • <td>

Пример 🔗

Напишем таблицу с первыми 3 местами в топ-250 лучших фильмов:

<table>
<thead>
<tr>
<th>Место</th>
<th>Оценка</th>
<th>Название фильма</th>
<th>Год выхода</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>9.1</td>
<td>Зелёная миля</td>
<td>1999</td>
</tr>
<tr>
<td>2</td>
<td>9.1</td>
<td>Побег из Шоушенка</td>
<td>1994</td>
</tr>
<tr>
<td>3</td>
<td>8.6</td>
<td>Властелин колец: Возвращение Короля</td>
<td>2003</td>
</tr>
</tbody>
</table>

See the Pen mdrWxro by Alena (@solarrust) on CodePen.

Структурные теги 🔗

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

table 🔗

Самый важный тег для создания таблицы это <table>. С него всё начинается. Им всё заканчивается. Встречая этот тег в разметке браузер понимает что дальше будет таблица.

Это парный тег, внутри которого мы дальше разметим строки и ячейки. А пока просто создадим нашу таблицу.

<table>

</table>

tr 🔗

Любая таблица в первую очередь состоит из строк. Чтобы в таблице появились строки используйте парный тег <tr>. Сколько нужно строк — столько нужно написать <tr> внутри <table>.

Пока добавим три строчки в таблицу:

<table>
<tr></tr>
<tr></tr>
<tr></tr>
</table>

tr расшифровывается как «table row» и переводится «ряд таблицы»

td 🔗

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

Ячейки формируют из себя столбцы. В HTML нет специального тега для столбцов.

Ячейки теоретически могут существовать и без <tr>. Они будут выстраиваться в строку. Чтобы новые ячейки встали в новую строку мы как раз и используем <tr>.

<table>
<tr>
<td>iPhone 12 Pro</td>
<td>$999</td>
</tr>
<tr>
<td>iPhone 12</td>
<td>$799</td>
</tr>
<tr>
<td>iPhone 12 mini</td>
<td>$699</td>
</tr>
</table>

td расшифровывается как «table data» и переводится «данные таблицы»

Теперь в нашей таблице 3 строки. В каждой строке по две ячейки. Из этих ячеек складывается два столбца.
По смыслу данных, в принципе, понятно, что в этой таблице. Но лучше добавить подписи для колонок, чтобы исключить недопонимание.

В принципе можно использовать уже знакомые нам <tr> и <td>:

<table>
<tr>
<td>Модель</td>
<td>Цена</td>
</tr>
<tr>
<td>iPhone 12 Pro</td>
<td>$999</td>
</tr>
<tr>
<td>iPhone 12</td>
<td>$799</td>
</tr>
<tr>
<td>iPhone 12 mini</td>
<td>$699</td>
</tr>
</table>

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

th 🔗

Специально для заголовков ячеек или строк есть тег <th>. Обернём в этот парный тег заголовки:

<table>
<tr>
<th>Модель</th>
<th>Цена</th>
</tr>
<tr>
<td>iPhone 12 Pro</td>
<td>$999</td>
</tr>
<tr>
<td>iPhone 12</td>
<td>$799</td>
</tr>
<tr>
<td>iPhone 12 mini</td>
<td>$699</td>
</tr>
</table>

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

th расшифровывается как «table header» и переводится «заголовок таблицы»

Теги логической группировки 🔗

Дальше пойдёт описание тегов <thead>, <tbody>, <tfoot> и <caption>. Казалось бы, у нас уже есть прекрасно выглядящая таблица. К чему усложнять?

Во-первых, это красиво 😄

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

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

Сниппет с таблицей расписания поездов на странице поисковой выдачи Google

thead 🔗

Тег <thead> отвечает за верхнюю часть таблицы. Внутри этого тега может располагаться одна или более строк с заголовками таблицы. <thead> должен располагаться в разметке сразу за открывающим <table> или после <caption>, но строго до <tbody> и <tfoot>.

<thead> по своей семантике похож на тег <header>, только его «влияние» распространяется в пределах таблицы.

Наличие этих тегов в разметке удобно и с точки зрения стилизации. Можно разом применить стили к блоку целиком, используя селекторы thead, tbody или table :not(tbody) (почему бы и нет? 😏).

Добавим в нашу таблицу <thead>:

<table>
<thead>
<tr>
<th>Модель</th>
<th>Цена</th>
</tr>
</thead>
<tr>
<td>iPhone 12 Pro</td>
<td>$999</td>
</tr>
<tr>
<td>iPhone 12</td>
<td>$799</td>
</tr>
<tr>
<td>iPhone 12 mini</td>
<td>$699</td>
</tr>
</table>

tbody 🔗

Этот тег предназначен для основной части таблицы. Внутрь него помещаются строки с данными.
Можно использовать несколько <tbody> внутри таблицы, разделяя тем самым данные на отдельные блоки.

Этот тег схож по семантике с <main>, но в пределах таблицы.

Обернём все айфоны в один <tbody> и добавим пару андройдов, чтобы показать, что может быть больше одного блока данных:

<table>
<thead>
<tr>
<th>Модель</th>
<th>Цена</th>
</tr>
</thead>
<tbody>
<tr>
<td>iPhone 12 Pro</td>
<td>$999</td>
</tr>
<tr>
<td>iPhone 12</td>
<td>$799</td>
</tr>
<tr>
<td>iPhone 12 mini</td>
<td>$699</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Xiaomi Mi 10</td>
<td>$768</td>
</tr>
<tr>
<td>Xiaomi Black Shark 3 128Gb</td>
<td>$529</td>
</tr>
</tbody>
</table>

tfoot 🔗

Тег <tfoot> нужен для строки «Итого» — некой строки с итогом данных таблицы. В таблице может быть только один блок <tfoot>.

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

Если по какой-то причине вы не использовали в таблице <thead> или <tbody>, то футер будет отрисован после всех <tr>.

По семантике этот тег похож на <footer> в пределах таблицы.

Добавим в нашу таблицу строку со средней ценой всех телефонов:

<table>
<thead>
<tr>
<th>Модель</th>
<th>Цена</th>
</tr>
</thead>
<tbody>
<tr>
<td>iPhone 12 Pro</td>
<td>$999</td>
</tr>
<tr>
<td>iPhone 12</td>
<td>$799</td>
</tr>
<tr>
<td>iPhone 12 mini</td>
<td>$699</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Xiaomi Mi 10</td>
<td>$768</td>
</tr>
<tr>
<td>Xiaomi Black Shark 3 128Gb</td>
<td>$529</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Средняя цена:</td>
<td>$758.8</td>
</tr>
</tfoot>
</table>

caption 🔗

Если нужно подписать таблицу, дать ей определение, то можно использовать парный тег <caption>. В него помещается общая информация о таблице.

Тег <caprion> должен идти сразу после открывающего тега <table>.

Например, для нашей таблицы прекрасно подошло бы описание «Цены на флагманские модели iPhone и Xiaomi». Добавим его в разметку (часть данных опущена для краткости):

<table>
<caption>Цены на флагманские модели iPhone и Xiaomi</caption>
<thead>
<tr>
<th>Модель</th>
<th>Цена</th>
</tr>
</thead>
<tbody>
<!-- Данные по iPhone -->
</tbody>
<tbody>
<!-- Данные по Xiaomi -->
</tbody>
<tfoot>
<tr>
<td>Средняя цена:</td>
<td>$758.8</td>
</tr>
</tfoot>
</table>

Атрибуты 🔗

Помимо глобальных атрибутов при работе с таблицами вам могут очень пригодиться атрибуты colspan и rowspan. Оба атрибута предназначены для объединения ячеек. colspan нужен для объединения ячеек из 2 или более столбцов, а rowspan для объединения ячеек из 2 или более рядов.

Разделим название телефонов на производителя и модель. Производитель будет повторяться, объединим ячейки с его названием во всех рядах. Добавим один заголовок «Производитель», а в первые <tr> каждого из <tbody> и применим атрибут rowspan. Теперь эти ячейки занимают собой пространство в 3 и 2 ряда соответственно.

<table>
<caption>Цены на флагманские модели iPhone и Xiaomi</caption>
<thead>
<tr>
<th>Производитель</th>
<th>Модель</th>
<th>Цена</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="3">iPhone</td>
<td>12 Pro</td>
<td>$999</td>
</tr>
<tr>
<td>12</td>
<td>$799</td>
</tr>
<tr>
<td>12 mini</td>
<td>$699</td>
</tr>
</tbody>
<tbody>
<tr>
<td rowspan="2">Xiaomi</td>
<td>Mi 10</td>
<td>$768</td>
</tr>
<tr>
<td>Black Shark 3 128Gb</td>
<td>$529</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Средняя цена:</td>
<td>$758.8</td>
</tr>
</tfoot>
</table>

Но теперь в итоговой строке количество ячеек не совпадает с общим числом колонок в таблице. Растянем первую ячейку на две колонки.

<table>
<caption>Цены на флагманские модели iPhone и Xiaomi</caption>
<thead>
<tr>
<th>Производитель</th>
<th>Модель</th>
<th>Цена</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="3">iPhone</td>
<td>12 Pro</td>
<td>$999</td>
</tr>
<tr>
<td>12</td>
<td>$799</td>
</tr>
<tr>
<td>12 mini</td>
<td>$699</td>
</tr>
</tbody>
<tbody>
<tr>
<td rowspan="2">Xiaomi</td>
<td>Mi 10</td>
<td>$768</td>
</tr>
<tr>
<td>Black Shark 3 128Gb</td>
<td>$529</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">Средняя цена:</td>
<td>$758.8</td>
</tr>
</tfoot>
</table>

Подсказки 🔗

💡 У таблицы нет встроенных стилей для отображения границ ячеек. Не удивляйтесь, если, написав разметку, вы не увидите рамки. Используйте CSS-свойство border.

Задать границы элементам <tr>, <thead>, <tfoot> и <tbody> нельзя, поэтому задавайте их тегам <table>, <th> или <td>.

💡 Внимательно считайте количество ячеек в строках таблицы. Их количество должно совпадать. Особенно важно это делать, если растягиваете ячейки по горизонтали или вертикали. Не удивляйтесь, если снизу таблицы или сбоку в одной из строк внезапно будет торчать ячейка, нарушая красоту вашей таблицы. Вы просто где-то забыли удалить лишнюю ячейку.

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

💡 Ширина таблицы по умолчанию подстраивается под контент внутри, если не задавать дополнительные CSS-свойства.

Это приводит к определённым сложностям на адаптивных сайтах. Если контент не помещается на маленький экран, то таблица не сжимается, у неё появляется горизонтальный скролл.

У этой проблемы есть несколько потенциальных решений: скрывать не первостепенную информацию для пользователей мобильных устройств или перестраивать отображение таблицы, например, при помощи свойства display.

В работе 🔗

🛠 Частый дизайнерский приём — подсветка строк таблицы через одну. Это помогает считывать длинные таблицы, глазу есть за что зацепиться.

Например, сделаем каждую вторую строку с серым фоном. Для этого понадобится всего одно CSS-правило с псевдоклассом :nth-child():

tr:nth-child(even) {
background-color: gray;
}

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

tbody tr:nth-child(even) {
background-color: gray;
}

🛠 Можно сделать так, чтобы строка с заголовками колонок прилипала при прокрутке длинной таблицы. Это удобно, если данных много и пользователь может просто забыть в какой колонке какие данные.

Это довольно просто сделать при помощи position: sticky. Имейте в виду, что нельзя применить это свойство к тегам <thead> или <tr>, поэтому применим его к <th>.

th {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 1;
}

Не забудьте добавить position: relative для родителя. Заодно подстрахуемся и сделаем прилипающими только заголовки в шапке таблицы.

table {
position: relative;
}

thead th {
position: sticky;
position: -webkit-sticky;
top: 0;
z-index: 1;
}

Задайте фон заголовкам чтобы текст ячеек не был виден при прокрутке. А чтобы избавиться от белых линий между ячейками зададим для всей таблицы свойство border-collapse: collapse:

table {
position: relative;
border-collapse: collapse;
}

thead th {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 1;
background-color: lightgray;
}

Автор: Алёна,