Старый добрый тег <table> — наиболее семантический HTML для отображения табличных данных. Но мне очень сложно контролировать то, как представлена таблица, особенно ширину столбцов в динамической среде, где вы можете не знать, сколько контента помещается в каждую ячейку таблицы. В некоторых случаях одна колонка очень широкая, а другие сжаты. В других случаях мы получаем одинаковую ширину, но за счет столбца, который содержит больше содержимого и требует больше места.
Но нашелся обходной путь CSS-трюков, который помогает немного упростить задачу. Это то, что я хочу показать вам в этой статье.
Проблема
Сначала нам нужно понять, как макет обрабатывается браузером. У нас есть свойство table-layout в CSS, чтобы определить, как таблица должна распределять ширину для каждого столбца таблицы. Он принимает одно из двух значений:
- auto (default)
- fixed
Давайте начнем с таблицы, не определяя ширину ее столбцов. Другими словами, мы позволим браузеру решить, какую ширину дать каждому столбцу, применив к нему table-layout: auto в CSS. Как вы заметите, браузер делает все возможное с алгоритмом, который он должен разделить на всю доступную ширину между каждым столбцом.
https://codepen.io/apdrsn/pen/KKqZgZE
Если мы заменим автоматический макет таблицы на table-layout: fixed, тогда браузер просто разделит все доступное пространство на общее количество столбцов, а затем применит это значение в качестве ширины для каждого столбца:
https://codepen.io/apdrsn/pen/xxrpEaE
Но что, если мы хотим контролировать ширину наших столбцов? У нас есть элемент <colgroup>, чтобы помочь! Он состоит из отдельных элементов <col>, которые мы можем использовать для указания точной ширины, необходимой для каждого столбца. Давайте посмотрим, как это работает с table-layout: auto:
https://codepen.io/apdrsn/pen/GREyNye
Браузер не учитывает встроенную ширину, поскольку при добавлении она превышает объем доступного табличного пространства. В результате таблица занимает место у столбцов, так что все столбцы видны. Это совершенно нормальное поведение по умолчанию.
Как <colgroup> работает с table-layout: fixed? Давайте узнаем:
https://codepen.io/apdrsn/pen/MWorbLm
Выглядит совсе не хорошо. Нам нужно, чтобы столбец с кучей контента немного изгибался, сохраняя при этом фиксированную ширину для остальных столбцов. Фиксированное значение table-layout учитывает ширину, но настолько, что поглощает пространство столбца, которому требуется больше всего места… что нам не подходит.
Это можно было бы легко решить, если бы мы могли установить для столбца min-width вместо ширины. Таким образом, столбец будет говорить: «Я могу дать всем вам часть своей ширины, пока мы не достигнем этого минимального значения». Тогда таблица просто переполнит свой контейнер и предоставит пользователю горизонтальную прокрутку, чтобы отобразить остальную часть таблицы. Но, к сожалению, min-width столбцов таблицы не учитывается элементом <col>.
Решение
Решение состоит в том, чтобы подделать min-width, и нам нужно проявить немного творчества, чтобы сделать это.
Мы можем добавить пустой <col> в качестве второго столбца для нашего <colgroup> в HTML и применить атрибут colspan к первому столбцу, чтобы первый столбец занимал место для обоих столбцов:
Хитрость заключается в отношенияx между первым <col> и пустым вторым <col>. Если мы применим ширину к первому столбцу (это 200px во фрагменте выше), то второй столбец будет съеден, когда фиксированный макет таблицы разделит доступное пространство для распределения по столбцам. Но ширина первого столбца (200px) соблюдается и остается на месте.
Вуаля! У нас есть искусственная min-width, установленная в ячейке таблицы. Первая ячейка изгибается по мере изменения доступного пространства, и таблица переполняется для горизонтальной прокрутки, как мы и надеялись.
https://codepen.io/apdrsn/pen/BaZJyLr
(Добавлено немного position: sticky к первому столбцу)
Специальные возможности
Давайте не будем полностью забывать о доступности здесь. Я прогнал таблицу через NVDA в Windows и VoiceOver в macOS и обнаружил, что объявляются все пять столбцов, даже если мы используем только четыре из них. И когда первый столбец находится в фокусе, он объявляет: «Столбцы с первого по второй». Не совсем элегантно, но и не заставит кого-то заблудиться. Я предполагаю, что мы могли бы добавить атрибут aria-hidden в неиспользуемый столбец, но я также знаю, что ARIA не заменит плохой HTML.
Я признаю, что это выглядит немного, xм, банально. Но это действительно работает! Дайте мне знать, если у вас есть другой подход в комментариях… или знать о каких-либо недоразумениях, которые этот “хак” может вызвать у наших пользователей.
Перевод статьи Faking Min Width on a Table Column.