I\'m trying to understand what css \"sticky\" does. I can get it to stick to the \'top\' of its parent, but not to the \'bottom\'
My test code is:
It's working fine but you will see nothing. Let's have a look at the definition:
A stickily positioned element is an element whose computed position value is sticky. It's treated as relatively positioned until its containing block crosses a specified threshold (such as setting top to value other than auto) within its flow root (or the container it scrolls within), at which point it is treated as "stuck" until meeting the opposite edge of its containing blockref
Give a big margin to the block element to hide it from the screen then start scrolling slowly
.block {
background: pink;
width: 50%;
height: 200px;
margin-top:120vh;
}
.move {
position: sticky;
bottom: 0;
}
AAAA
BBBB
You will notice that when your element is showing the BBB
is overlapping the AAA
until it reach its initial place. This is the sticky behavior when using bottom:0
. So our element is kept position:relative
and when the container start going out from the screen on the top, it become sticky to its bottom until it reach the opposite edge (the top of the container).
Exactly the same happen with top:0
but in the opposite direction:
.block {
background: pink;
width: 50%;
height: 200px;
margin-bottom:120vh;
}
.move {
position: sticky;
top: 0;
}
AAAA
BBBB
So sticky will not position the element to the top or the bottom but it will decide how the element shoul stick in order to be visible when the container will start moving out of the screen.
In order to obtain what you want you need to put your element in the bottom using other properties and keep it bottom sticky.
Here is an example where I place the element at the bottom using flexbox and I specify that I need it to be sticky at the bottom.
.block {
background: pink;
width: 50%;
height: 200px;
margin-top:120vh;
display:flex;
flex-direction:column;
}
.move {
margin-top:auto;
position: sticky;
bottom: 0;
}
AAAA
BBBB
So position:sticky
will never define the position of the element like we do with absolute
or fixed
but it will define how the element will stick when there is a scrolling behavior.
Here more examples to better understand:
.block {
background: pink;
display:inline-flex;
vertical-align:top;
height: 200px;
max-width:100px;
flex-direction:column;
margin:100vh 0;
}
.e1 {
position: sticky;
top: 0;
}
.e2 {
margin-top:auto;
position: sticky;
top: 0;
}
.e3 {
position: sticky;
top: 20px;
}
.e4 {
position: sticky;
bottom: 0;
margin:auto;
}
.e5 {
position: sticky;
bottom: 0;
top:0;
margin:auto;
}
.e5 {
position: sticky;
bottom: 0;
}
Top sticky
Top sticky at bottom (nothing will happen :( )
Top sticky at 10px
bottom sticky in the middle
top/bottom sticky in the middle
bottom sticky at the top (nothing will happen :( )
Another common mistake with sticky is to forget about the height/width of the element relatively to the one of its parent. If the height of element is equal to the height of the parent (containing block) then logically there will be no sticky behavior because we are already at the opposite edge.
.block {
background: pink;
display:inline-flex;
vertical-align:top;
height: 200px;
max-width:100px;
flex-direction:column;
margin:100vh 0;
}
.block > div {
border:2px solid;
}
.e1 {
position: sticky;
top: 0;
}
Top sticky
I will not stick
I will stick a little ..
I will not stick too
Notice the last case where the height of the parent is set to auto
(default value) thus its height will be defined by its content which make the sticky element to have the same height as the containing block and nothing will happen because there is no room for a sticky behavior.