I have a nested child container and when I'm trying to scrollIntoView
it breaks the parent container. I'm not able to understand why it's acting like this. Please help me out in this.
Please have a look at the code below or on jsfiddle
function moveToTop() {
console.log('MOVE TO TOP::');
const child = document.getElementById('child');
child.scrollIntoView({
behavior: "smooth"
});
}
#parent {
background-color: blue;
padding: 10px;
height: 500px;
overflow: hidden;
display: flex;
flex-direction: column;
}
#scroller {
overflow: auto;
padding: 10px;
background-color: red;
flex-grow: 1;
}
#child {
height: 10000px;
background-color: green;
}
body {
overflow: hidden;
color: #fff;
font-weight: bold;
}
button {
position: fixed;
bottom: 20px;
width: 140px;
left: 20%;
right: 0;
}
<div id="parent">
PARENT
<div id="something">Something</div>
<div id="scroller">
CHILD
<div id="child">
GRAND CHILD
<button onclick="moveToTop()">Top</button>
</div>
</div>
</div>
I have a nested child container and when I'm trying to scrollIntoView
it breaks the parent container. I'm not able to understand why it's acting like this. Please help me out in this.
Please have a look at the code below or on jsfiddle
function moveToTop() {
console.log('MOVE TO TOP::');
const child = document.getElementById('child');
child.scrollIntoView({
behavior: "smooth"
});
}
#parent {
background-color: blue;
padding: 10px;
height: 500px;
overflow: hidden;
display: flex;
flex-direction: column;
}
#scroller {
overflow: auto;
padding: 10px;
background-color: red;
flex-grow: 1;
}
#child {
height: 10000px;
background-color: green;
}
body {
overflow: hidden;
color: #fff;
font-weight: bold;
}
button {
position: fixed;
bottom: 20px;
width: 140px;
left: 20%;
right: 0;
}
<div id="parent">
PARENT
<div id="something">Something</div>
<div id="scroller">
CHILD
<div id="child">
GRAND CHILD
<button onclick="moveToTop()">Top</button>
</div>
</div>
</div>
Share
Improve this question
edited Jan 29, 2021 at 12:48
deathstroke
asked Jan 29, 2021 at 11:43
deathstrokedeathstroke
6037 silver badges19 bronze badges
7
- 1 What means - "it breaks the parent container"? – s.kuznetsov Commented Jan 29, 2021 at 11:50
-
It means when you fire a
scrollIntoView
event the scroll breaks into parent view although the overflow was in child. If you see jsfiddle you can get a better idea about what I'm trying to say. I'm sorry for the bad english. – deathstroke Commented Jan 29, 2021 at 11:53 -
But I don't see any problem in your code.
scrollIntoView
works like that - scrolls to the top of the specified item. Everything is correct. What general behavior do you want to see? – s.kuznetsov Commented Jan 29, 2021 at 11:59 - So we have a Parent, Child and Grand Child. When you click on the button, it breaks into the Parent. It should go to the top of Grand Child only. – deathstroke Commented Jan 29, 2021 at 12:06
- I think I understand your problem. The parent block hides at the top of the window after scrolling - ibb.co/fSjKV3p. So? – s.kuznetsov Commented Jan 29, 2021 at 12:17
1 Answer
Reset to default 7The whole problem is that scrollIntoView()
is moving the window. But since the #parent
overflow is hidden, when the window is moved, this element itself breaks. I could suggest setting a position: fixed
for the #parent
, which will solve your problem, but it can harm the layout in general.
Use the scroll()
method. The scrolling mechanism itself is:
scroller.scroll(0, child.offsetTop - 55);
child.offsetTop - top element;
55 - distance from the top of the #parent
to the top #scroller
.
The transition animation must be set to css, in selector #scroller
. Like that:
#scroller {
...
scroll-behavior: smooth;
}
function moveToTop() {
console.log('MOVE TO TOP::');
const child = document.getElementById('child');
const scroller = document.getElementById('scroller');
scroller.scroll(0, child.offsetTop - 55);
}
#parent {
background-color: blue;
padding: 10px;
height: 500px;
overflow: hidden;
display: flex;
flex-direction: column;
}
#scroller {
overflow: auto;
padding: 10px;
background-color: red;
flex-grow: 1;
scroll-behavior: smooth;
}
#child {
height: 10000px;
background-color: green;
}
body {
overflow: hidden;
color: #fff;
font-weight: bold;
}
button {
position: fixed;
bottom: 20px;
width: 140px;
left: 20%;
right: 0;
}
<div id="parent">
PARENT
<div id="something">Something</div>
<div id="scroller">
CHILD
<div id="child">
GRAND CHILD
<button onclick="moveToTop()">Top</button>
</div>
</div>
</div>