Вариант 1: Классический горизонтальный скролл
Самый простой вариант, просто включаем горизонтальную прокрутку и немного уменьшаем размер шрифта на телефонах. Таблица сохраняет свою структуру, но помещается в контейнер с прокруткой.
Особенности:
- Минимальное вмешательство в структуру на мобильных устройствах.
Плюсы:
- Сохраняется нативная семантика
<table>. - Нет дублирования контента.
- Идеально для очень больших наборов данных (финансовые отчеты, лог-файлы).
Минусы:
- Плохой UX: пользователю приходится постоянно скроллить влево-вправо, теряя из виду начало строки.
В примерах можно сужать и расширять контейнер, чтобы посмотреть мобильную версию. Потяните за
ярлычок справа снизу, как у textarea.
| № | ФИО | Дата рождения | Должность | Оклад, руб. |
|---|---|---|---|---|
| 1 | Белов Максим Артемович | 22.10.1988 | Технический директор | 185 000 |
| 2 | Мельникова Дарья Сергеевна | 03.12.1995 | Системный аналитик | 140 000 |
| 3 | Костин Андрей Николаевич | 15.06.1991 | DevOps-инженер | 160 000 |
| 4 | Соколова Алина Игоревна | 28.01.1998 | UI/UX дизайнер | 115 000 |
| 5 | Павлов Илья Владимирович | 09.04.1985 | Менеджер проектов | 130 000 |
Показать HTML код
<div class="variant-1">
<table>
<thead>
<tr>
<th width="5%">№</th>
<th width="40%">ФИО</th>
<th width="15%">Дата рождения</th>
<th width="20%">Должность</th>
<th width="20%">Оклад, руб.</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Белов Максим Артемович</td>
<td>22.10.1988</td>
<td>Технический директор</td>
<td>185 000</td>
</tr>
<tr>
<td>2</td>
<td>Мельникова Дарья Сергеевна</td>
<td>03.12.1995</td>
<td>Системный аналитик</td>
<td>140 000</td>
</tr>
<tr>
<td>3</td>
<td>Костин Андрей Николаевич</td>
<td>15.06.1991</td>
<td>DevOps-инженер</td>
<td>160 000</td>
</tr>
<tr>
<td>4</td>
<td>Соколова Алина Игоревна</td>
<td>28.01.1998</td>
<td>UI/UX дизайнер</td>
<td>115 000</td>
</tr>
<tr>
<td>5</td>
<td>Павлов Илья Владимирович</td>
<td>09.04.1985</td>
<td>Менеджер проектов</td>
<td>130 000</td>
</tr>
</tbody>
</table>
</div> Показать CSS код
.variant-1 {
container-type: inline-size;
}
.variant-1 table {
--border-color: #cad5e2;
--half-border-color: color-mix(in srgb, var(--border-color), transparent 50%);
background: white;
color: #1d293d;
border-collapse: separate;
border-spacing: 0;
overflow: hidden;
border-radius: 0.5rem;
border: 1px solid var(--border-color);
border-color: var(--border-color);
}
.variant-1 th {
border-bottom-width: 2px;
border-color: #45556c;
background-color: #f1f5f9;
padding: 0.5rem 1rem;
text-align: left;
vertical-align: bottom;
}
.variant-1 td {
padding: 0.5rem 1rem;
vertical-align: baseline;
}
.variant-1 tr:nth-child(even) {
background-color: #f8fafc;
}
.variant-1 tr:not(:last-child) td {
border-bottom: 1px solid var(--half-border-color);
}
.variant-1 :is(th, td):nth-child(3),
.variant-1 :is(th, td):nth-child(5) {
text-align: right;
}
.variant-1 td:nth-child(5) {
white-space: nowrap;
}
@container (width < 640px) {
.variant-1 table {
font-size: 0.875rem;
}
} Вариант 2: Карточки
В мобильной версии строки разворачиваем вертикально. Но для каждого значения рядом ставим легенду – значение столбца, которое мы задаём через дата-атрибут или стилями.
Плюсы:
- Не меняем разметку (значение создаётся через псевдоэлемент
before) - Весь контент виден сразу без скролла.
Минусы:
- Трудно сравнивать значения разных строк между собой.
Карточки с data-атрибутами
Для этого сохраним в data-label значение легенды столбца у всех ячеек.
<tr>
<td data-label="№">1</td>
<td data-label="ФИО">Белов Максим Артемович</td>
<td data-label="Дата рождения">22.10.1988</td>
<td data-label="Должность">Технический директор</td>
<td data-label="Оклад, руб.">185 000</td>
</tr>
А в CSS установим для псевдоэлемента значение, которое будет автоматически подхватываться из дата-атрибута.
td::before {
content: attr(data-label) ':';
}
| № | ФИО | Дата рождения | Должность | Оклад, руб. |
|---|---|---|---|---|
| 1 | Белов Максим Артемович | 22.10.1988 | Технический директор | 185 000 |
| 2 | Мельникова Дарья Сергеевна | 03.12.1995 | Системный аналитик | 140 000 |
| 3 | Костин Андрей Николаевич | 15.06.1991 | DevOps-инженер | 160 000 |
| 4 | Соколова Алина Игоревна | 28.01.1998 | UI/UX дизайнер | 115 000 |
| 5 | Павлов Илья Владимирович | 09.04.1985 | Менеджер проектов | 130 000 |
Показать HTML код
<div class="table-container">
<table class="variant-2">
<thead>
<tr>
<th width="5%">№</th>
<th width="40%">ФИО</th>
<th width="15%">Дата рождения</th>
<th width="20%">Должность</th>
<th width="20%">Оклад, руб.</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="№">1</td>
<td data-label="ФИО">Белов Максим Артемович</td>
<td data-label="Дата рождения">22.10.1988</td>
<td data-label="Должность">Технический директор</td>
<td data-label="Оклад, руб.">185 000</td>
</tr>
<tr>
<td data-label="№">2</td>
<td data-label="ФИО">Мельникова Дарья Сергеевна</td>
<td data-label="Дата рождения">03.12.1995</td>
<td data-label="Должность">Системный аналитик</td>
<td data-label="Оклад, руб.">140 000</td>
</tr>
<tr>
<td data-label="№">3</td>
<td data-label="ФИО">Костин Андрей Николаевич</td>
<td data-label="Дата рождения">15.06.1991</td>
<td data-label="Должность">DevOps-инженер</td>
<td data-label="Оклад, руб.">160 000</td>
</tr>
<tr>
<td data-label="№">4</td>
<td data-label="ФИО">Соколова Алина Игоревна</td>
<td data-label="Дата рождения">28.01.1998</td>
<td data-label="Должность">UI/UX дизайнер</td>
<td data-label="Оклад, руб.">115 000</td>
</tr>
<tr>
<td data-label="№">5</td>
<td data-label="ФИО">Павлов Илья Владимирович</td>
<td data-label="Дата рождения">09.04.1985</td>
<td data-label="Должность">Менеджер проектов</td>
<td data-label="Оклад, руб.">130 000</td>
</tr>
</tbody>
</table>
</div> Показать CSS код
.table-container {
container-type: inline-size;
}
.variant-2 {
--border-color: #cad5e2;
--half-border-color: color-mix(in srgb, var(--border-color), transparent 50%);
width: 100%;
border-collapse: separate;
border-spacing: 0;
overflow: hidden;
border-radius: 0.5rem;
border: 1px solid var(--border-color);
border-color: var(--border-color);
}
.variant-2 tr:nth-child(even) {
background-color: #f8fafc;
}
.variant-2 th {
border-bottom-width: 2px;
border-color: #45556c;
background-color: #f1f5f9;
padding: 0.5rem 1rem;
text-align: left;
vertical-align: bottom;
}
.variant-2 td {
padding: 0.5rem;
vertical-align: baseline;
}
.variant-2 td:nth-child(5) {
white-space: nowrap;
}
@container (width < 640px) {
.variant-2 {
font-size: 0.875rem;
}
.variant-2 thead {
display: none;
}
.variant-2 td {
display: grid;
grid-template-columns: 15ch 1fr;
gap: 0.5rem;
}
.variant-2 td::before {
content: attr(data-label) ':';
font-weight: bold;
}
.variant-2 td:first-child {
padding-top: 1.25rem;
}
.variant-2 td:last-child {
padding-bottom: 1.25rem;
}
.variant-2 tr:not(:last-child) td:last-child {
border-bottom: 1px solid var(--half-border-color);
}
}
@container (width >= 640px) {
.variant-2 td {
padding-inline: 1rem;
}
.variant-2 tr:not(:last-child) td {
border-bottom: 1px solid var(--half-border-color);
}
.variant-2 :is(th, td):nth-child(3),
.variant-2 :is(th, td):nth-child(5) {
text-align: right;
}
} Карточки с статическим CSS
Другой вариант – это вручную прописывать значения для каждой колонки в CSS. В этом случае оставляем HTML чистым.
Здесь зависит только от того, как проще для вас. Этот вариант немного экономнее в плане размера HTML-файла. Также, если вручную добавляете строки таблицы, а не через CRM, то лучше выбрать такой вариант – так меньше шанс ошибиться, и легче переделывать.
td:nth-child(1)::before {
content: '№:';
}
td:nth-child(2)::before {
content: 'ФИО:';
}
td:nth-child(3)::before {
content: 'Дата рождения:';
}
td:nth-child(4)::before {
content: 'Должность:';
}
td:nth-child(5)::before {
content: 'Оклад, руб.:';
}
| № | ФИО | Дата рождения | Должность | Оклад, руб. |
|---|---|---|---|---|
| 1 | Белов Максим Артемович | 22.10.1988 | Технический директор | 185 000 |
| 2 | Мельникова Дарья Сергеевна | 03.12.1995 | Системный аналитик | 140 000 |
| 3 | Костин Андрей Николаевич | 15.06.1991 | DevOps-инженер | 160 000 |
| 4 | Соколова Алина Игоревна | 28.01.1998 | UI/UX дизайнер | 115 000 |
| 5 | Павлов Илья Владимирович | 09.04.1985 | Менеджер проектов | 130 000 |
Показать HTML код
<div class="table-container">
<table class="variant-3">
<thead>
<tr>
<th width="5%">№</th>
<th width="40%">ФИО</th>
<th width="15%">Дата рождения</th>
<th width="20%">Должность</th>
<th width="20%">Оклад, руб.</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Белов Максим Артемович</td>
<td>22.10.1988</td>
<td>Технический директор</td>
<td>185 000</td>
</tr>
<tr>
<td>2</td>
<td>Мельникова Дарья Сергеевна</td>
<td>03.12.1995</td>
<td>Системный аналитик</td>
<td>140 000</td>
</tr>
<tr>
<td>3</td>
<td>Костин Андрей Николаевич</td>
<td>15.06.1991</td>
<td>DevOps-инженер</td>
<td>160 000</td>
</tr>
<tr>
<td>4</td>
<td>Соколова Алина Игоревна</td>
<td>28.01.1998</td>
<td>UI/UX дизайнер</td>
<td>115 000</td>
</tr>
<tr>
<td>5</td>
<td>Павлов Илья Владимирович</td>
<td>09.04.1985</td>
<td>Менеджер проектов</td>
<td>130 000</td>
</tr>
</tbody>
</table>
</div> Показать CSS код
.table-container {
container-type: inline-size;
}
.variant-3 {
--border-color: #cad5e2;
--half-border-color: color-mix(in srgb, var(--border-color), transparent 50%);
width: 100%;
border-collapse: separate;
border-spacing: 0;
overflow: hidden;
border-radius: 0.5rem;
border: 1px solid var(--border-color);
background-color: white;
}
.variant-3 tr:nth-child(even) {
background-color: #f8fafc;
}
.variant-3 th {
border-bottom-width: 2px;
border-color: #45556c;
background-color: #f1f5f9;
padding: 0.5rem 1rem;
text-align: left;
vertical-align: bottom;
}
.variant-3 td {
padding: 0.5rem;
vertical-align: baseline;
}
.variant-3 td:nth-child(5) {
white-space: nowrap;
}
.variant-3 td::before {
font-weight: bold;
}
.variant-3 td:nth-child(1)::before {
content: '№:';
}
.variant-3 td:nth-child(2)::before {
content: 'ФИО:';
}
.variant-3 td:nth-child(3)::before {
content: 'Дата рождения:';
}
.variant-3 td:nth-child(4)::before {
content: 'Должность:';
}
.variant-3 td:nth-child(5)::before {
content: 'Оклад, руб.:';
}
@container (width < 640px) {
.variant-3 {
font-size: 0.875rem;
}
.variant-3 thead {
display: none;
}
.variant-3 td {
display: grid;
grid-template-columns: 15ch 1fr;
gap: 0.5rem;
}
.variant-3 td:first-child {
padding-top: 1.25rem;
}
.variant-3 td:last-child {
padding-bottom: 1.25rem;
}
.variant-3 tr:not(:last-child) td:last-child {
border-bottom: 1px solid var(--half-border-color);
}
}
@container (width >= 640px) {
.variant-3 td {
padding-inline: 1rem;
}
.variant-3 td::before {
display: none;
}
.variant-3 tr:not(:last-child) td {
border-bottom: 1px solid var(--half-border-color);
}
.variant-3 :is(th, td):nth-child(3),
.variant-3 :is(th, td):nth-child(5) {
text-align: right;
}
} Отдельные карточки
Дальнейшее развитие прошлого варианта. Отличается только дизайном.
| № | ФИО | Дата рождения | Должность | Оклад, руб. |
|---|---|---|---|---|
| 1 | Белов Максим Артемович | 22.10.1988 | Технический директор | 185 000 |
| 2 | Мельникова Дарья Сергеевна | 03.12.1995 | Системный аналитик | 140 000 |
| 3 | Костин Андрей Николаевич | 15.06.1991 | DevOps-инженер | 160 000 |
| 4 | Соколова Алина Игоревна | 28.01.1998 | UI/UX дизайнер | 115 000 |
| 5 | Павлов Илья Владимирович | 09.04.1985 | Менеджер проектов | 130 000 |
Показать HTML код
<div class="table-container">
<table class="variant-4">
<thead>
<tr>
<th width="5%">№</th>
<th width="40%">ФИО</th>
<th width="15%">Дата рождения</th>
<th width="20%">Должность</th>
<th width="20%">Оклад, руб.</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Белов Максим Артемович</td>
<td>22.10.1988</td>
<td>Технический директор</td>
<td>185 000</td>
</tr>
<tr>
<td>2</td>
<td>Мельникова Дарья Сергеевна</td>
<td>03.12.1995</td>
<td>Системный аналитик</td>
<td>140 000</td>
</tr>
<tr>
<td>3</td>
<td>Костин Андрей Николаевич</td>
<td>15.06.1991</td>
<td>DevOps-инженер</td>
<td>160 000</td>
</tr>
<tr>
<td>4</td>
<td>Соколова Алина Игоревна</td>
<td>28.01.1998</td>
<td>UI/UX дизайнер</td>
<td>115 000</td>
</tr>
<tr>
<td>5</td>
<td>Павлов Илья Владимирович</td>
<td>09.04.1985</td>
<td>Менеджер проектов</td>
<td>130 000</td>
</tr>
</tbody>
</table>
</div> Показать CSS код
.table-container {
container-type: inline-size;
}
.variant-4 {
--border-color: #cad5e2;
--half-border-color: color-mix(in srgb, var(--border-color), transparent 50%);
width: 100%;
border-collapse: separate;
border-spacing: 0;
overflow: hidden;
border-radius: 0.5rem;
border: 1px solid var(--border-color);
}
.variant-4 th {
border-bottom-width: 2px;
border-color: #45556c;
background-color: #f1f5f9;
padding: 0.5rem 1rem;
text-align: left;
vertical-align: bottom;
}
.variant-4 td {
padding: 0.5rem 1rem;
vertical-align: baseline;
}
.variant-4 td:nth-child(5) {
white-space: nowrap;
}
@container (width < 640px) {
.variant-4 {
font-size: 0.875rem;
border: none;
}
.variant-4 thead {
display: none;
}
.variant-4 tbody {
display: grid;
gap: 1rem;
}
.variant-4 tr {
border: 1px solid var(--border-color);
border-radius: 0.5rem;
overflow: hidden;
}
.variant-4 tr:nth-child(even) {
background-color: white;
}
.variant-4 td {
display: grid;
grid-template-columns: 15ch 1fr;
gap: 0.5rem;
text-align: right;
border-bottom: 1px solid var(--half-border-color);
}
.variant-4 td:last-child {
border-bottom: none;
}
.variant-4 td::before {
text-align: left;
font-weight: bold;
}
.variant-4 td:nth-child(1)::before {
content: '№:';
}
.variant-4 td:nth-child(2)::before {
content: 'ФИО:';
}
.variant-4 td:nth-child(3)::before {
content: 'Дата рождения:';
}
.variant-4 td:nth-child(4)::before {
content: 'Должность:';
}
.variant-4 td:nth-child(5)::before {
content: 'Оклад, руб.:';
}
}
@container (width >= 640px) {
.variant-4 tr:nth-child(even) {
background-color: #f8fafc;
}
.variant-4 tr:not(:last-child) td {
border-bottom: 1px solid var(--half-border-color);
}
.variant-4 th:nth-child(3),
.variant-4 th:nth-child(5),
.variant-4 td:nth-child(3),
.variant-4 td:nth-child(5) {
text-align: right;
}
} Итоги: какой вариант выбрать?
Все способы адаптации можно разделить на две стратегии. Выбор зависит от того, что важнее для вашего пользователя: структура данных или удобство чтения на узком экране.
Стратегия 1: Сохранение табличного вида (scroll)
Этот вариант остается единственным, если пользователю необходимо сравнивать значения в разных строках.
- Когда выбирать: Таблицы с тарифами, технические спецификации, финансовые отчеты.
- Главный плюс: Глаз легко перемещается вертикально по столбцу, сравнивая показатели нескольких объектов.
Стратегия 2: Трансформация в карточки (Data-label и CSS)
Здесь мы жертвуем возможностью легкого сравнения ради того, чтобы данные не вылезали за пределы экрана и читались как обычный текст.
- Когда выбирать: Списки пользователей, реестры документов, простые каталоги.
- Главный плюс: Весь объем информации о конкретном объекте (строке) виден сразу, без горизонтального скролла.