CSS Position: Sticky and Overflow

CSS position: sticky and overflow

It's important to understand that sticky elements are first treated like a relative element and then a fixed element (see MDN). Therefore, you must first look at it like a relative element. If you give a height of 100% to a relative element, then nothing really happens unless its parent element has a defined height.

If you want your sticky element to have a scrollbar too, you must give it a meaningful height. I suggest using viewport height:

.child {
position: sticky;
top: 0;
bottom: 0;
height: 50vh;
overflow-y: auto;
}

For the record - the "stickiness" doesn't appear to be working as expected in either FF or Safari in terms of the element becoming fixed during scrolling. I'm not concerning myself with that - just focusing on the overflow issue.

How does the position: sticky; property work?

Sticky positioning is a hybrid of relative and fixed positioning. The element is treated as relative positioned until it crosses a specified threshold, at which point it is treated as fixed positioned.

...

You must specify a threshold with at least one of top, right, bottom, or left for sticky positioning to behave as expected. Otherwise, it will be indistinguishable from relative positioning.
[source: MDN]

So in your example, you have to define the position where it should stick in the end by using the top property.

html, body {
height: 200%;
}

nav {
position: sticky;
position: -webkit-sticky;
top: 0; /* required */
}

.nav-selections {
text-transform: uppercase;
letter-spacing: 5px;
font: 18px "lato", sans-serif;
display: inline-block;
text-decoration: none;
color: white;
padding: 18px;
float: right;
margin-left: 50px;
transition: 1.5s;
}

.nav-selections:hover {
transition: 1.5s;
color: black;
}

ul {
background-color: #B79b58;
overflow: auto;
}

li {
list-style-type: none;
}
<nav>
<ul align="left">
<li><a href="#/contact" class="nav-selections" style="margin-right:35px;">Contact</a></li>
<li><a href="#/about" class="nav-selections">About</a></li>
<li><a href="#/products" class="nav-selections">Products</a></li>
<li><a href="#" class="nav-selections">Home</a></li>
</ul>
</nav>

CSS position: sticky on horizontal scroll

Parent (.scroll) has to be position: relative at first as you can check below but I would consider different structure (all contents with same title could be in same div) to stick it over multiple items.

* {
box-sizing: border-box;
}

body {
margin: 0;
padding: 0;
}

.scroll {
position: relative;
display: flex;
flex-direction: row;
width: 100vw;
height: 100px;
background: yellow;
overflow: scroll;
}

.item {
flex-flow: column;
flex-shrink: 0;
width: 200px;
height: 100%;
margin-right: 20px;
}

.scroll .item .title {
position: sticky;
display: inline;
left: 0;
top: 0;
width: 100%;
height: 40px;
}

.item .content {
width: 100%;
height: 60px;
border: 3px solid green;
}

.item .content:first-child {
margin-top: 1rem;
}
<div class="scroll">

<div class="item">
<div class="title">
Title 1
</div>
<div class="content">
Content
</div>
</div>

<div class="item">
<div class="content">
Content
</div>
</div>

<div class="item">
<div class="title">
Title 2
</div>
<div class="content">
Content
</div>
</div>

<div class="item">
<div class="content">
Content
</div>
</div>

<div class="item">
<div class="content">
Content
</div>
</div>

</div>

position: sticky not working after some amount of scroll

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 class="slider">
<div class="header">
<div class="item sticky-item-left"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item sticky-item-right"></div>
</div>
<div class="body">
<div class="item sticky-item-left"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item sticky-item-right"></div>
</div>
</div>


Related Topics



Leave a reply



Submit