Reputation: 1792
I'm trying to have a child absolute element of a sticky parent to not scroll down (follow the parents sticky, essentially).
The issue is the header element is below a topbar
element. When opening the drawer without scrolling it's below the top bar, which makes sense because absolute dictates it follows the parent's relative position.
I'm trying to have the drawer sit at top:0px
(in regards to a fixed position), at the very top of the screen overlapping the top bar. Moving the element from top:0px
to top:-20px
won't work because the content in the drawer would get cut off.
One solution I thought of it is just adjusting the top
value of the element with the element scroll to give that illusion, but that seems slightly extreme in terms of resources.
A second solution would be decoupling the drawer from the parent but ...
.. This is actually a substantially more complex header/functionality with one too many coupled and moving parts (I didn't make it). It's quite delicate when it comes to changes due to the parent/child dependancy of the elements, otherwise making the drawer an element of its own would have been the easiest solution.
Here is a small example of how it functions at the moment:
$("#toggle").click(function() {
$("#drawer").toggle("open");
})
#wrapper {display:flex; flex-direction:column}
#topbar {
background-color: red;
height: 20px;
}
#header {
position: sticky;
z-index: 5;
top:0;
background-color: blue;
height :40px;
}
#drawer {
position:absolute;
height: 100vh;
top:0px;
right: 10px;
background-color:yellow;
}
#page {
height:900px;
}
.open {
right:50vw;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="topbar">top bar</div>
<div id="header">
<div id="header_inner">
<button id="toggle"> Drawer Toggle</button>
</div>
<div id="drawer" >
Drawer Content
</div>
</div>
<div id="page"> Page Content <div>
Upvotes: 1
Views: 1175
Reputation: 1757
Set the drawer at top:-20px; and add a scroll listener to check if you need to move or not. If scroll is less than 20 calculate difference to set top, otherwise, set top to zero.
I've added a rule to avoid margins for HTML and BODY, because if there are margins or padding, you need to add them to the calculation.
$(document).on( 'scroll', function(){
let scroll = $(document).scrollTop();
let diff = 20 - scroll;
if(diff > 20) {
$("#drawer").css('top', 0);
} else if(diff >= 0) {
$("#drawer").css('top', '-' + diff + 'px');
}
});
$("#toggle").click(function() {
$("#drawer").toggle("open");
});
html, body {
margin:0;
padding:0;
}
#wrapper {display:flex; flex-direction:column}
#topbar {
background-color: red;
height: 20px;
}
#header {
position: sticky;
z-index: 5;
top:0;
background-color: blue;
height :40px;
}
#drawer {
position:absolute;
height: 100vh;
top:-20px;
right: 10px;
background-color:yellow;
}
#page {
height:900px;
}
.open {
right:50vw;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="topbar">top bar</div>
<div id="header">
<div id="header_inner">
<button id="toggle"> Drawer Toggle</button>
</div>
<div id="drawer" >
Drawer Content
</div>
</div>
<div id="page"> Page Content <div>
Upvotes: 1