На хабре вышла статья про отрисовку таблиц при помощи Symbiote.js. Это фреймворк, который базируются на веб-стандартах и активно использует API веб-компонентов. За это авторам отдельный респект, потому что мне нравится идея максимально близких к платформе инструментов, полагающихся на стандарты.
В статье описывается работа с таблицами при помощи этого фреймворка. Всё бы хорошо, но приводятся примеры итоговой сгенерированной разметки:
<my-table>Этот фрагмент разметки не является валидным. Дело в том, что по спецификации внутри
<table>
<table-row>
<td>Row number: 1</td>
<td>Date: 1714405915233</td>
</table-row>
<table-row>
<td>Row number: 2</td>
<td>Date: 1714405915233</td>
</table-row>
<table-row>
<td>Row number: 3</td>
<td>Date: 1714405915233</td>
</table-row>
</table>
</my-table>
<table> разрешено вкладывать только <caption>, <colgroup>, <thead>, <tbody>, <tfoot>, <tr>, <script> и <template>. Причём не просто вкладывать в произвольно порядке, а по определённым правилам.В примере кода из статьи внутрь
<table> вкладываются кастомные элементы <table-row>, что недопустимо. На этом этапе валидатор бросает критическую ошибку и прекращает дальнейший разбор разметки.Фреймворк добавляет таким элементам свойство
display: contents, которое делает кастомный элемент "прозрачным" при построении раскладки и не учитывает его. Но физически элемент всё равно остаётся в DOM и AOM, поэтому свойство проблему не решает.Чем такая невалидная разметка чревата? Страница будет невалидной, валидатор не сможет полностью проверить страницу, ассистивные технологии, парсеры и поисковые роботы не распознают данные из таблицы, перестанут работать API-методы таблиц (добавление строк, получение данных и т.д.).
Как в этой ситуации поступить? Раз инструмент полагается на кастомные элементы, то всю таблицу стоит делать при помощи них и добавлять дополнительную семантику при помощи ARIA-атрибутов как рекомендуется в WAI-ARIA практиках для таблиц.
<my-table role="table" aria-rowcount="3" aria-colcount="2">
<table-row role="row">
<table-cell role="rowheader">Row number: 1</table-cell>
<table-cell role="cell">Date: 1714405915233</table-cell>
</table-row>
<table-row role="row">
<table-cell role="rowheader">Row number: 2</table-cell>
<table-cell role="cell">Date: 1714405915233</table-cell>
</table-row>
<table-row role="row">
<table-cell role="rowheader">Row number: 3</table-cell>
<table-cell role="cell">Date: 1714405915233</table-cell>
</table-row>
</my-table>