I have HTML elements with a position: fixed
within an second element with an overflow-y :auto
When the mouse is over the fixed element the scroll doesn't bubble to it's parent. When moving away, the scroll occurs.
I've reduced the situation to the code below
main {
/* I am the element that scrolls */
height: 200px;
display: flex;
flex-flow: row nowrap;
overflow-y: auto;
}
main section {
flex: 1 1 800px;
max-width: 800px;
}
main nav {
flex: 1 1 auto;
min-width: 100px;
}
main nav a {
/* I am the element that prevent scroll on when hovering */
position: fixed;
}
<main>
<aside>
<nav>
<a href="#">left</a>
</nav>
</aside>
<section>
<p>Could be a long text...</p>
</section>
<aside>
<nav>
<a href="#">right</a>
</nav>
</aside>
</main>
You can test it at JSBin by trying to scroll over the pink element or somewhere else.
Is there a way in CSS or even in JavaScript ?
Seems Straight forward, position:fixed
and/or position:absolute
as you may now takes the element out of the document flow as if it doesn't exists, like it's somewhat just there for visual effects.
position:absolute
still can bubble the scroll events of it's relative positioned ancestor as we know.
.parent {
height: 100px;
width: 100px;
border: 1px solid;
overflow-y: auto;
/* Take this out to see the effect */
position: relative;
}
p {
height: 5000px;
/* Mimic overflow */
}
.kid {
height: 20px;
width: 20px;
border: 1px solid;
position: absolute;
}
<div class="parent">
<div class="kid"></div>
<p></p>
</div>
However position:fixed
is special, because it's relative to the browser window (viewport), it'll bubble the scroll event of the browser.
body {
/* Mimic body has scrollbars */
height: 5000px;
}
.parent {
height: 100px;
width: 100px;
border: 1px solid;
overflow-y: auto;
/* Take this out to see the effect */
position: relative;
}
p {
/* Mimic overflow */
height: 5000px;
}
.kid {
height: 20px;
width: 20px;
border: 1px solid;
position: fixed;
}
<div class="parent">
<div class="kid"></div>
<p></p>
</div>
Basically you can't make a fixed position element bubble up it's parent scroll event.
Using JavaScript you can still handle the wheel
event and trigger it to the parent element:
const fixedElts = document.querySelectorAll('nav a');
const parentElt = document.querySelectorAll('main');
const bubbleFixedScroll = e => {
if(e.deltaMode){
parentElt.scrollTop += e.deltaY;
}
};
fixedElts.forEach( fixedElt => {
fixedElt.addEventListener('wheel', bubbleFixedScroll)
});
Of course the delta value can be adapted for a smother scrolling. Also some throttling can be added to prevent to much handlers to be executed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With