Home > database >  position: sticky not working after some amount of scroll
position: sticky not working after some amount of scroll

Time:07-20

I am trying to create a layout where 1st and last columns in a div are sticky. When I scroll for some amount, the left most column goes beyond left limit. Why could this be happening and how do I fix it?

When you scroll to the very right, you can see that red column goes out of the box.

Sample codepen: https://codepen.io/vighnesh-google/pen/WNzjvqN

Sample code:

.slider {
  width: 100%;
  position: relative;
  overflow: auto;
}

.header,
.body {
 display: flex;
}

.item {
  width: 20%;
  height: 100px;
  background: yellow;
  border: 1px solid black;
  
  flex-grow: 0;
  flex-shrink: 0;
}

.sticky-item-left {
  position: sticky;
  left: 0;  
  background: red;
}

.sticky-item-right {
  position: sticky;
  right: 0;
  background: green;
}
<div >
  <div >
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
  </div>
  <div >
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
  </div>
</div>

CodePudding user response:

One way to solve this:

.slider {
  overflow: auto;
  display: grid; /* main element as grid */
  grid-auto-columns: 20%;  /* width of the items */
}
.header,
.body {
   display: contents; /* remove the parent boundary to make sticky works */
}
.header > * {
  grid-row: 1; /* all header elements in first row */
}
.body > * {
  grid-row: 2; /* all body elements in second row */
}
.item {
  height: 100px;
  background: yellow;
  border: 1px solid black;
}

.sticky-item-left {
  position: sticky;
  left: 0;  
  background: red;
}

.sticky-item-right {
  position: sticky;
  right: 0;
  background: green;
}
<div >
  <div >
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
  </div>
  <div >
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
  </div>
</div>

To understand the issue with your initial code, add border to the parent element to see the limit of the sticky elements:

.slider {
  width: 100%;
  position: relative;
  overflow: auto;
}

.header,
.body {
 display: flex;
 border:4px solid blue;
}

.item {
  width: 20%;
  height: 100px;
  background: yellow;
  border: 1px solid black;
  
  flex-grow: 0;
  flex-shrink: 0;
}

.sticky-item-left {
  position: sticky;
  left: 0;  
  background: red;
}

.sticky-item-right {
  position: sticky;
  right: 0;
  background: green;
}
<div >
  <div >
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
  </div>
  <div >
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
  </div>
</div>

CodePudding user response:

The problem is in the fact that all the items stacked next to each other become larger than the div they are placed in. Therefore they overflow the div and you end up actually scrolling the div off of the screen.

A simple solution is add overflow: scroll; to both the header and body class by updating the CSS to the following:

.header,
.body {
 display: flex;
  overflow: scroll;
}

For further reading on the topic, have a look at Css Tricks:Creating sliding effects using sticky positioning

  • Related