SST - Единый стандарт для таблиц

SST - Единый стандарт для таблиц
Стандарты

32

7 мин.

Определения

Стандарт SST определяет требования к семантике, доступности и логике работы таблиц.

Структура и семантика

Основные элементы таблицы

  • Если таблице требуется название или краткое описание, оно задаётся элементом <caption>. При наличии <caption> размещается первым элементом внутри <table>. Подпись помогает понять назначение таблицы, но сама по себе не гарантирует улучшения SEO.
  • <thead> объединяет строки с заголовками столбцов. В постраничной печати браузер или генератор документа может повторять эту группу; фактическое поведение зависит от движка печати и настроек разбиения страниц.
  • Один или несколько <tbody> объединяют строки данных. Несколько групп <tbody> применяются, когда строки разделены на логические блоки. В таблице используется не более одной секции <thead> и одной <tfoot>.
  • <tfoot> содержит итоговые или сводные строки. В текущей модели HTML его размещают после групп строк таблицы; CSS отображает его как группу нижнего колонтитула таблицы. Старые примеры с <tfoot> перед <tbody> не следует считать актуальным правилом разметки.
  • <tr> задаёт строку, <th> — ячейку-заголовок, <td> — ячейку данных. Элементы <th> и <td> должны соответствовать реальной роли содержимого, а не только нужному визуальному стилю.

Группы столбцов

  • <colgroup> обозначает группу столбцов и располагается после <caption> и до групп строк.
  • <col> описывает один или несколько столбцов внутри <colgroup>. Атрибут span задаёт количество столбцов, охватываемых элементом.
  • Если <colgroup> содержит элементы <col>, для количества столбцов задаётся span у <col>. Альтернативный вариант — указать span непосредственно у пустого <colgroup> без дочерних <col>.
  • Через <col> и <colgroup> удобно задавать ширину и фон столбцов. Набор применимых к ним CSS-свойств ограничен: например, text-align и padding на <col> не выравнивают текст и не задают внутренние отступы ячеек.
  • Фон столбца рисуется под фоном строк и ячеек. Если у <th> или <td> задан непрозрачный фон, цвет <col> может быть не виден. Границы столбцов через <col> отображаются только в модели схлопнутых границ.

Доступность

Заголовки и связи ячеек

  • В простой таблице заголовки столбцов задаются через <th scope="col">, а заголовок строки — через <th scope="row">. Атрибут scope связывает ячейку-заголовок с относящимися к ней данными.
  • Для заголовков, охватывающих группу строк или столбцов, применяются scope="rowgroup" и scope="colgroup", если структура таблицы соответствует этим группам.
  • В сложных таблицах с многоуровневыми или несмежными заголовками одной модели scope может быть недостаточно. Связи между заголовками и ячейками данных задаются явно с помощью уникальных id у <th> и соответствующих значений headers у <td>.
  • Визуального выделения недостаточно для программного определения связи заголовка и данных. Структуру таблицы необходимо проверять со вспомогательными технологиями.

Пример простых заголовков строк и столбцов:

<table>
  <caption>Участники проекта</caption>
  <thead>
    <tr>
      <th scope="col">Поле</th>
      <th scope="col">Значение</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Имя пользователя</th>
      <td>Алексей</td>
    </tr>
  </tbody>
</table>

Стилизация и модель таблицы

Отступы, границы и пустые ячейки

  • Внутренние отступы задаются ячейкам <th> и <td>. padding на строке <tr> не управляет отступами её ячеек.
  • border-collapse: collapse объединяет соседние границы ячеек в общую сетку. При border-collapse: separate границы и промежутки между ними обрабатываются раздельно.
  • empty-cells: show и empty-cells: hide управляют отображением границ и фона пустых ячеек только в модели border-collapse: separate. Это свойство не удаляет ячейку из таблицы и не определяет значение отсутствующих данных.
  • Для отсутствующего значения указывается понятное содержимое или состояние, если оно важно для интерпретации данных. Пустая ячейка не должна создавать неоднозначность.

