I have a page where a scroll bar containing table rows with divs in them is dynamically generated from the database. Each table row acts like a link, sort of like you\'d see
Get correct y
coordinate and use window.scrollTo({top: y, behavior: 'smooth'})
const id = 'profilePhoto';
const yOffset = -10;
const element = document.getElementById(id);
const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;
window.scrollTo({top: y, behavior: 'smooth'});
Based on the answer of Arseniy-II: I had the Use-Case where the scrolling entity was not window itself but a inner Template (in this case a div). In this scenario we need to set an ID for the scrolling container and get it via getElementById
to use its scrolling function:
<div class="scroll-container" id="app-content">
...
</div>
const yOffsetForScroll = -100
const y = document.getElementById(this.idToScroll).getBoundingClientRect().top;
const main = document.getElementById('app-content');
main.scrollTo({
top: y + main.scrollTop + yOffsetForScroll,
behavior: 'smooth'
});
Leaving it here in case someone faces a similar situation!
Assuming you want to scroll to the divs that are all at the same level in DOM and have class name "scroll-with-offset", then this CSS will solve the issue:
.scroll-with-offset {
padding-top: 100px;
margin-bottom: -100px;
}
The offset from the top of the page is 100px. It will only work as intended with block: 'start':
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
What's happening is that the divs' top point is at the normal location but their inner contents start 100px below the normal location. That's what padding-top:100px is for. margin-bottom: -100px is to offset the below div's extra margin. To make the solution complete also add this CSS to offset the margins/paddings for the top-most and bottom-most divs:
.top-div {
padding-top: 0;
}
.bottom-div {
margin-bottom: 0;
}
Another solution is to use "offsetTop", like this:
var elementPosition = document.getElementById('id').offsetTop;
window.scrollTo({
top: elementPosition - 10, //add your necessary value
behavior: "smooth" //Smooth transition to roll
});
You can do it in two steps :
el.scrollIntoView(true);
window.scrollBy(0, -10); // Adjust scrolling with a negative value here
This solution belongs to @Arseniy-II, I have just simplified it into a function.
function _scrollTo(selector, yOffset = 0){
const el = document.querySelector(selector);
const y = el.getBoundingClientRect().top + window.pageYOffset + yOffset;
window.scrollTo({top: y, behavior: 'smooth'});
}
Usage (you can open up the console right here in StackOverflow and test it out):
_scrollTo('#question-header', 0);
I'm currently using this in production and it is working just fine.