DevGang
Авторизоваться

Руководство по стилизации таблиц

Недавно я заметил небольшой парадокс: много лет назад — до появления CSS Grid — мы использовали <table> для имитации макетов сетки. Теперь, когда у нас есть макеты сетки, мы используем их для моделирования таблиц! Это неправильно. Таблицы предназначены для табличных данных; и нет смысла представлять табличные данные в группе <div>.

Причина этой злоупотребления может заключаться в том, что таблицы могут быть немного сложными для стилизации, и что большинство фреймворков CSS используют border-collapse: коллапс для стилизации таблиц по умолчанию. Как мы увидим в этом уроке, свернутые границы не всегда полезны для стилизации таблицы.

Давайте рассмотрим элементы <table>, а затем их структурирование и стилизацию.

Элементы

Помимо самого элемента <table>, для создания базовой таблицы вам понадобятся только эти 3 тега:

Пример:

<table>
  <tr><th>Header</th></tr>
  <tr><td>Content</td></tr>
</table>

Однако, чтобы лучше структурировать таблицу, мы можем инкапсулировать строки в:

Наконец, мы можем добавить <caption> в таблицу и определить столбцы в тегах <col> внутри <colgroup>.

Пример:

<table>
  <caption>Super Heroes</caption>
  <colgroup><col><col><col><col></colgroup>
  <thead>
    <tr><th>First Name</th><th>Last Name</th><th>Known As</th><th>Place</th></tr>
  </thead>
  <tbody>
    <tr><td>Bruce</td><td>Wayne</td><td>Batman</td><td>Gotham City</td></tr>
    <tr><td>Clark</td><td>Kent</td><td>Superman</td><td>Metropolis</td></tr>
    <tr><td>Tony</td><td>Stark</td><td>Iron Man</td><td>Malibu</td></tr>
    <tr><td>Peter</td><td>Parker</td><td>Spider-Man</td><td>New York City</td></tr>
    <tr><td>Matt</td><td>Murdock</td><td>Daredevil</td><td>New York City</td></tr>
  </tbody>
</table>

Без каких-либо стилей ваш браузер отобразит это:  

Стили пользовательского агента по умолчанию:

table {
  border-collapse: separate;
  text-indent: initial;
  border-spacing: 2px;
}

Теперь, если мы добавим очень простое правило:

:is(td,th) {
  border-style: solid;
}

Обратите внимание на отдельные границы. Это выглядит не слишком красиво...

Итак, чтобы понять популярность свернутых границ (а также лучшего шрифта!), если мы просто добавим:

table {
  border-collapse: collapse;
  font-family: system-ui;
}

Мы получаем:

Если мы затем добавим дополнение: .5ch 1ch к нашему :is(td,th)-селектору и поля-блоку: 1rlh к <caption>, мы получим:

Подводя итог, все, что нам нужно для получения вышеуказанного стиля, это:

table {
  border-collapse: collapse;
  font-family: system-ui;
  & caption { margin-block: 1rlh; }
  &:is(td, th) {
    border-style: solid;
    padding: .5ch 1ch;
  }
}

Вместо этого, чтобы разместить <caption> под таблицей, используйте:

table {
  caption-side: bottom;
}

Полосы Зебры

Чтобы добавить нечетные/четные полосы зебры для столбцов, мы можем просто стилизовать тег <col>:

