Тег td в HTML: ячейка таблицы, colspan, размеры и выравнивание

Тег td (от английского table data, «данные таблицы») создаёт ячейку: одну клетку на пересечении строки и колонки. В ячейку записывают всё, что допустимо в обычном потоке страницы: текст, абзацы, списки, формы, картинки и даже вложенную таблицу. Заголовки колонок и строк задаёт th, а td несёт сами данные.

В уроке «Строки tr и ячейки td» показано, как ячейки складываются в строки и в сетку. Здесь разберём пределы и подводные камни: до скольких можно растянуть colspan и rowspan, какие атрибуты ячейки устарели, а какие остались рабочими, почему ячейка получается шире заданной ширины, что делать с длинным словом и многоточием, как ведут себя пустые и скрытые ячейки, как посчитать колонку и закрепить её при прокрутке.

HTML
<table>
  <tr>
    <td>Сенча</td>
    <td>100</td>
    <td colspan="2">50 г</td>
  </tr>
</table>

Тег td в HTML: что это и что записывают внутри

Ячейка td записывается только внутри строки tr. Если записать её прямо в table, валидатор Nu сообщит об ошибке, а браузер сам создаст вокруг ячейки tbody и tr. Какие ещё теги браузер достраивает вокруг ячеек, описано на странице tr. Закрывающий </td> можно опустить: ячейка кончается там, где начинается следующая или закрывается строка.

Внутри допустимы абзацы, списки, формы, заголовки, другие таблицы. Пустая ячейка тоже допустима и остаётся ячейкой: она занимает место в сетке. Ссылка, записанная в ячейке, по умолчанию занимает только свой текст, а не всю ячейку; чтобы ссылка закрыла ячейку, ячейке убирают отступы, а ссылке задают display: block и свои отступы. Если соседняя ячейка строки выше, ссылка закроет ячейку по всей ширине, а по высоте только свою часть.

ЗаписьЧто получаетсяПример записи
Текст в tdЯчейка с данными<td>100</td>
Абзацы и спискиДопустимы: ячейка вытягивается по содержимому<td><p>Чай</p><ul>...</ul></td>
Вложенная tableДопустима: полная таблица внутри ячейки<td><table>...</table></td>
Форма или inputДопустимы: поле стоит в ячейке<td><input type="text"></td>
Пустая ячейкаДопустима: остаётся местом в сетке<td></td>
td прямо в tableБраузер создаёт tbody и tr, валидатор считает ошибкой<table><td>100</td></table>

Пример: что записывают внутри ячейки

Результат

Выберите содержимое: вверху виден код, под ним — что получилось на экране.

Допустимые места и содержимое перечислены в описании элемента в стандарте HTML.

Объединение ячеек td: пределы colspan и rowspan

Атрибут colspan растягивает ячейку по колонкам, rowspan — по строкам. Основы разобраны в уроке про объединение ячеек, а здесь разберём границы значений. У colspan допустимы числа от 1 до 1000, у rowspan — от 0 до 65534. Недопустимое значение браузер исправляет молча, а валидатор Nu считает его ошибкой.

Значения 0, отрицательные числа и слова у colspan превращаются в 1, дробное 2.7 обрезается до 2, а 1001 — до 1000. У rowspan значение 0 допустимо и растягивает ячейку до конца секции (thead, tbody или tfoot), 70000 превращается в 65534. За пределы секции ячейка не выходит: в таблице с шапкой и телом объединение обрезается по границе секции.

ЗаписьЧто получаетсяПример записи
colspan 2Ячейка занимает две колонки<td colspan="2">Скидка</td>
colspan больше числа колонокПоявляются лишние колонки без ширины, валидатор считает ошибкой<td colspan="5">Скидка</td>
colspan="0"Браузер читает как 1, валидатор считает ошибкой<td colspan="0">Скидка</td>
rowspan 2Ячейка занимает две строки<td rowspan="2">Чай</td>
Лишняя ячейка в строке под rowspanТаблица получает лишнюю колонку<tr><td>1</td><td>2</td><td>3</td></tr>
rowspan="0"Ячейка тянется до конца секции, валидатор не возражает<td rowspan="0">Чай</td>
rowspan за пределы секцииОбъединение обрезается, валидатор считает ошибкой<td rowspan="9">Чай</td>

