I am trying to build a layout where the Header is sticky at the top and i can collapse it when scrolling. I am running into an issue where the as i start scrolling the header collapses and the scroll position is reset to 0 which makes the header expand and this happens many times per second until i actually scroll further.
I am building an Angular2 app and one of the key points is that my header has dynamic height. I've seen a lot of examples where i can set the header position: fixed
and set a margin-top: $headerHeight
for the content
, but this will not work for me due to the fact the header has a dynamic height. Another alternative which i was considering is to just make the content scrollable but i like the behavior where the you can start scrolling even on the header as it would take almost half of the viewport height in my app initially. if it makes a difference I am using CSS grid and flexbox in the project, so just supporting modern browsers.
I've made a codepen to reproduce and illustrate the issue:
SCSS
#container {
display: grid;
grid-template-rows: max-content 1fr;
grid-template-columns: 1fr;
min-height: 100vh;
}
.header {
position: sticky;
top: 0;
z-index: 100;
background-color: green;
min-height: 200px;
transition: min-height .2s;
&.collapsed {
min-height: 100px;
}
}
.content {
height: 1000px;
background-color: red;
}
HTML
<div id="container">
<div id="header" class="header">Header</div>
<div id="content" class="content">Content</div>
</div>
JS
window.onscroll = function() {myFunction()};
function myFunction() {
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
document.getElementById("header").className = "header collapsed";
} else {
document.getElementById("header").className = "header";
}
}
I am trying to build a layout where the Header is sticky at the top and i can collapse it when scrolling. I am running into an issue where the as i start scrolling the header collapses and the scroll position is reset to 0 which makes the header expand and this happens many times per second until i actually scroll further.
I am building an Angular2 app and one of the key points is that my header has dynamic height. I've seen a lot of examples where i can set the header position: fixed
and set a margin-top: $headerHeight
for the content
, but this will not work for me due to the fact the header has a dynamic height. Another alternative which i was considering is to just make the content scrollable but i like the behavior where the you can start scrolling even on the header as it would take almost half of the viewport height in my app initially. if it makes a difference I am using CSS grid and flexbox in the project, so just supporting modern browsers.
I've made a codepen to reproduce and illustrate the issue: https://codepen.io/darko1002001/pen/eXKYGM
SCSS
#container {
display: grid;
grid-template-rows: max-content 1fr;
grid-template-columns: 1fr;
min-height: 100vh;
}
.header {
position: sticky;
top: 0;
z-index: 100;
background-color: green;
min-height: 200px;
transition: min-height .2s;
&.collapsed {
min-height: 100px;
}
}
.content {
height: 1000px;
background-color: red;
}
HTML
<div id="container">
<div id="header" class="header">Header</div>
<div id="content" class="content">Content</div>
</div>
JS
window.onscroll = function() {myFunction()};
function myFunction() {
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
document.getElementById("header").className = "header collapsed";
} else {
document.getElementById("header").className = "header";
}
}
Share
Improve this question
asked Mar 17, 2019 at 20:09
DArkODArkO
16.1k12 gold badges65 silver badges93 bronze badges
3 Answers
Reset to default 4I found a better solution to this. The proposed solution works great in chrome but the behavior is not great in Firefox and Safari for example. There seems to be an easy fix for this in chrome, I found it while digging into the bug reports.
https://bugs.chromium/p/chromium/issues/detail?id=734461
The solution of adding overflow-anchor: none;
to the content element in this case works like a charm in Chrome, doesn't cause issues in Safari and Firefox. no Javascript for scrolling is required.
.content {
height: 1000px;
background-color: red;
overflow-anchor: none;
}
Change your function to -
function myFunction() {
if (document.documentElement.scrollTop > 100) {
if(!document.getElementById("header").classList.contains('collapsed')){
document.documentElement.scrollTop += 100;
document.getElementById("header").className = "header collapsed";
}
} else {
if(document.getElementById("header").classList.contains('collapsed')){
document.getElementById("header").className = "header";
document.documentElement.scrollTop = 0;
}
}
}
You should trigger collapse when scrollTop is more than collapsed header height. In this case it's 100px. If scrollTop is above 100px and header is collapsed, then do nothing. Otherwise, add collapsed to header and scrollTop to +100 to retain its scroll Position. There is still a very tiny skipping when you scroll down, and that is because of transition on height.
Codepen - https://codepen.io/anon/pen/VRdYoM
I use this code:
.content {
max-height:200px;
overflow:scroll;
background-color:#f0f0f0;
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745659458a4638744.html
评论列表(0条)