Using scrollIntoView with a fixed position header
It's a bit hacky but here's a workaround.
var node = 'select your element';
var yourHeight = 'height of your fixed header';
// scroll to your element
node.scrollIntoView(true);
// now account for fixed header
var scrolledY = window.scrollY;
if(scrolledY){
window.scroll(0, scrolledY - yourHeight);
}
Edit:
A modern workaround is to use the CSS scroll-margin-top
property in combination with the :target
selector. Described in detail: https://www.bram.us/2020/03/01/prevent-content-from-being-hidden-underneath-a-fixed-header-by-using-scroll-margin-top/
scrollintoview() blocked by sticky Navbar
You have to leave some pixels from top so that the content will appear to start from the bottom of navbar. In this case padding-bottom
worked.
function scrollToView(id){ var top = document.getElementById(id).offsetTop-document.getElementById("nav").offsetHeight-10; //show 10 pixels down the border window.scrollTo(0, top);}
<div style="height:90px; border: 1px solid red; background-color: grey; position: fixed; width: 100%;" id="nav">Navbar</div>
<div id="A" style="padding-top: 100px">This text will blocked by sticky navbar<br/>A<br/><br/><br/><br/><br/>---</div>
<div id="B">This text will blocked by sticky navbar<br/>B<br/><br/><br/><br/><br/>---</div>
<br/><br/><br/><br/><br/><br/><br/><div id="C">This text will blocked by sticky navbar<br/>C<br/><br/><br/><br/><br/>---</div>
<button onClick="scrollToView('A')">A</button><button onClick="scrollToView('B')">B</button>
How to move an element to just below a fixed header
After scrollIntoView()
, push it down by 50px, using something like this:
scrollBy(0, -50);
Scroll into view element hides behind header
I believe you need to apply the styles to the outer container that is wrapping the container you want scrollable. This is the div
rendering both the fixed position header and the content.
To the outer div
- Add the
margin-top: 100px
to push content down. - Set a height that restricts the content from just expanding the height automatically,
height: calc(100vh - 100px)
, the height of the view window minus the height of the header. Note: In the codesandbox I tweaked to99vh
to keep the window's scrollbar from appearing, so you'll likely need to tweak these values for your real code. - Hide the overflowing content and automatically display scrollbars when overflow occurs,
overflow: auto
. - Remove the in-line
style
prop from the inner contentdiv
.
Code
<div
style={{
marginTop: "100px",
height: "calc(99vh - 100px)",
overflow: "auto"
}}
>
{/* Nav */}
<div id="container">
<div className="_2iA8p44d0WZ">
// content
</div>
</div>
{/* fieldsets */}
</div>
scrollIntoView() is not working: does not taking in account fixed element
You can make the window scrollTo
x position 0
and y position the element's offsetTop
subtracted by the fixed element's offsetHeight
.
JSFiddle with your code: http://jsfiddle.net/3sa2L14k/
.header{ position: fixed; background-color: green; width: 100%; top: 0; left: 0; right: 0;}html, body{ height: 1000px;}
#toBeScrolledTo{ position: relative; top: 500px;}
<div class="header">Header</div><div id="toBeScrolledTo">Text Text Text</div><script>window.scrollTo(0, document.getElementById('toBeScrolledTo').offsetTop - document.getElementsByClassName('header')[0].offsetHeight);</script>
How to automatically scroll to a div section when you have a fixed header
The problem is that your navbar is covering the top of the div. You can avoid this by using window.scrollBy()
and offsetHeight
to scroll the window up again by the height of the navbar. This solution has the advantage that it does not require you to know what height your navbar will be to start with, so it allows for various different browser configurations.
function headerClick(elem) {
if (elem.innerHTML === 'One') {
document.getElementById("One").scrollIntoView();
window.scrollBy(0, -(elem.offsetHeight)-2)
}
if (elem.innerHTML === 'Two') {
document.getElementById("Two").scrollIntoView();
window.scrollBy(0, -(elem.offsetHeight)-2)
}
if (elem.innerHTML === 'Three') {
document.getElementById("Three").scrollIntoView();
window.scrollBy(0, -(elem.offsetHeight)-2)
}
if (elem.innerHTML === 'Four') {
document.getElementById("Four").scrollIntoView();
window.scrollBy(0, -(elem.offsetHeight)-2)
}
if (elem.innerHTML === 'Five') {
document.getElementById("Five").scrollIntoView();
window.scrollBy(0, -(elem.offsetHeight)-2)
}
}
The extra -2 is to ensure that the div border can be seen, but you can delete that if it's not needed.
scrollIntoView Scrolls just too far
If it's about 10px, then I guess you could simply manually adjust the containing div
's scroll offset like that:
el.scrollIntoView(true);
document.getElementById("containingDiv").scrollTop -= 10;
JavaScript scrollIntoView smooth scroll and offset
Is there a way to have an offset and make it scroll smoothly?
#Yes, but not with scrollIntoView()
The scrollIntoViewOptions of Element.scrollIntoView() do not allow you to use an offset. It is solely useful when you want to scroll to the exact position of the element.
You can however use Window.scrollTo() with options to both scroll to an offset position and to do so smoothly.
If you have a header with a height of 30px
for example you might do the following:
function scrollToTargetAdjusted(){
var element = document.getElementById('targetElement');
var headerOffset = 45;
var elementPosition = element.getBoundingClientRect().top;
var offsetPosition = elementPosition + window.pageYOffset - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: "smooth"
});
}
This will smoothly scroll to your element just so that it is not blocked from view by your header.
Note: You substract the offset because you want to stop before you scroll your header over your element.
#See it in action
You can compare both options in the snippet below.
<script type="text/javascript">
function scrollToTarget() {
var element = document.getElementById('targetElement');
element.scrollIntoView({
block: "start",
behavior: "smooth",
});
}
function scrollToTargetAdjusted() {
var element = document.getElementById('targetElement');
var headerOffset = 45;
var elementPosition = element.getBoundingClientRect().top;
var offsetPosition = elementPosition + window.pageYOffset - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: "smooth"
});
}
function backToTop() {
window.scrollTo(0, 0);
}
</script>
<div id="header" style="height:30px; width:100%; position:fixed; background-color:lightblue; text-align:center;"> <b>Fixed Header</b></div>
<div id="mainContent" style="padding:30px 0px;">
<button type="button" onclick="scrollToTarget();">element.scrollIntoView() smooth, header blocks view</button>
<button type="button" onclick="scrollToTargetAdjusted();">window.scrollTo() smooth, with offset</button>
<div style="height:1000px;"></div>
<div id="targetElement" style="background-color:red;">Target</div>
<br/>
<button type="button" onclick="backToTop();">Back to top</button>
<div style="height:1000px;"></div>
</div>
Related Topics
Cannot Open Local File - Chrome: Not Allowed to Load Local Resource
How to Convert Uint8 Array to Base64 Encoded String
How to Redirect to Another Component Onsubmit Search
Force Facebook to Open Link in External Browser for Smart Phones
Export Array of Objects into Excel Using JavaScript
Add and Remove Values Inside Array in Change Event of Checkbox
React .Map() Is Not a Function Error
Jquery Datatables: Hide Search Bar
Change Value of a Variable Inside Foreach Loop? Make It Available Outside the Loop
How to Push Array in Array in Angular
How to Replace All Words of Length Less Than 3 in a String With " " (Space) in JavaScript
How to Validate Mobile Number for Countries in Angular
How to Monitor Changes to an Object
Increase JavaScript Heap Size in Create-React-App Project
How to Get Parent Width/Height in React Using Hooks
How to Prevent a Key Input from Appearing in Input Field
How to Reset Child Elements' State
React Hooks Error: Hooks Can Only Be Called Inside the Body of a Function Component