Пример: пределы colspan и rowspan

Результат

Выберите запись: вверху виден код, под ним — что получилось и что сказал бы валидатор.

Атрибуты td: что устарело и как работает headers

У ячейки три рабочих атрибута: colspan, rowspan и headers. Остальные устарели: Chrome их выполняет, а валидатор Nu выдаёт предупреждение. Это width, height, align, valign, bgcolor, nowrap, background, abbr, axis, char и charoff. Правило CSS перебивает устаревший атрибут, поэтому при переходе на стили вёрстка не ломается.

Атрибут headers нужен сложным таблицам, где заголовок нельзя определить по положению ячейки. В нём перечисляют через пробел значения id ячеек th, к которым относится данная ячейка: скринридер читает их вместе с данными. Ссылка на несуществующий id или на ячейку td считается ошибкой. Для обычных таблиц хватает scope у th: у td этот атрибут устарел.

АтрибутЧто получаетсяПример записи
width, heightУстарели: размеры применяются, валидатор предупреждаетСвойства width и height
alignУстарел: выравнивает текст, валидатор предупреждаетСвойство text-align
valignУстарел: выравнивает по вертикали, валидатор предупреждаетСвойство vertical-align
bgcolor, backgroundУстарели: красят фон, валидатор предупреждаетСвойство background
nowrapУстарел: запрещает перенос, валидатор предупреждаетtd { white-space: nowrap; }
abbr, axis, char, charoff, scopeУстарели у td, валидатор предупреждаетУбрать атрибут
headersРабочий: связывает ячейку с заголовками th<td headers="chay cena">100</td>
headers на несуществующий idВалидатор считает ошибкой<td headers="net">100</td>

Пример: устаревшие атрибуты и их замена

Результат

Выберите атрибут: вверху виден код, под ним — что сделал браузер.

HTML
<table>
  <tr>
    <th id="chay">Чай</th>
    <th id="cena">Цена</th>
  </tr>
  <tr>
    <td headers="chay">Сенча</td>
    <td headers="cena">100</td>
  </tr>
</table>
CSS
td {
  width: 110px;
  height: 40px;
  text-align: center;
  vertical-align: top;
  background: #ffd9a8;
  white-space: nowrap;
}

Ширина и высота td: content-box, длинное слово и многоточие

Ширина и высота ячейки считаются как у обычного блока: content-box, то есть отступы и рамки добавляются сверху. Ячейка с width: 100px, отступами по 10 px и рамкой по 1 px получается шириной 122 px. Если нужно, чтобы заданная ширина включала отступы, добавляют box-sizing: border-box. Внешние отступы margin у ячейки не действуют. Поведение max-width и min-width у ячеек стандарт CSS 2.1 не определяет, а Chrome их учитывает.

Ширина одной ячейки задаёт ширину всей колонки: ячейки других строк в этой колонке получают такую же ширину. Подробнее о ширине колонок — на странице col. Высота ячейки задаёт минимум для строки. Длинное слово без пробелов растягивает колонку: overflow-wrap: break-word минимальную ширину ячейки не уменьшает, а overflow-wrap: anywhere и word-break: break-all уменьшают.

