I'm trying to use scrollIntoView() in my application, but because I have a top fixed bar, when I use the scrollIntoView(), the elements will be scroll to the fixed bar back.
This means that when I try to put some element visible to the user, by scrolling the element to a visible area, it will be scrolled, but to another invisible ate that is were this fixed bar is.
Follows an example of what I'm trying to do:
let element = document.getElementsByClassName('second-element')[0]; element.scrollIntoView();.fixed-element{ height: 30px; width: 100%; background-color:black; position:fixed; } .parent-element { width: 100%; height: 40000px; background-color:blue; } .element { width: 100%; height:100px; background-color: yellow; margin-top:10px; } .second-element{ width: 100%; background-color: red; height:200px; }<div></div> <div class='parent-element'> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='second-element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> <div class='element'></div> </div>There is any way that I could use this function in a way that the scroll elements not became invisible because of the fixed bar?
I would like a vanilla JavaScript solution. Also, and only if it is possible, a solution that doesn't need to know the existent of any fixed elements.
5 Answers
You can make the window scrollTo x position 0 and y position the element's offsetTop subtracted by the fixed element's offsetHeight.
.header{ position: fixed; background-color: green; width: 100%; top: 0; left: 0; right: 0; } html, body{ height: 1000px; } #toBeScrolledTo{ position: relative; top: 500px; }<div> Header </div> <div> Text Text Text </div> <script> window.scrollTo(0, document.getElementById('toBeScrolledTo').offsetTop - document.getElementsByClassName('header')[0].offsetHeight); </script>Your question is answered in this link.
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); } Also you can use this way:
let item = // what we want to scroll to let wrapper = // the wrapper we will scroll inside let count = item.offsetTop - wrapper.scrollTop - xx // xx = any extra distance from top ex. 60 wrapper.scrollBy({top: count, left: 0, behavior: 'smooth'}) 2Try scroll padding. It is not a JavaScript solution (it is a CSS property) but it can be helpful with your problem.
2A great simple solution (inspired by Sanyam Jain's comment in this link) is to use {block: 'center'} to vertically center the selection like this:
scrollIntoView({block: 'center'}) Edit - I sadly found on MDN page that this features is 'experimental - should not be used in production'. Also, IE doesn't support it (if that's a need).
This is 2021, so you could solve this by just using scroll-margin-top. It exists for this express purpose!
