Position: sticky doesn't work
I have this HTML code:
<div class="header">
<div class="desc">Description</div>
<div class="logo"><img src=""/></div>
<div class="navbar"></div></div>
.header is 150px high..navbar is 20px high. When the user scrolls, I want the .navbar to stick to the top. So I went into CSS and set position: sticky and top: 0. But that didn't work. I originally thought firefox didn't support position: sticky, but it doesn't because I was able to see a working demo of this. I searched for it but found nothing useful. Does anyone know why this is not working?
source to share
It works great if you move the navbar outside of the header. See below. For this reason, according to MDN :
The element is positioned according to the normal flow of the document and then offset relative to its flow root and containing block , depending on the values โโof the top, bottom, and left.
For the containing block:
The containing block is the ancestor to which the element is located relative
So, when I don't understand, the navbar is positioned at offset 0 inside the title as soon as it scrolls outside the viewport (which obviously means you can't see it anymore).
.navbar {
background: hotpink;
width: 100%;
height: 50px;
position: -webkit-sticky;
position: sticky;
top: 0;
}
.header {
height: 150px;
background: grey;
}
body {
height: 800px;
position: relative;
}
<div class="header">
<div class="desc">Description</div>
<div class="logo"><img src=""/></div>
</div>
<div class="navbar"></div>
source to share
Somehow your code only works when the element is .navbar
not inside another container like a header. I pulled it out and then it works fine. I created a code snippet for this, check it out
<header>
<div class="logo">Logo</div>
<div class="description"><div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo, veritatis.</div></div>
</header>
<div class="navbar">
<ul>
<li><a href="#">navitem1</a></li>
<li><a href="#">navitem2</a></li>
<li><a href="#">navitem3</a></li>
<li><a href="#">navitem4</a></li>
</ul>
</div>
The position:sticky
support is pretty good right now , as you can see on canIuse. Of course, IE currently has no support, but the new version of Edge will bring full support for that! I found interesting articles on this topic:
- Working demo (chrome, firefox ๐) https://codepen.io/simevidas/pen/JbdJRZ
- Caniuse refernce: http://caniuse.com/#search=sticky
- sticky article on MDN including latest browser support table https://developer.mozilla.org/en-US/docs/Web/CSS/position#Sticky_positioning
But there is good news on the horizon. I think next time will improve browser support.
source to share
Your HTML code as it is
<div class="header">
<div class="desc">Description</div>
<div class="logo"><img src=""/></div>
<div class="navbar"></div></div>
and write a CSS class for the navigation bar
.header {
height: 150px;
background-color: #d1d1d1;
}
.navbar {
background: #999;
border-bottom: 1px solid #333;
border-top: 1px solid #333;
color: #FFF;
margin: 0;
padding: 2px 0 0 12px;
position: -webkit-sticky;
position: sticky;
top: -1px;
}
Hope this helps
source to share
Adding more content after the navigation inside the header provides sticky behavior, but only for a moment - if the user scrolls too much, the navigation will disappear with the header as it cannot fall below the bottom of the header.
So the only pure CSS solution is to put the nav inside an element that is partially visible even after the user scrolls to the bottom of the page (directly inside the body, or inside some container that extends to the bottom of the page, or at least in footer).
If this solution is not possible, another way is to use JavaScript. Before switching to CSS, I used the following code (a similar jQuery solution was found somewhere long ago, can't remember where, so credit goes to an anonymous author; Vanilla JS can be easily obtained from this):
$(document).ready(function () {
var sticky_navigation_offset_top = $('nav').offset().top;
var sticky_navigation = function () {
var scroll_top = $(window).scrollTop();
if (scroll_top > sticky_navigation_offset_top) {
$('nav').css({
'position': 'fixed',
'top': 0,
'left': 0,
'right': 0,
'margin-left': 'auto',
'margin-right': 'auto'
});
} else {
$('nav').css({
'position': 'relative'
});
}
};
sticky_navigation();
$(window).scroll(function () {
sticky_navigation();
});
});
source to share