ЗаписьЧто получаетсяПример записи
width с отступамиЯчейка шире заданной на сумму отступов и рамокtd { width: 100px; padding: 10px; }
box-sizing: border-boxЗаданная ширина включает отступы и рамкиtd { box-sizing: border-box; }
width у одной ячейкиЗадаёт ширину всей колонкиtd:first-child { width: 150px; }
margin у ячейкиНе действуетtd { margin: 10px; }
Длинное словоРастягивает колонку и таблицу<td>ВсёОдним...</td>
overflow-wrap: break-wordСлово по-прежнему растягивает колонкуtd { overflow-wrap: break-word; }
overflow-wrap: anywhereСлово переносится по буквамtd { overflow-wrap: anywhere; }
Многоточие без max-widthНе срабатывает: ячейка растягивается по текстуtd { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
Многоточие с max-width: 0В Chrome срабатывает: текст обрезаетсяtd { max-width: 0; } к тем же свойствам

Пример: ширина, длинное слово и многоточие

Результат

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

Многоточие начинает работать и при table-layout: fixed у таблицы: ширина колонок тогда не зависит от содержимого.

CSS
td {
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

Выравнивание, пустые и скрытые ячейки td

По вертикали ячейка по умолчанию выравнивает содержимое по середине: vertical-align: middle. Значения top и bottom прижимают текст к верху или низу, baseline выравнивает первые строки всех ячеек строки по общей базовой линии. Свойство vertical-align действует на ячейке, а не на тексте внутри неё, и наследуется от строки и секции, как описано на странице tr. По горизонтали работает text-align.

Пустая ячейка, которая должна выглядеть пустой, получает empty-cells: hide: скрываются её рамка и фон. Свойство действует только при border-collapse: separate, а при collapse игнорируется. Пробел и комментарий внутри ячейки пустоту не нарушают, а неразрывный пробел нарушает.

Скрывать ячейку надо с оглядкой. Если у одной td задать display: none, она выпадает из сетки строки, и остальные ячейки строки сдвигаются влево, а колонка рассыпается. Без сдвига ячейку скрывает visibility: hidden: место остаётся. Всю колонку скрывают display: none у ячеек всех строк.

ЗаписьЧто получаетсяПример записи
vertical-align: topТекст прижат к верху ячейкиtd { vertical-align: top; }
vertical-align: middleТекст по середине: так по умолчаниюtd { vertical-align: middle; }
vertical-align: bottomТекст прижат к низу ячейкиtd { vertical-align: bottom; }
empty-cells: hideПустая ячейка без рамки и фона, если нет collapsetd { empty-cells: hide; }
display: none у одной ячейкиКолонка рассыпаетсяtd:nth-child(2) { display: none; }
display: none у всей колонкиКолонка исчезает, сетка ровнаяtd:nth-child(2) { display: none; }
visibility: hiddenЯчейка невидима, место остаётсяtd { visibility: hidden; }

Пример: выравнивание, пустые и скрытые ячейки

Результат

Выберите правило и при желании включите border-collapse: collapse: результат виден сразу.

Колонка таблицы и ячейки td: nth-child и colspan

В таблице нет элемента «колонка», по которому можно было бы выбрать все ячейки: колонку собирают из ячеек строк. Селектор td:nth-child(2) берёт вторую ячейку каждой строки, и пока строки одинаковой длины, это вторая колонка. Как только в одной строке есть ячейка с colspan, счёт сбивается: вторая ячейка строки оказывается уже в третьей колонке.

Правильно посчитать колонку может скрипт: он складывает значения colSpan ячеек строки и сравнивает сумму с номером колонки. Для первой и последней ячейки строки хватает td:first-child и td:last-child, если число ячеек в строках одинаково.

ЗаписьЧто получаетсяПример записи
td:nth-child(2)Вторая ячейка каждой строкиtd:nth-child(2) { ... }
td:nth-child(2) при colspanКрасит ячейку не из той колонки<td colspan="2">Акция</td>
Скрипт с суммой colSpanНаходит ячейки нужной колонкиcol += cell.colSpan;
td:first-child, td:last-childПервая и последняя ячейки строкиtd:last-child { text-align: right; }

Пример: счёт колонки

Результат

Выберите способ: вверху виден код, под ним таблица. Во второй строке ячейка объединяет две колонки.

Закрепление колонки td при горизонтальной прокрутке

Первую колонку закрепляют при горизонтальной прокрутке таблицы: ячейкам колонки задают position: sticky и left: 0, а таблицу оборачивают в блок с overflow-x: auto. Без фона закреплённая колонка просвечивает: прокручиваемые ячейки видны сквозь неё. Закрепление шапки при вертикальной прокрутке описано на странице thead, а подвала — на странице tfoot.

Есть и отдельная ловушка с границей. При border-collapse: collapse граница закреплённой ячейки не остаётся на месте и пропадает. Полосу справа от колонки рисуют через box-shadow: inset -3px 0 0 цвет: тень остаётся при любом режиме границ.

ЗаписьЧто получаетсяПример записи
Без правилКолонка уезжает за левый край блокаtd:first-child { }
position: sticky; left: 0Колонка закреплена, но просвечиваетtd:first-child { position: sticky; left: 0; }
Закрепление и фонКолонка закреплена и закрывает остальныеtd:first-child { background: #fff7d6; }
border-right при collapseГраница пропадаетtd:first-child { border-right: 3px solid; }
box-shadow: insetПолоса справа остаётсяtd:first-child { box-shadow: inset -3px 0 0 #c0292e; }

Пример: закреплённая первая колонка

Результат

Выберите правило: вверху виден код, под ним блок с прокруткой, уже сдвинутый вправо.

CSS
.scroll {
  overflow-x: auto;
}
td:first-child {
  position: sticky;
  left: 0;
  background: #fff7d6;
  box-shadow: inset -3px 0 0 #c0292e;
}

Тег td и JavaScript: cellIndex, colSpan и closest

Ячейка в скрипте представлена интерфейсом HTMLTableCellElement, общим для td и th. Ячейки строки возвращает свойство cells, о нём подробнее на странице tr. Свойство cellIndex возвращает номер ячейки в строке, а не номер колонки: при colspan эти числа расходятся. Свойства colSpan и rowSpan читают и записывают числа, headers возвращает строку с id.

Запись colSpan = 0 оставляет в атрибуте 0, а при чтении возвращает 1. Запись rowSpan = 70000 возвращает 65534. Обращение row.cells[1] во всех строках цикла ломается на строке с одной ячейкой: на месте второй ячейки undefined, а textContent у него вызывает ошибку.

ЗаписьЧто делаетПример записи
cell.cellIndexВозвращает номер ячейки в строке, не номер колонкиcell.cellIndex
cell.colSpan = 3Растягивает ячейку на три колонкиcell.colSpan = 3
cell.colSpan = 0В атрибуте 0, при чтении 1cell.colSpan = 0
row.cells[1]Вторая ячейка строки, у короткой строки undefinedrow.cells[1]
e.target.closest("td, th")Находит ячейку, в которой произошёл кликe.target.closest("td, th")
row.insertCell(-1)Добавляет в конец строки ячейку tdrow.insertCell(-1)

Пример: свойства ячейки

Результат

Выберите действие: вверху виден код, под ним таблица и результат, который считает сама страница.

JavaScript
table.addEventListener('click', (event) => {
  const cell = event.target.closest('td, th');
  if (!cell || !table.contains(cell)) return;
  console.log(cell.cellIndex, cell.colSpan, cell.textContent);
});

Частые ошибки с тегом td

Типичные ошибки с ячейками и как их исправить.

ОшибкаЧто происходитКак исправить
colspan="0" или слово в colspanБраузер читает как 1, валидатор считает ошибкойПисать число от 1 до 1000
colspan больше числа колонокЛишние колонки без ширины, валидатор считает ошибкойСчитать колонки по самой длинной строке
rowspan за пределы секцииОбъединение обрезается, валидатор считает ошибкойОбъединять строки в пределах одной секции
Лишняя ячейка в строке под rowspanТаблица получает лишнюю колонкуУбрать ячейку, которую закрывает объединение
Атрибуты width, height, align, valign, bgcolorУстарели, валидатор предупреждаетСвойства width, height, text-align, vertical-align, background
headers на несуществующий id или на tdВалидатор считает ошибкойСсылаться на id существующих th
td прямо в tableБраузер достраивает tbody и tr, валидатор считает ошибкойЗаписывать td в tr
width с отступамиЯчейка шире заданнойbox-sizing: border-box
margin у ячейкиНе действуетОтступы задавать через padding или border-spacing
Длинное слово и break-wordКолонка по-прежнему растянутаoverflow-wrap: anywhere
Многоточие без max-widthТекст не обрезаетсяmax-width: 0
empty-cells: hide при collapseРамка пустой ячейки виднаИспользовать border-collapse: separate
display: none у одной ячейкиКолонка рассыпаетсяvisibility: hidden
td:nth-child() в строке с colspanКрасит ячейку не той колонкиСчитать колонку в скрипте по colSpan
Граница закреплённой колонки при collapseГраница пропадаетbox-shadow: inset -3px 0 0 #c0292e
Закреплённая колонка без фонаЯчейки просвечиваютЗадать ячейкам фон
cellIndex как номер колонкиПри colspan числа расходятсяСкладывать значения colSpan
row.cells[1] в строке с одной ячейкойВозвращает undefinedПроверять длину row.cells
Категория
Поделиться в социальных сетях

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

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×