col:nth-of-type(even) { background: #F2F2F2; }

Для строк это аналогично:

tr:nth-of-type(odd) { background: #F2F2F2; }

Закругленные углы

Закругленные углы немного сложнее. Вы не можете просто добавить border-radius в <table>, поэтому нам нужно указать первую и последнюю ячейку первой и последней строк:

th {
  &:first-of-type { border-start-start-radius: .5em }
  &:last-of-type { border-start-end-radius: .5em }
}
tr {
  &:last-of-type {
    & td {
      &:first-of-type { border-end-start-radius: .5em }
      &:last-of-type { border-end-end-radius: .5em }
    }
  }
}

Но все равно ничего не происходит! Это потому что:

Если у вашей таблицы есть свернутые границы, вы не можете добавить border-radius.

Поэтому нам придется использовать отдельные границы и просто имитировать свернутые границы:

table {
  border-spacing: 0;
}
:is(td, th) {
  border-block-width: 1px 0;
  border-inline-width: 1px 0;
  &:last-of-type { border-inline-end-width: 1px }
}

И теперь у нас есть закругленные углы:

Разделить столбцы

Давайте сохраним отдельные столбцы и воспользуемся свойством border-spacing-spacing, чтобы добавить пробел между столбцами:

table {
  border-spacing: 2ch 0;
  & :is(td, th) {
    border-inline-width: 1px;
  }
}

Мы можем даже добавить border-radius:

Это по-прежнему просто <table>, но ее гораздо удобнее читать, если использовать ее в качестве «таблицы сравнения».

Разделить строки

Для разделенных строк нам просто нужно обновить вторую часть (ось Y) свойства border-spacing:

table {
  border-spacing: 0 2ch;
  & :is(td, th) {
    border-block-width: 1px;
  }
}

Наведите курсор и сфокусируйтесь

При работе с большими столами важно точно знать, где вы находитесь. Для этого нам понадобится :hover и — если вы работаете с таблицей, управляемой с помощью клавиатуры — :focus-visble-styles.

В этом примере стили наведения применяются как к <col>, <tr>, так и к <td>:

Наводить курсор на строки и ячейки очень просто:

td:hover {
  background: #666666;
}

tr:hover {
  background: #E6E6E6;
}

Наведение <col> немного сложнее.

Вы можете добавить правило:

col:hover {
  background: #E6E6E6;
}

Но это не работает?

Как ни странно, если вы выберете элемент col в Dev Tools и включите для него :hover, он будет работать, но не в реальной жизни.

Вместо этого нам нужно зафиксировать наведение ячеек с помощью :has, а затем стилизовать элемент <col>:

table {
  &:has(:is(td,th):nth-child(1):hover col:nth-child(1) {
background: #E6E6E6;
}

Итак, что происходит?

Давайте разберемся:

Если в нашей таблице есть <td> или <th>, который является nth-child(1) и он в данный момент наведен, выберите <col> с тем же nth-child-селектором и установите его фон.

Уф! ... и вам нужно повторить этот код для каждого столбца: nth-child(2), nth-child(3) и т.д.

Контуры

Отображать контуры при наведении также просто, то же самое касается ячеек и строк. Вам нужно вычесть ширину из смещения:

:is(td, th, tr):hover {
  outline: 2px solid #666;
  outline-offset: -2px;
}

Контуры столбцов

Очертить столбец очень сложно, но выглядит красиво:

Если ширина ячейки составляет 1 пиксель, вы можете установить ширину границы <col> на 2 пикселя при наведении курсора, но тогда вся таблица сместится.

Альваро Монторо предложил использовать фоновые градиенты в <col> для имитации границы, что отлично работает, если ячейки таблицы прозрачны.

Чтобы заставить его работать с border-radius и сохранять любой фон, который могли бы иметь ячейки, я в итоге использовал псевдоэлемент для каждой ячейки:

:is(td,th) {
  position: relative;
  &::after {
    border-inline: 2px solid transparent;
    border-radius: inherit;
    content: '';
    inset: -2px 0 0 0;
    position: absolute;
  }
}
tr:first-of-type th::after {
  border-block-start: 2px solid transparent;
}
tr:last-of-type td::after {
  border-block-end: 2px solid transparent;
}

А затем, аналогично тому, что мы сделали с col-hover, нацеливаемся на все ячейки с одинаковым «col-index» при наведении:

:has(:is(td,th):nth-child(1):hover :is(td,th):nth-child(1) {
  border-color: #666;
}

Повторите для всех столбцов

Выравнивание текста

В старой спецификации вы могли добавить свойство align к элементу <col>. Это больше не работает.

Пример. Вы хотите центрировать текст во втором столбце и выровнять текст по правому краю в четвертом столбце:

Вместо добавления класса в каждую ячейку мы можем добавить атрибут данных для каждого столбца в саму таблицу:

<table data-c2="center" data-c4="end">

Затем в CSS:

[data-c2~="center"] tr > *:nth-of-type(2) {
  text-align: center;
}
[data-c4~="end"] tr > *:nth-of-type(4) {
  text-align: end;
}

Повторите для всех столбцов.

Заключение

На этом руководство по стилизации стола заканчивается.

Я не рассмотрел colspan, rowspan, область видимости и диапазон. Если вы хотите больше узнать об этом, я предлагаю прочитать страницу MDN посвященную таблицам.

Демо

Я сделал один CodePen с кучей демо:

Источник:

#CSS #HTML
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу