Сортировка таблицы HTML: 5 причин оставить таблицу
Прайс, история заказов, список клиентов: кто-то просит сортировку и фильтр, и ответ обычно «поставим грид-библиотеку». Через полгода таблица становится чёрным ящиком, страница везёт двести килобайт скрипта, а скринридер объявляет div там, где была таблица.
Код: Oat-Table, лицензия MIT.
Сортировка таблицы HTML такого обмена не требует. Oat Table добавляет сортировку, фильтр и выбор строк вокруг элемента <table>, и таблица остаётся таблицей.
Разметка уже несёт смысл
<th scope="col"> говорит скринридеру, к какому столбцу относится ячейка. <time datetime="2026-05-15"> говорит парсеру, что значит видимая дата. Нативный чекбокс в форме отправляет значение без сериализатора.
Грид-библиотека пересобирает всё это на JavaScript, и каждая пересборка что-то теряет: связь заголовка с ячейкой, стили печати, вставку списка в таблицу.
Сортировка это атрибут, а не виджет
<th scope="col" data-sort> делает столбец сортируемым как текст. number или date меняют сравнение, auto определяет тип сам.
Когда видимый текст отформатирован, ячейка несёт значение отдельно: $42,128 сортируется по 42128. Это вся настройка. Ни описаний колонок в отдельном файле, ни функции рендера, ни виртуального DOM.
Скрипт оборачивает текст заголовка в кнопку и обновляет aria-sort, поэтому управление доступно с клавиатуры, а состояние объявляется. Именно этот шаг самописные решения пропускают.
Фильтр скрывает строки, а не перезагружает данные
Поле с data-table-filter сравнивает текст строки и скрывает то, что не подошло. Строка может объявить собственную строку поиска, и тогда «Ada» находит запись, у которой видимый текст начинается с названия компании.
Счётчик попадает в <output aria-live="polite">, поэтому скринридер слышит «12 строк» после каждого нажатия, не теряя фокус.
Выбор строк идёт нативными чекбоксами, и «выбрать все» действует только на видимые строки. Отфильтровали регион, выбрали все, и действие применилось к региону. В библиотеке такое поведение обычно становится багом.
Что видит посетитель на плохой связи
Таблица есть в HTML, поэтому она отрисовывается раньше, чем разбирается скрипт, и работает, если скрипт не загрузился. На телефоне с одной полоской сигнала эта разница решает, пригоден ли список.
Прогрессивное улучшение это ещё и стратегия тестирования: у страницы есть состояние без JavaScript, поэтому сломанный бандл даёт деградировавшую страницу, а не пустую.
Как проверить откат
Выключите JavaScript и загрузите страницу. Таблица должна отрисоваться, напечататься и находиться поиском по странице. Потом заблокируйте запрос скрипта и повторите: страница, которая теряет содержимое из-за одного файла, имеет единственную точку отказа посреди релиза.
Сколько это стоит
Одна таблица стилей, один скрипт, никаких зависимостей в рантайме и разметка, которую вы написали бы и так. Для проекта по 30–50 $ в час экономия не в загрузке, а в неделе связывания, которая не попадает в счёт.
Где библиотека всё равно выигрывает
Правка ячеек на месте, виртуализация на десять тысяч строк, сводные таблицы, перетаскивание колонок, выгрузка с оформлением. Это функции продукта, а не украшение таблицы, и там библиотека отрабатывает свой вес.
Что проверить перед выбором
Посчитайте строки в реальном документе и посмотрите, есть ли в таблице правка ячеек или сводные итоги. Если нет ни того ни другого, библиотека добавляет вес без функции.
Потом откройте страницу с выключенным JavaScript. Список, который без скрипта превращается в пустое место, стоит дороже, чем кажется: он пропадает у части посетителей и на части релизов.
Если таблица нужна только для чтения, сортировка по клику часто не нужна вовсе: достаточно ссылки на отсортированный адрес, и такой адрес живёт в закладках.
Прайс на сорок строк таким продуктом не является. Нативная таблица означает, что следующий разработчик прочитает страницу, не открывая документацию.
Рядом: веб-разработка о том, как считается объём фронтенда, и SEO о том, что содержимое таблицы даёт поиску. Если страницу читает переведённая аудитория, эту проверку закрывает читаемость текста.
