Можно ли сделать его вертикально прокручиваемым только с помощью CSS?
Краткий ответ: да, но давайте сначала проанализируем проблему:
Чтобы показать это, я сделал ваш минимальный пример (я использовал реальный table
, а не divs
и выбрал макет, который немного отличается, но проблемы по-прежнему будут такими же и применяются к вашим фрагментам кодаа также).
.wrapper {
display: flex;
overflow: auto;
}
.sticky-left {
text-align: left;
left: 0;
position: absolute;
}
.sticky-left td {
max-width: 200px;
min-width: 200px;
background: lightgrey;
}
thead th {
padding: 15px 5px;
background: #f4f3f8;
font-size: 14px;
border: none;
color: #575962;
max-width: 200px;
min-width: 200px;
}
.content-table {
margin-left: 200px;
}
<div class="wrapper">
<table class="sticky-left">
<thead>
<tr>
<th>#</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
</tbody>
</table>
<table class="content-table">
<thead>
<tr>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
</tbody>
</table>
</div>
К элементу добавляется полоса прокрутки, если содержимое переполняет flow
.Другими словами:
overflow property
указывает, следует ли обрезать содержимое или добавлять полосы прокрутки, если содержимое элемента слишком велико, чтобы поместиться в указанной области.
Источник .
Задача # 1
Таким образом, первым подходом будет просто добавить горизонтальную полосу прокрутки на оси Y, просто сделавстолик меньше.Итак, давайте так:
Добавьте height: 200px
(или любой другой размер) к классу .wrapper
.
https://jsfiddle.net/gwz3rce6/
(Я должен использовать JSFiddle, потому что символпредел был бы превышен, если бы я каждый раз добавлял фрагменты кода)
На первый взгляд это кажется очень многообещающим.У вас есть полоса прокрутки там, где вы хотите.
Проблема в том, что в фиксированном столбце с левой стороны нет потока, поскольку мы добавили position: absolute
и left: 0
.Проблема в том, что position: absolute
использует тело документа и перемещается вместе с прокруткой страницы, пока он не находится внутри позиционированного предка (например, родительский элемент с position: relative
).
Проблема # 2
Так почему бы нам просто не добавить position: relative
к .wrapper
?Фиксированный столбец должен находиться внутри контейнера и не должен ориентироваться в теле документа.
Хорошо, и это так!
https://jsfiddle.net/gwz3rce6/1/
Но это приводит к проблеме!Левый столбец больше не фиксируется ... почему?Теперь это немного усложняется:
Чтобы понять проблему, давайте представим, что левый столбец фактически находится вне элемента .wrapper
, и мы разместили его absolute
, как в моем первом примере.У вас все еще будет проблема в Проблема № 1 , но по крайней мере у вас не будет проблемы, описанной в начале Проблема № 2 .Таким образом, левый столбец фактически зафиксирован на левой стороне.
Обратите внимание, что у вас есть два контейнера: таблица с вертикальной полосой прокрутки и документ.Прокручивая таблицу, она не оказывает влияния на левый столбец прямо сейчас, потому что она находится за пределами вашей таблицы и, следовательно, не имеет к этому никакого отношения.И это то, что делает position: absolute
.Он имитирует элемент вне вашего контейнера, если он не находится в позиционированном контейнере (например, position: relative
).
Поскольку он ориентируется на документе, вы получите эффект, если добавите полосу прокрутки к body
.
Итак, давайте снова поместим левый столбец внутри вашего контейнера.При добавлении position: relative
элемент с абсолютным позиционированием может перемещаться только внутри этого контейнера и не ориентируется на документе.Вот почему он теперь внутри контейнера, а не снаружи (как в Problem # 1 ) его.Но это также причина, почему это больше не исправлено.По той же причине добавление полосы прокрутки к телу может повлиять на левый столбец в Задача # 1 .
Да, это довольно сложно понять ... ноэто также довольно трудно выразить словами.Я все еще надеюсь, что вы чему-то научились из этого, и это ответило на ваш вопрос, хотя я еще не дал решения.
Существуют и другие подходы к задаче, но ни один из них не работает (кроме одногоСейчас опишу) и я рассмотрел наиболее перспективный подход.Кроме того, если я сделал что-то не так и пропустил что-то, не стесняйтесь комментировать.
Решение
Решением этой проблемы является использование position: sticky
.
https://jsfiddle.net/zvgn7u49/
В вашем случае вы бы добавили это в класс .tg .sticky-col-1
вместо position: absolute
.
Элемент с position: sticky;
позиционируется на основе позиции прокрутки пользователя.
Липкий элемент переключается между relative
и fixed
, в зависимости от позиции прокрутки.Он позиционируется относительно до тех пор, пока в окне просмотра не будет достигнута заданная позиция смещения - затем он «залипнет» на месте (как position:fixed
).
Источник .
Но будьте осторожны, так как в нем отсутствует поддержка браузером определенных элементов.Некоторые браузеры (например, Safari) также требуют префикса -webkit-
.Вы можете получить дополнительную информацию здесь .
Редактировать: Пока я делал скрипку для вашего кода, я обнаружил, что @ Icaro Heimig уже охваченэто решение, а также сделал ручку.
Я сделал пример на codepen: https://codepen.io/icaromh/pen/gyJdvZ