Ещё несколько лет назад фронтенд-разработчики активно использовали табличную вёрстку для создания веб-страниц. Сегодня появились более удобные инструменты, а тег <table>
теперь применяется по прямому назначению: для создания таблиц с данными. Однако оформлять таблицы по-прежнему не так просто. Некоторые CSS-свойства, например, margin
, border-radius
, z-index
, не работают с элементами таблиц <tbody>
, <thead>
, <tr>
. Статья поможет обойти эти ограничения.
Эталонный вариант таблицы
Иллюстрация выше показывает, как можно оформить таблицу с помощью CSS. Первый ряд выступает в качестве заголовка, а разделы таблицы обозначены подзаголовками.
<table class="table">
<thead>
<tr>
<th>MO</th>
<th>TU</th>
<th>WE</th>
<th>TH</th>
<th>FR</th>
<th>SA</th>
<th>SU</th>
</tr>
</thead>
<tbody class="section section-step">
<tr class="sub-header">
<th colspan="7">
Working hours
</th>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
<tbody class="section section-step">
<tr class="sub-header">
<th colspan="7">
Workout
</th>
</tr>
<tr>
<td>0.5</td>
<td>0.5</td>
<td>0.5</td>
<td>1</td>
<td>0.5</td>
<td>2</td>
<td>0</td>
</tr>
</tbody>
<tbody class="section">
<tr class="section-header">
<th colspan="7">
Total
</th>
</tr>
<tr>
<td>8.5</td>
<td>8.5</td>
<td>9.5</td>
<td>10</td>
<td>5.5</td>
<td>2</td>
<td>0</td>
</tr>
</tbody>
</table>
Выше представлена структура таблицы в HTML. В <thead>
содержится главное название. В таблице есть несколько секций <tbody>
, каждая из которых имеет собственный подзаголовок.
margin
и как оформить отступы для элементов таблицыКак видно на иллюстрации в начале статьи, между главным заголовком и секцией <tbody>
, а также между остальными секциями <tbody>
, есть отступы. Можно подумать, что они определяются свойствами margin-top
для <tbody>
, но это не так.
Если попытаться использовать margin-top
для оформления <tbody>
, <thead>
или <tr>
, добиться отступов не удастся. Чтобы margin
заработали, можно изменить свойство display
, которое менять опасно, так как изменения могут нарушить форматирование таблицы. Поэтому лучше воспользоваться альтернативными решениями, которые описаны ниже.
border
Самый простой способ получить отступы без использования margin
— применить к <tbody>
border-top: 1 em
.
// Это нужно, чтобы работал border-top
.table {
border-collapse: collapse; // 1
border-spacing: 0;
}
.section {
border-top: 1em solid transparent;
}
Все секции <tbody>
, у которых должны быть отступы, имеют класс .section
. Чтобы свойство border-top
сработало, необходимо применить к таблице border-collapse: collapse
.
::before
и ::after
Псевдоэлементы ::before
и ::after
— ещё один способ добавить отступы для элементов таблицы.
.section::before {
height: 1em;
display: table-row;
content: '';
}
В данном случае создаётся пустой ряд, который обеспечивает визуальный отступ между секциями <tbody>
.
Вы можете использовать для оформления отступов как псевдоэлементы, так и свойство border
.
border-radius
Задача: добавить к секциям <tbody>
границы и применить к ним border-radius
. Напрямую это сделать невозможно — border
и border-radius
не работают с <tbody>
.
// 1. Приходится использовать свойство box-shadow
// border-radius не работает с <tbody>.
.section-step {
border-radius: 0.25em; // 1
box-shadow: 0 0 0 1px #ccc; // 1
}
Пример выше показывает, как с помощью box-shadow
добиться практически такого же результата, как с помощью border
при работе с нетабличными элементами.
Внешний вид текущей таблицы (см. иллюстрацию ниже) отличается от эталонного варианта, который представлен в начале статьи.
Нужны марджины, а не паддинги
После добавления границ можно заметить, что полученные отступы работают не как «марджины», а как «паддинги». Это можно изменить, если работать с границами ячеек и использовать селекторы :first-child
и :last-child
.
.section-step th,
.section-step td {
border: 0 solid #ccc;
}
.section-step th:first-child,
.section-step td:first-child {
border-left-width: 1px;
}
.section-step th:last-child,
.section-step td:last-child {
border-right-width: 1px;
}
.section-step tr:first-child th,
.section-step tr:first-child td {
border-top-width: 1px;
}
.section-step tr:first-child th:first-child,
.section-step tr:first-child td:first-child {
border-top-left-radius: 0.25em;
}
.section-step tr:first-child th:last-child,
.section-step tr:first-child td:last-child {
border-top-right-radius: 0.25em;
}
.section-step tr:last-child th,
.section-step tr:last-child td {
border-bottom-width: 1px;
}
.section-step tr:last-child th:first-child,
.section-step tr:last-child td:first-child {
border-bottom-left-radius: 0.25em;
}
.section-step tr:last-child th:last-child,
.section-step tr:last-child td:last-child {
border-bottom-right-radius: 0.25em;
}
В примере выше стили применяются к соответствующим элементам th
и td
ячеек таблицы. К ячейкам, которые находятся в углах таблицы, применяется border-radius
. Все ячейки, которые находятся по краям таблицы, имеют границы. Селекторы :first-child
и :last-child
позволяют обращаться к нужным ячейкам.
z-index
к элементам таблицыПроблемы с box-shadow
На первой иллюстрации в статье видно, что свойство box-shadow
применяется к подзаголовкам, поэтому тени попадают на следующие ниже ряды таблицы. Если попробовать прямо применить box-shadow
к соответствующему элементу, тень в рядах не появится.
В обычной ситуации можно использовать для решения таких проблем z-index
. Но с таблицами всё сложнее: z-index
не работает с <tbody>
. Проблема решается, если вы знаете, как работать с контекстом наложения. Если применить к элементу position: relative
и z-index
, появляется новый контекст наложения. Также эту задачу можно решить с помощью transform: translate (0, 0)
.
Чтобы сделать таблицы визуально привлекательными, приходится использовать неочевидные трюки CSS. Но этим и хороши CSS — с их помощью можно решить практически любую задачу по оформлению веб-элементов.
При работе с таблицами возникает соблазн переопределить свойство display
. Но это приведёт к дополнительным сложностям: придётся вручную определять ширину ячеек, чтобы таблица нормально отображалась. Поэтому удобнее пользоваться предложенными выше трюками, которые позволяют оформлять таблицы элегантно и без лишнего кода.
Адаптированный перевод статьи Styling HTML Tables: How to Apply Margins, Borders and z-index on Table Elements by Markus Oberlehner. Мнение автора оригинальной публикации может не совпадать с мнением администрации «Хекслета».