Тег tfoot (от английского table foot, «подвал таблицы») собирает итоговые строки: суммы, средние значения, пояснения к колонкам. Браузер выводит подвал под телом таблицы, где бы он ни был записан, а при печати на нескольких страницах повторяет его на каждой из них.
Зачем таблицу делят на шапку, тело и подвал, объясняет урок «Как разделить таблицу: thead, tbody и tfoot». Здесь собрано то, чего в уроке нет: где по стандарту записывают tfoot и что будет при неверном порядке, как оформить итоговую строку, как закрепить подвал, как не повторять итог на каждой печатной странице и как управлять подвалом из скрипта.
<table>
<thead>
<tr><th>Чай</th><th>Цена</th></tr>
</thead>
<tbody>
<tr><td>Сенча</td><td>100</td></tr>
<tr><td>Улун</td><td>120</td></tr>
</tbody>
<tfoot>
<tr><th scope="row">Итого</th><td>220</td></tr>
</tfoot>
</table>
В этой статье
- Тег tfoot в HTML: что это и что записывать внутри
- Где записывать tfoot: порядок, валидность и парсер
- Стили tfoot: оформление итоговой строки и поиск последнего tbody
- Закрепление tfoot при прокрутке: sticky bottom, две строки и граница
- Печать tfoot: как не повторять итог на каждой странице
- Тег tfoot и JavaScript: tFoot, createTFoot и deleteTFoot
- Частые ошибки с тегом tfoot
Тег tfoot в HTML: что это и что записывать внутри
Внутри tfoot записывают только строки tr. Строк может быть несколько: например, «Итого», «НДС» и «К оплате». Начальный тег обязателен, своих атрибутов у тега нет, только глобальные. По умолчанию браузер выводит его отдельной секцией (display: table-footer-group), а для скринридера это группа строк с ролью rowgroup.
Название итога записывают ячейкой th с scope="row": для скринридера она остаётся заголовком строки, а число рядом записывают обычной ячейкой td. Если название итога должно занять несколько колонок, ячейке задают colspan.
| Запись | Что получается | Пример записи |
|---|---|---|
th со scope="row" в tfoot | Заголовок итоговой строки | <th scope="row">Итого</th> |
td в tfoot | Ячейка с итоговым значением | <td>220</td> |
colspan у th | Название итога занимает несколько колонок, значение стоит под последней | <th scope="row" colspan="2">Итого</th> |
Несколько строк tr | Все строки выводятся в подвале под телом таблицы | <tr>...</tr><tr>...</tr> |
Атрибуты align, valign, bgcolor | Устарели | Свойства text-align, vertical-align и background |
<tfoot>
<tr><th scope="row" colspan="2">Итого</th><td>7260</td></tr>
<tr><th scope="row" colspan="2">НДС</th><td>1210</td></tr>
</tfoot>
Где записывать tfoot: порядок, валидность и парсер
По стандарту tfoot записывают последним среди секций таблицы: после caption, colgroup, thead, tbody и строк tr, и он может быть только один. В HTML 4 подвал, наоборот, требовалось записывать перед tbody, и это правило до сих пор встречается в справочниках. Валидатор Nu считает ошибкой tfoot перед tbody, перед thead и второй tfoot в одной таблице.
Браузер ошибку не показывает: подвал выводится внизу при любом месте записи, поэтому неверный порядок остаётся незамеченным, пока код не проверит валидатор. Закрывающий тег </tfoot> можно опустить только в конце таблицы, когда после подвала нет других секций.
| Как записано | Что делает браузер | Пример записи |
|---|---|---|
tfoot последним | Выводит подвал внизу, запись соответствует стандарту | <tbody>...</tbody><tfoot>...</tfoot> |
tfoot перед tbody | Выводит подвал внизу, но валидатор считает запись ошибкой | <tfoot>...</tfoot><tbody>...</tbody> |
Два tfoot | Внизу выводит первый, а второй остаётся обычной секцией на своём месте; валидатор считает второй ошибкой | <tfoot>...</tfoot><tfoot>...</tfoot> |
Опущен </tfoot>, а следом идёт tr | Строка остаётся внутри tfoot | <tfoot><tr><td>Итого<tr><td>Сенча |
Текст или div внутри tfoot | Выносит их из таблицы, они оказываются перед ней | <tfoot>Итого<tr>...</tr></tfoot> |
Пример: где записан tfoot и что получилось
Выберите запись: вверху виден код, внизу - что получилось на экране.
Как браузер разбирает запись шапки, описано на странице thead, а секции тела с опущенными тегами - на странице tbody. Допустимые места записи перечислены в описании элемента в стандарте HTML.
Стили tfoot: оформление итоговой строки и поиск последнего tbody
Общие правила, то есть наследование цвета, размера шрифта и выравнивания, фон секции и граница при border-collapse: collapse, работают у tfoot так же, как у thead: подробности есть на странице thead. Итоговую строку обычно выделяют жирным шрифтом, название итога выравнивают по правому краю, а от тела таблицы отделяют верхней границей.
| Запись | Что получается | Пример записи |
|---|---|---|
font-weight у tfoot | Значение доходит до td, а th и так жирные | tfoot { font-weight: 700; } |
text-align у tfoot th | Название итога выравнивается по правому краю | tfoot th { text-align: right; } |
border-top у tfoot | Рисуется только при border-collapse: collapse | tfoot { border-top: 3px solid #c0292e; } |
tbody:last-child | Ничего не выбирает: после tbody записан tfoot, и tbody не последний дочерний элемент | tbody:last-child { ... } |
tbody:last-of-type | Выбирает последний tbody: подвал в счёте не участвует | tbody:last-of-type { ... } |
Пример: оформление итоговой строки
Выберите правило и при желании включите border-collapse: collapse: результат виден сразу.
tfoot {
font-weight: 700;
border-top: 3px solid #2c5e77;
}
tfoot th {
text-align: right;
}
table {
border-collapse: collapse;
}
Закрепление tfoot при прокрутке: sticky bottom, две строки и граница
Подвал закрепляют у нижнего края значением position: sticky со свойством bottom: итоговая строка остаётся на виду, пока таблица прокручивается, а когда прокрутка доходит до конца, занимает своё обычное место. Правило записывают на tfoot или на ячейки, и результат разный. Закрепление шапки описано на странице thead, у подвала те же особенности, но отсчёт идёт снизу.
| Запись | Результат | Пример записи |
|---|---|---|
tfoot с position: sticky | Все строки подвала закреплены как одна группа | tfoot { position: sticky; bottom: 0; } |
th и td с position: sticky, одна строка | Работает так же | tfoot th, tfoot td { position: sticky; bottom: 0; } |
Ячейки двух строк с bottom: 0 | Строки наезжают друг на друга | tfoot th, tfoot td { bottom: 0; } |
Верхняя строка с bottom, равным высоте нижней | Строки закреплены друг над другом | tfoot tr:first-child th { bottom: 24px; } |
Закреплены и thead, и tfoot | Шапка у верхнего края, подвал у нижнего | thead { top: 0; } tfoot { bottom: 0; } |
Закрепление при border-collapse: collapse | Верхняя граница подвала пропадает | tfoot th { box-shadow: inset 0 3px 0 #000; } |
Обёртка с overflow-x: auto | Подвал не закрепляется при прокрутке страницы: он привязывается к обёртке | .wrap { overflow-x: auto; } |
Пример: закрепление подвала в блоке с прокруткой
Выберите запись: блок уже прокручен немного вниз, и видно, где остановился подвал.
Ячейкам подвала нужен собственный фон: иначе строки тела видны сквозь него. Когда таблица выше окна, подвал с bottom: 0 прижимается к нижнему краю окна, пока таблица на экране.
thead {
position: sticky;
top: 0;
}
tfoot {
position: sticky;
bottom: 0;
}
thead th,
tfoot th,
tfoot td {
background: #fff;
}
Печать tfoot: как не повторять итог на каждой странице
При печати на нескольких страницах браузер повторяет подвал внизу каждой страницы так же, как шапку вверху. В пробной таблице из 120 строк на листах A4 строка «Итого» вышла на всех четырёх страницах. Для сводки по колонке это удобно, а для итога всей таблицы нет: сумма внизу первой страницы выглядит как итог только этой страницы. Поэтому подвалу возвращают обычный режим вывода, и он остаётся один раз в конце таблицы, а шапка по-прежнему повторяется.
@media print {
tfoot {
display: table-row-group;
}
}
| Запись | Результат при печати | Пример записи |
|---|---|---|
Обычный tfoot | Подвал повторяется на каждой странице | <tfoot>...</tfoot> |
tfoot с display: table-row-group | Подвал стоит только на последней странице | tfoot { display: table-row-group; } |
Результат видно в предпросмотре печати: Ctrl + P. Повтор шапки и его отмена описаны на странице thead.
Тег tfoot и JavaScript: tFoot, createTFoot и deleteTFoot
Подвал в скрипте представлен интерфейсом HTMLTableSectionElement. Свойство tFoot возвращает подвал или null, метод createTFoot() создаёт его в конце таблицы, а если подвал уже есть, возвращает существующий, поэтому два вызова подряд не дадут два подвала. Метод deleteTFoot() удаляет подвал, при двух tfoot только первый.
| Запись | Что делает | Пример записи |
|---|---|---|
table.tFoot | Возвращает первый подвал или null | const foot = table.tFoot; |
table.createTFoot() | Создаёт подвал в конце таблицы или возвращает существующий | table.createTFoot(); |
table.deleteTFoot() | Удаляет первый подвал | table.deleteTFoot(); |
tfoot.insertRow() | Добавляет строку в подвал | foot.insertRow(); |
row.rowIndex | Возвращает номер строки в таблице: строка подвала идёт после всех строк шапки и тела | foot.rows[0].rowIndex |
Пример: методы таблицы для подвала
Выберите действие: вверху виден код, под ним таблица и результат, который считает сама страница.
const rows = table.tBodies[0].rows;
const sum = [...rows].reduce(
(total, row) => total + Number(row.cells[1].textContent),
0
);
const foot = table.tFoot ?? table.createTFoot();
const row = foot.rows[0] ?? foot.insertRow();
row.replaceChildren();
row.insertCell().textContent = 'Итого';
row.insertCell().textContent = sum;
Метод table.insertRow(-1) у таблицы с подвалом добавляет строку в tfoot, а не в тело: строки данных добавляют в tbody, как описано на странице tbody. Ячейки, созданные методом insertCell(), получаются тегами td, поэтому название итога, если оно должно быть заголовком строки, создают через document.createElement('th').
Частые ошибки с тегом tfoot
Ошибки с тегом tfoot и их исправления.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
tfoot перед tbody, как в HTML 4 | Браузер выводит подвал внизу, но валидатор считает запись ошибкой | Записывать tfoot последним |
Два tfoot в одной таблице | Внизу выводится только первый, второй остаётся обычной секцией | Объединить строки в один tfoot |
Опущен </tfoot> перед строкой данных | Строка остаётся внутри tfoot | Строки данных записывать в tbody, а tfoot закрывать |
Текст внутри tfoot | Браузер выносит его перед таблицей | Записывать текст в ячейки th или td |
tbody:last-child при подвале | Ничего не выбирает | tbody:last-of-type |
tfoot { border-top: 1px solid; } без collapse | Рамка не рисуется | Добавить border-collapse: collapse или использовать box-shadow |
| Закреплённый подвал без фона | Строки тела видны сквозь подвал | tfoot th, tfoot td { background: #fff; } |
Ячейки двух строк подвала с bottom: 0 | Строки наезжают друг на друга | tfoot { position: sticky; bottom: 0; } |
Закрепление подвала при border-collapse: collapse | Верхняя граница пропадает при прокрутке | tfoot th { box-shadow: inset 0 3px 0 #000; } |
Закрепление в обёртке с overflow-x: auto | Подвал не закрепляется при прокрутке страницы | .wrap { max-height: 70vh; overflow: auto; } |
| Итог всей таблицы повторяется на каждой печатной странице | Сумма внизу первой страницы похожа на итог только этой страницы | @media print { tfoot { display: table-row-group; } } |
table.insertRow(-1) для строки данных | Строка попадает в подвал | tbody.insertRow(-1) |
Устаревшие align, valign, bgcolor у tfoot | Атрибуты устарели | Свойства text-align, vertical-align и background |