Чтобы спланировать HTML-таблицу с пересекающимися объединениями, сначала начертите всю сетку, затем задайте для каждой объединённой ячейки прямоугольную область и добавляйте ячейки только в начальных позициях этих областей. В этом руководстве разобран искусственный пример, который можно создать в TextEdit и просмотреть на Mac.
Определите сетку до добавления ячеек
Задача — создать таблицу из пяти столбцов с группированными заголовками столбцов, ячейкой, охватывающей одновременно строки и столбцы, и ещё одной ячейкой, охватывающей другое количество строк. Приведённые ниже подписи и содержимое служат иллюстрацией: они представляют нейтральные блоки узлов, расположенные по слотам.
HTML-таблицы представляют многомерные данные. Их ячейки должны заполнять сетку таблицы без наложений. Если вам нужно лишь расположить на странице несвязанные блоки, стандарт HTML рекомендует использовать средства вёрстки, например CSS Grid. Здесь каждый блок связан по смыслу с заголовками своей строки и столбца, поэтому для этой задачи подходит таблица. Стандарт HTML: элемент table.
Для начала назовите самые мелкие столбцы, которые встречаются в таблице. В этом примере это Slot, Node A, Node B, Node C и Note. Заголовок Nodes охватывает три из них, но не создаёт дополнительный столбец.
Оба атрибута объединения задают полный размер ячейки, включая её начальную позицию. Поэтому colspan="2" охватывает два столбца, а rowspan="2" — две строки. Одновременное применение обоих атрибутов создаёт прямоугольник размером два на два. Если атрибут объединения не указан, его значение по умолчанию равно одному. MDN: элемент ячейки данных таблицы.
«Пересекающиеся» описывает то, как эти прямоугольники стыкуются друг с другом. Отдельная ячейка всё равно занимает прямоугольную область: она не может огибать другую ячейку. Представьте, что вы размещаете подписанные прямоугольники на клетчатой бумаге.
Составьте таблицу занятости слотов для каждой строки
Используйте расширенную планировочную таблицу, где повторяющиеся подписи показывают область одной объединённой ячейки. Повторение в этой таблице не означает, что эту ячейку нужно повторять в HTML. В разделе заголовков будет две строки, в теле таблицы — четыре.
| Планируемая строка | Столбец 1 | Столбец 2 | Столбец 3 | Столбец 4 | Столбец 5 |
|---|---|---|---|---|---|
| Заголовок 1 | Slot | Nodes | Nodes | Nodes | Note |
| Заголовок 2 | Slot | Node A | Node B | Node C | Note |
| Тело 1 | Slot 1 | Block P | Block P | Block Q | Note X |
| Тело 2 | Slot 2 | Block P | Block P | Block R | Note X |
| Тело 3 | Slot 3 | Block S | Block T | Block T | Note X |
| Тело 4 | Slot 4 | Block U | Block U | Block U | Note Y |
Теперь запишите начальную позицию и размеры каждого объединённого прямоугольника. Здесь используются координаты с отсчётом от единицы; в каждом разделе отсчёт начинается заново.
| Ячейка | Начальная позиция | Охвачено строк | Охвачено столбцов |
|---|---|---|---|
| Заголовок Slot | Строка заголовка 1, столбец 1 | 2 | 1 |
| Заголовок Nodes | Строка заголовка 1, столбец 2 | 1 | 3 |
| Заголовок Note | Строка заголовка 1, столбец 5 | 2 | 1 |
| Block P | Строка тела 1, столбец 2 | 2 | 2 |
| Note X | Строка тела 1, столбец 5 | 3 | 1 |
| Block T | Строка тела 3, столбец 3 | 1 | 2 |
| Block U | Строка тела 4, столбец 2 | 1 | 3 |
С этой таблицей занятости сложная вторая строка тела становится понятной: Block P уже занимает столбцы 2 и 3, а Note X — столбец 5. В этой строке начинаются только Slot 2 и Block R, поэтому для неё нужны всего два элемента ячеек.
Для каждой строки выполните следующие действия:
- Отметьте позиции, занятые объединениями, начавшимися в предыдущих строках.
- Найдите первый незанятый столбец.
- Разместите следующую ячейку и отметьте всю занимаемую ею область, включая будущие строки.
- Отклоните прямоугольник, если любая его часть накладывается на занятую позицию.
- Продолжайте, пока не учтёте все пять позиций столбцов.
Эта процедура — вспомогательный способ планирования, основанный на модели таблицы в стандарте. При размещении ячеек браузеры пропускают уже занятые начальные позиции, но авторы всё равно должны избегать наложения прямоугольников. Поэтому одного подсчёта элементов ячеек в строке недостаточно. Стандарт HTML: модель обработки.
Для проверки строки полезно использовать правило: перенесённые из предыдущих строк занятые столбцы + столбцы, охваченные новыми ячейками, = пять. Во второй строке тела три позиции перенесены из предыдущей строки, а две — новые. В третьей строке тела одна позиция перенесена, а четыре — новые. Проверьте также их фактическое расположение: одна лишь верная сумма не выявит сочетание наложения и пропуска.
Спланируйте группы строк и связи заголовков
Поместите обе строки заголовков в один thead, а все четыре строки тела — в один tbody. Ячейка не может охватывать разные группы строк. Например, Block P не может начинаться в одном tbody и заканчиваться в другом. Стандарт также задаёт порядок дочерних элементов таблицы: необязательный caption, группы столбцов, необязательный thead, строки тела и необязательный tfoot. Стандарт HTML: таблицы.
В примере заданы три группы столбцов: один столбец для Slot, три для Nodes и один для Note. Для заголовка Nodes используется scope="colgroup", а для подчинённых ему заголовков — scope="col". В рекомендациях W3C для таблиц с нерегулярными заголовками предлагается сочетать группированные заголовки с явной структурой групп столбцов. Таблицы с нерегулярными заголовками.
Геометрию и смысл нужно определять отдельно. Block P охватывает две строки слотов и два столбца узлов, поэтому его предполагаемые заголовки — Slot 1, Slot 2, Nodes, Node A и Node B. Note X относится к трём строкам слотов и столбцу Note.
В этом примере связи для таких объединённых ячеек данных задаются явно: в заголовках используются значения id, а в атрибуте headers каждой ячейки данных — разделённые пробелами ссылки на них. W3C описывает этот подход для сложных таблиц, где связи с заголовками нужно указывать явно. Таблицы с многоуровневыми заголовками.
Не объединяйте независимые значения только потому, что их текст совпадает. В этом искусственном документе Block P намеренно обозначает один блок, занимающий четыре позиции. Если бы каждая позиция содержала отдельное наблюдение, оставьте эти ячейки раздельными, чтобы сохранить это различие.
Создайте полный HTML-файл на Mac
В TextEdit можно создать локальный HTML-документ. Выберите File > New, затем Format > Make Plain Text. Вставьте полный документ ниже, выберите File > Save и сохраните его под именем span-plan.html. Если появится запрос о расширении файла, выберите Use .html. Эти действия создания HTML-документа описаны в документации Apple. Работа с HTML-документами в TextEdit на Mac.
Это полный автономный документ со встроенными примером содержимого и стилями. Скрипты и внешние ресурсы не требуются.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Interlocking span plan</title>
<style>
body { font-family: system-ui, sans-serif; margin: 2rem; }
table { border-collapse: collapse; }
caption { text-align: left; font-weight: bold; margin-bottom: 1rem; }
th, td { border: 1px solid #555; padding: 0.75rem; text-align: left; }
thead { background: #eee; }
</style>
</head>
<body>
<table>
<caption>Synthetic node blocks by slot</caption>
<colgroup span="1"></colgroup>
<colgroup span="3"></colgroup>
<colgroup span="1"></colgroup>
<thead>
<tr>
<th rowspan="2" scope="col" id="slot">Slot</th>
<th colspan="3" scope="colgroup" id="nodes">Nodes</th>
<th rowspan="2" scope="col" id="note">Note</th>
</tr>
<tr>
<th scope="col" id="a">Node A</th>
<th scope="col" id="b">Node B</th>
<th scope="col" id="c">Node C</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" id="s1">Slot 1</th>
<td rowspan="2" colspan="2" headers="s1 s2 nodes a b">Block P</td>
<td headers="s1 nodes c">Block Q</td>
<td rowspan="3" headers="s1 s2 s3 note">Note X</td>
</tr>
<tr>
<th scope="row" id="s2">Slot 2</th>
<td headers="s2 nodes c">Block R</td>
</tr>
<tr>
<th scope="row" id="s3">Slot 3</th>
<td headers="s3 nodes a">Block S</td>
<td colspan="2" headers="s3 nodes b c">Block T</td>
</tr>
<tr>
<th scope="row" id="s4">Slot 4</th>
<td colspan="3" headers="s4 nodes a b c">Block U</td>
<td headers="s4 note">Note Y</td>
</tr>
</tbody>
</table>
</body>
</html>
Откройте сохранённый файл в браузере на Mac. Сверьте его с таблицей занятости: Block P должен охватывать слоты 1 и 2 в столбцах Nodes A и B; Note X должен охватывать слоты 1–3; Block T должен занимать только столбцы Nodes B и C в слоте 3. Эти три проверки отличают задуманную схему пересекающихся объединений от таблицы, у которой просто прямоугольный контур.
Если при повторном открытии файла в TextEdit отображается форматированное содержимое, выберите File > Open, укажите файл, нажмите Show Options и выберите Ignore rich text commands. Для дальнейшего редактирования Apple также описывает настройки TextEdit > Settings > Open and Save, где можно включить параметр Display HTML files as HTML code instead of formatted text. Руководство Apple по HTML в TextEdit.
Найдите ошибки и обновите план, сохранив структуру
Если результат отличается от плана, проверьте первую строку с ошибкой и области объединений, перенесённые в неё. Перед изменением интервалов или стилей выполните следующие проверки.
| Признак | Что проверить | Исправление для этого примера |
|---|---|---|
| Появился неожиданный дополнительный столбец | Ячейки, добавленные туда, где место уже занимает предыдущее объединение | Во второй строке тела есть только Slot 2 и Block R; удалите из неё все ячейки-заполнители |
| Block R отображается не под тем узлом | Ширину и высоту Block P | Убедитесь, что для Block P заданы оба атрибута: rowspan="2" и colspan="2" |
| Note X заканчивается после Slot 2 | Число охватываемых строк | Задайте объединение на три строки |
| Уровни заголовков не выровнены | Первую строку заголовков и число ячеек во второй строке | Для Slot и Note задайте охват в две строки; во второй строке заголовков должны быть только три заголовка узлов |
| Для объединённой ячейки указаны не все заголовки | Ссылки headers |
Сверьте каждую охваченную строку и столбец с таблицей занятости |
Пустая ячейка уместна, если соответствующая позиция действительно содержит пустое значение. Она не нужна в позиции, уже занятой объединённой ячейкой. В документации MDN о ячейках объясняется, что обычные ячейки размещаются в свободных позициях и что объединения не должны накладываться друг на друга. MDN: элемент ячейки данных таблицы.
Для этого фиксированного примера задавайте явное положительное число строк. Специальное значение rowspan="0" означает оставшиеся строки текущей группы строк, поэтому добавление строки может расширить охват такой ячейки. Используйте это значение, только если подразумеваемая связь действительно означает «до конца этой группы». MDN: поведение объединения строк.
Перед вставкой, удалением или перестановкой строки обновите таблицу занятости. Если между слотами 1 и 2 вставляется новая строка и Block P должен её охватить, увеличьте число объединяемых строк для Block P и добавьте заголовок новой строки в список headers. Отдельно пересмотрите Note X: эта же вставка может изменить предполагаемую область его охвата. Перестановка строк требует такой же проверки, поскольку объединение следует за позицией в документе.
Если содержимое уже не складывается в понятные прямоугольники, упростите его представление. W3C рекомендует рассмотреть вариант с несколькими небольшими таблицами, если из-за нескольких уровней заголовков одну таблицу становится трудно понять. Таблицы с многоуровневыми заголовками.
При редактировании держите таблицу занятости рядом с исходным кодом документа. Для каждого изменения определяйте предполагаемые прямоугольники, добавляйте ячейки только в начальных позициях этих областей и проверяйте связанные заголовки. Так вы сможете последовательно сохранять и форму таблицы, и смысловые связи, которые она выражает.
Источники
- Стандарт HTML — табличные данные — WHATWG.
<td>: элемент ячейки данных таблицы — MDN Web Docs.- Таблицы с нерегулярными заголовками — Инициатива W3C по веб-доступности.
- Таблицы с многоуровневыми заголовками — Инициатива W3C по веб-доступности.
- Работа с HTML-документами в TextEdit на Mac — служба поддержки Apple.