scrollIntoView() is not working: does not taking in account fixed element

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.

JSFiddle with your code:

.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'}) 

Source:

2

Try scroll padding. It is not a JavaScript solution (it is a CSS property) but it can be helpful with your problem.

MDN
CSS Tricks

2

A 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).

enter image description here

This is 2021, so you could solve this by just using scroll-margin-top. It exists for this express purpose!

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like