Сохранение табличной модели

  • Элементы <table>, <tr>, <th> и <td> сохраняют нативную табличную модель отображения, когда содержимое действительно представляет строки и столбцы.
  • Замена display строки таблицы на flex или grid меняет алгоритм раскладки: ячейки такой строки перестают участвовать в общей сетке таблицы, поэтому столбцы разных строк могут перестать выравниваться.
  • Для адаптации таблицы сначала настраивается её нативная ширина, перенос содержимого и прокрутка контейнера. Перестроение данных в карточки допустимо как отдельное представление, если сохраняются доступные связи заголовков и понятный порядок чтения.

Выравнивание данных

  • Выравнивание задаётся явно через CSS, а не предполагается по стилям браузера по умолчанию.
  • Текстовые значения обычно выравниваются по началу строки, числовые — по её концу, чтобы облегчить сравнение величин. Для поддержки RTL используется логическое выравнивание, например text-align: start и text-align: end, вместо безусловных left и right.
  • Если важно сравнивать числа по десятичному разделителю, применяется отдельная разметка или форматирование, учитывающее используемую локаль.

Фиксированная раскладка столбцов

  • table-layout: fixed подходит, когда требуется более предсказуемое распределение ширины столбцов и задана ширина самой таблицы, отличная от auto.
  • При фиксированном алгоритме ширина столбцов определяется заданными ширинами <col>, затем ширинами ячеек первой строки; оставшееся пространство распределяется между остальными столбцами.
  • Алгоритм меньше зависит от содержимого всех ячеек и может упростить раскладку, но не гарантирует ускорения в каждом интерфейсе. Длинное содержимое при этом может переноситься, переполнять ячейку или требовать отдельной обработки.

Адаптивность и прокрутка

  • Если таблица не помещается в доступную ширину без потери читаемости, горизонтальная прокрутка ограничивается отдельным контейнером с overflow-x: auto. Ширина контейнера должна быть ограничена шириной родительской области.
  • Элемент <table> сохраняет нативное табличное отображение. display: block не используется как замена контейнеру переполнения: изменение типа отображения может нарушить алгоритм раскладки строк и общих столбцов.
  • Возможность горизонтальной прокрутки должна оставаться обнаружимой и доступной с клавиатуры. Для отдельно прокручиваемой области задаются понятное доступное имя, видимый фокус и клавиатурная фокусируемость, если она не обеспечивается браузером и содержимым области.
  • -webkit-overflow-scrolling: touch не требуется считать базовым условием ускоренной прокрутки в iOS и iPadOS 13 и новее. На iPhone свойство может создавать контекст наложения; его оставляют только при подтверждённой необходимости для старых целевых систем и после проверки побочных эффектов.
  • При узком экране проверяется не только прокрутка, но и доступность всех столбцов, заголовков, значений и фокусируемых элементов внутри ячеек.

Пример прокручиваемого контейнера:

<div
  class="table-scroll"
  role="region"
  aria-label="Сводка продаж по месяцам"
  tabindex="0"
>
  <table class="data-table data-table--wide">
    <caption>Сводка продаж по месяцам</caption>
    <colgroup>
      <col class="data-table__month">
      <col span="2" class="data-table__metrics">
    </colgroup>
    <thead>
      <tr>
        <th scope="col">Месяц</th>
        <th scope="col">Заказы</th>
        <th scope="col">Выручка</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th scope="row">Январь</th>
        <td>120</td>
        <td>360 000 ₽</td>
      </tr>
      <tr>
        <th scope="row">Февраль</th>
        <td>145</td>
        <td>435 000 ₽</td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <th scope="row">Итого</th>
        <td>265</td>
        <td>795 000 ₽</td>
      </tr>
    </tfoot>
  </table>
</div>
.table-scroll {
  max-width: 100%;
  overflow-x: auto;
}

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

.data-table--fixed {
  table-layout: fixed;
}

.data-table--separate {
  border-collapse: separate;
  empty-cells: hide;
}

.data-table--wide {
  min-width: 42rem;
}

