Давайте начнем с того, как работает position:sticky
.
Когда элемент прикреплен, он застревает только относительно своего родителя. Это означает, что если родитель прокручивается, за ним следует липкий элемент.
Демо
[scoll] {
background: pink;
white-space: nowrap;
padding: 10px;
overflow: auto;
}
[stickyElementsContainer]{
background: orange;
width:200px;
padding: 10px;
}
[stuckElement] {
background: red;
position: sticky;
left: 0;
}
[overflow]{
width:2000px;
height:1px;
}
<div scoll>
<div stickyElementsContainer>
<span stuckElement>stuck</span>
</div>
<div overflow></div>
</div>
Теперь мы понимаем, что когда элемент выходит из видимой области, липкий элемент внутри него будет следовать за ним.
Ваша проблема точно такая же: когда вы прокручиваете оболочку, строка прокручивается, поэтому липкие элементы внутри нее следуют.
Но мы можем ясно видеть, что строка все еще широкая, Что такое происходит?
Следующая демоверсия должна объяснить
[scrollable] {
width: 300px;
padding: 10px;
background: red;
border: 5px solid;
overflow:auto;
}
[container] {
white-space: nowrap;
background: orange;
padding: 10px;
}
<div scrollable>
<div container>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
Оранжевый <div>
- это ваш ряд. Он занимает ширину прокручиваемого контейнера, хотя его содержимое все еще широко.
Потому что это элемент уровня блока (display:block
по умолчанию), а его ширина auto
означает, что он будет принимать ширину его родителя.
Теперь Если мы поместим туда липкий элемент int, Угадайте что будет .
[scrollable] {
width: 300px;
padding: 10px;
background: red;
border: 5px solid;
overflow: auto;
}
[container] {
padding: 10px;
white-space: nowrap;
background: orange;
}
[stuck] {
background: pink;
position: sticky;
left: 0;
}
<div scrollable>
<div container>
<span stuck>stuck</span> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
Вот иллюстрация проблемы в вашем коде, просто добавив фон, мы можем увидеть проблему
:root {
--column-width: 70px;
}
.wrapper {
font-family: sans-serif;
max-width: 700px;
height: 300px;
overflow: auto;
}
.table-container {
width: auto;
}
.table {
position: relative;
display: grid;
grid-template-columns: 200px repeat(14, var(--column-width));
background:orange;
}
.table.header {
position: sticky;
top: 0;
z-index: 999;
}
.table.header+.table.header {
position: sticky;
top: 36px;
;
}
.table.header .row {
background: #ccc !important;
}
.table .row.sticky {
position: sticky;
background: #eee;
}
.table .row.sticky:nth-child(1) {
left: 0px;
}
.table .row.sticky:nth-child(2) {
left: 200px;
}
.table .row.sticky:nth-child(3) {
left: 270px;
}
input {
width: 45px;
}
<div class="wrapper">
<div class="table-container" role="table" aria-label="Destinations">
<div class="table header" role="rowgroup">
<div class="row sticky" role="columnheader">Produkt</div>
<div class="row sticky" role="columnheader">föreg. År</div>
<div class="row sticky" role="columnheader">Totalt produkt</div>
<div class="row" role="columnheader">v.1</div>
<div class="row" role="columnheader">v.2</div>
<div class="row" role="columnheader">v.3</div>
<div class="row" role="columnheader">v.4</div>
<div class="row" role="columnheader">v.5</div>
<div class="row" role="columnheader">v.6</div>
<div class="row" role="columnheader">v.7</div>
<div class="row" role="columnheader">v.8</div>
<div class="row" role="columnheader">v.9</div>
<div class="row" role="columnheader">v.10</div>
<div class="row" role="columnheader">v.11</div>
<div class="row" role="columnheader">v.12</div>
</div>
<div class="table header" role="rowgroup">
<div class="row sticky" role="columnheader">Totalt vecla</div>
<div class="row sticky" role="columnheader"></div>
<div class="row sticky" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
</div>
<div class="table row" role="rowgroup">
<div class="row sticky" role="columnheader">Produktnamn</div>
<div class="row sticky" role="columnheader">100 000 SEK</div>
<div class="row sticky" role="columnheader">50 000 SEK</div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
</div>
</div>
Решение 1
Установите ширину нашей строки, соответствующую содержимому.
В вашем случае у вас есть grid-template-columns: 200px repeat(14, var(--column-width));
Из этого мы можем вывести ширину нашего контента 200px + (14 * var(--column-width))
:root {
--column-width: 70px;
}
.wrapper {
font-family: sans-serif;
max-width: 700px;
height: 300px;
overflow: auto;
}
.table-container {
width: auto;
}
.table {
position: relative;
display: grid;
grid-template-columns: 200px repeat(14, var(--column-width));
width:calc(200px + (14 * var(--column-width)));
}
.table.header {
position: sticky;
top: 0;
z-index: 999;
}
.table.header+.table.header {
position: sticky;
top: 36px;
;
}
.table.header .row {
background: #ccc !important;
}
.table .row.sticky {
position: sticky;
background: #eee;
}
.table .row.sticky:nth-child(1) {
left: 0px;
}
.table .row.sticky:nth-child(2) {
left: 200px;
}
.table .row.sticky:nth-child(3) {
left: 270px;
}
input {
width: 45px;
}
<div class="wrapper">
<div class="table-container" role="table" aria-label="Destinations">
<div class="table header" role="rowgroup">
<div class="row sticky" role="columnheader">Produkt</div>
<div class="row sticky" role="columnheader">föreg. År</div>
<div class="row sticky" role="columnheader">Totalt produkt</div>
<div class="row" role="columnheader">v.1</div>
<div class="row" role="columnheader">v.2</div>
<div class="row" role="columnheader">v.3</div>
<div class="row" role="columnheader">v.4</div>
<div class="row" role="columnheader">v.5</div>
<div class="row" role="columnheader">v.6</div>
<div class="row" role="columnheader">v.7</div>
<div class="row" role="columnheader">v.8</div>
<div class="row" role="columnheader">v.9</div>
<div class="row" role="columnheader">v.10</div>
<div class="row" role="columnheader">v.11</div>
<div class="row" role="columnheader">v.12</div>
</div>
<div class="table header" role="rowgroup">
<div class="row sticky" role="columnheader">Totalt vecla</div>
<div class="row sticky" role="columnheader"></div>
<div class="row sticky" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
</div>
<div class="table row" role="rowgroup">
<div class="row sticky" role="columnheader">Produktnamn</div>
<div class="row sticky" role="columnheader">100 000 SEK</div>
<div class="row sticky" role="columnheader">50 000 SEK</div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
</div>
</div>
Я бы не рекомендовал это, поскольку нам нужно знать ширину содержимого, и это не так гибко.
Решение 2
Установите ширину для нашей строки, соответствующую содержимому, используя min-content .
:root {
--column-width: 70px;
}
.wrapper {
font-family: sans-serif;
max-width: 700px;
height: 300px;
overflow: auto;
}
.table-container {
width: auto;
}
.table {
position: relative;
display: grid;
grid-template-columns: 200px repeat(14, var(--column-width));
width:min-content;
}
.table.header {
position: sticky;
top: 0;
z-index: 999;
}
.table.header+.table.header {
position: sticky;
top: 36px;
;
}
.table.header .row {
background: #ccc !important;
}
.table .row.sticky {
position: sticky;
background: #eee;
}
.table .row.sticky:nth-child(1) {
left: 0px;
}
.table .row.sticky:nth-child(2) {
left: 200px;
}
.table .row.sticky:nth-child(3) {
left: 270px;
}
input {
width: 45px;
}
<div class="wrapper">
<div class="table-container" role="table" aria-label="Destinations">
<div class="table header" role="rowgroup">
<div class="row sticky" role="columnheader">Produkt</div>
<div class="row sticky" role="columnheader">föreg. År</div>
<div class="row sticky" role="columnheader">Totalt produkt</div>
<div class="row" role="columnheader">v.1</div>
<div class="row" role="columnheader">v.2</div>
<div class="row" role="columnheader">v.3</div>
<div class="row" role="columnheader">v.4</div>
<div class="row" role="columnheader">v.5</div>
<div class="row" role="columnheader">v.6</div>
<div class="row" role="columnheader">v.7</div>
<div class="row" role="columnheader">v.8</div>
<div class="row" role="columnheader">v.9</div>
<div class="row" role="columnheader">v.10</div>
<div class="row" role="columnheader">v.11</div>
<div class="row" role="columnheader">v.12</div>
</div>
<div class="table header" role="rowgroup">
<div class="row sticky" role="columnheader">Totalt vecla</div>
<div class="row sticky" role="columnheader"></div>
<div class="row sticky" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
</div>
<div class="table row" role="rowgroup">
<div class="row sticky" role="columnheader">Produktnamn</div>
<div class="row sticky" role="columnheader">100 000 SEK</div>
<div class="row sticky" role="columnheader">50 000 SEK</div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
</div>
</div>
Я бы пока не рекомендовал это решение, Барбекю не очень широко пока поддерживается .
Решение 3
Сделайте нашу сетку встроенной.
inline
элементы уровня будут расти и уменьшаться в соответствии с их содержанием.
Самое жизнеспособное решение из трех.
:root {
--column-width: 70px;
}
.wrapper {
font-family: sans-serif;
max-width: 700px;
height: 300px;
overflow: auto;
}
.table-container {
width: auto;
}
.table {
position: relative;
/* display: grid; Removed */
display: inline-grid; /* NEW */
grid-template-columns: 200px repeat(14, var(--column-width));
}
.table.header {
position: sticky;
top: 0;
z-index: 999;
}
.table.header+.table.header {
position: sticky;
top: 36px;
;
}
.table.header .row {
background: #ccc !important;
}
.table .row.sticky {
position: sticky;
background: #eee;
}
.table .row.sticky:nth-child(1) {
left: 0px;
}
.table .row.sticky:nth-child(2) {
left: 200px;
}
.table .row.sticky:nth-child(3) {
left: 270px;
}
input {
width: 45px;
}
<div class="wrapper">
<div class="table-container" role="table" aria-label="Destinations">
<div class="table header" role="rowgroup">
<div class="row sticky" role="columnheader">Produkt</div>
<div class="row sticky" role="columnheader">föreg. År</div>
<div class="row sticky" role="columnheader">Totalt produkt</div>
<div class="row" role="columnheader">v.1</div>
<div class="row" role="columnheader">v.2</div>
<div class="row" role="columnheader">v.3</div>
<div class="row" role="columnheader">v.4</div>
<div class="row" role="columnheader">v.5</div>
<div class="row" role="columnheader">v.6</div>
<div class="row" role="columnheader">v.7</div>
<div class="row" role="columnheader">v.8</div>
<div class="row" role="columnheader">v.9</div>
<div class="row" role="columnheader">v.10</div>
<div class="row" role="columnheader">v.11</div>
<div class="row" role="columnheader">v.12</div>
</div>
<div class="table header" role="rowgroup">
<div class="row sticky" role="columnheader">Totalt vecla</div>
<div class="row sticky" role="columnheader"></div>
<div class="row sticky" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader"></div>
<div class="row" role="columnheader">100 000 SEK</div>
</div>
<div class="table row" role="rowgroup">
<div class="row sticky" role="columnheader">Produktnamn</div>
<div class="row sticky" role="columnheader">100 000 SEK</div>
<div class="row sticky" role="columnheader">50 000 SEK</div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
<div class="row" role="columnheader"><input type="number" /></div>
</div>
</div>
Примечание: Мне пришлось уменьшить число строк, чтобы опубликовать ответ.