.data-table__month {
  width: 40%;
}

.data-table__metrics {
  background-color: #f5f5f5;
}

.data-table th,
.data-table td {
  padding: 0.75rem;
  border: 1px solid #ccc;
}

.data-table th {
  text-align: start;
}

.data-table td {
  text-align: end;
}

.table-scroll:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

Класс data-table--wide применяется только когда столбцам нужна заданная минимальная ширина; значение 42rem в примере подбирается под содержимое. Фон, заданный через <col>, виден, пока его не перекрывает фон ячеек или строк.

Дополнительные состояния

Липкая шапка

  • Для длинной таблицы заголовки могут оставаться видимыми при вертикальной прокрутке с помощью position: sticky на ячейках <th> внутри <thead>.
  • Для липких ячеек задаются смещение, фон и при необходимости z-index; иначе содержимое строк может просвечивать или перекрывать заголовки.
  • position: sticky ограничивается ближайшим scroll-контейнером. При сочетании липкой шапки с горизонтально прокручиваемой областью проверяется поведение и при вертикальной прокрутке страницы, и внутри контейнера.

Пример липких заголовков:

.data-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background-color: #fff;
}

Шапка и печать

  • <thead> сохраняет семантическую группу заголовков. Печатные и PDF-движки могут повторять её при разбиении длинной таблицы на страницы, но результат проверяется в целевой среде печати.

Тестирование

  • Проверяется соответствие структуры таблицы типу данных и порядок элементов: caption, colgroup, thead, группы tbody и tfoot.
  • Каждая строка и столбец имеют понятные заголовки; связи scope либо id/headers проверяются со скринридером.
  • Проверяются таблицы с несколькими <tbody>, объединёнными ячейками и многоуровневыми заголовками, если такие случаи предусмотрены.
  • На узких экранах проверяются горизонтальная прокрутка, возможность клавиатурного доступа и отсутствие горизонтального переполнения всей страницы.
  • Проверяются отображение длинного содержимого при table-layout: fixed, фокус и слои липкой шапки, если они используются.
  • Пустые ячейки проверяются при фактическом значении border-collapse; пустое значение не должно менять смысл данных.
  • Проверяются печатный вид и повторение заголовков в целевых браузерах и генераторах PDF.

Итоговый чек-лист SST

КатегорияОсновные элементыНазначение
Семантикаcaption, thead, tbody, tfoot, tr, th, tdПередача структуры и роли данных
Столбцыcolgroup, col, spanЗадание групп и ограниченного набора стилей столбцов
Доступностьscope, id, headersСвязь заголовков с ячейками данных
СтилизацияОтступы ячеек, границы, empty-cellsПредсказуемое оформление табличной сетки
Раскладкаtable-layout, логическое выравниваниеУправление шириной и сопоставимостью значений
АдаптивностьКонтейнер overflow-x: autoДоступ к широкой таблице без переполнения страницы
Дополнительные состоянияSticky-заголовки, печатьЧитаемость длинных таблиц в целевых средах

Похожие статьи

  • Анатомия React компонента

    Моё видение того, как должен выглядеть React компонент

    421

    7 мин.

  • SST-A - Единый стандарт для табов

    Стандарт SST-A определяет требования к семантике, доступности и логике работы табов

    62

    6 мин.

  • SSF-U - Единый стандарт для фуллскрина

    Стандарт SSF-U определяет требования к семантике, доступности и логике работы фуллскрина

    248

    2 мин.

  • SSA - Единый стандарт для аккордеона

    Стандарт SSA определяет требования к семантике, доступности и логике работы аккордеона

    258

    2 мин.

  • Bad Practices для сайтов

    Разбор критических ошибок веб-дизайна. Почему слайдеры, автоплей и тяжёлые страницы снижают конверсию и позиции в Google и Yandex

    232

    1 мин.

  • SSP - Единый стандарт для пагинации

    Стандарт SSP определяет требования к семантике, доступности и логике работы пагинации

    240

    1 мин.

  • Все статьи

Свяжитесь со мной