简体   繁体   中英

Centering Scroll to Element to via # ? (without modifying the DOM / using refs)

I would like to scroll to a certain element via # :

<a href="#element">Element</a>

<div name="element" />

It accomplishes this quite well, but it goes to the very top of the element. However, I'd like the element scrolled to to be centered for the user.

I am hesitant to use Javascript's scrollTo or other, external libraries, since I will need to use this functionality a lot (very, very much). I am using React and don't want to overuse refs and slow down my app. So I'd like to accomplish this with HTML only, preferably. JS is fine too, of course, but most solutions I came across modify the DOM and/or use refs .

There is probably a better/cleaner way to do it, but with only html/css, the only thing that I think about is to use a hidden span under your div element, like so:

 html { scroll-behavior: smooth; } .space { width: 100%; height: 400px; background-color: blue; } #element { position: relative; top: -50vh; visibility: hidden; } 
 <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <a href="#element">Element</a> <div class="space"></div> <p> some text </p> <div class="space"></div> <p> some text </p> <div class="space"></div> <div> <p> Your element </p> <span id="element">anchor </span> </div> <div class="space"></div> </body> </html> 

AFAIK, no way to achieve your desirable effect without a bit of js. As for "centered", then some calculation is needed.

 <html> <head> <title>Document</title> <style> .placeholder { height: 1000px; } </style> <script> function scrollToDest(event) { var id = event.target.getAttribute("href"); if (id.charAt(0) !== "#") return; // not a valid <a> element var dest = document.getElementById(id.substr(1)); if (!dest) return; // no destination found; event.preventDefault(); // calculate the top and bottom margin remained when dest is centered var margin = window.innerHeight - dest.clientHeight; // what if the dest's height is larger than viewport? if (margin < 0) margin = 0; window.scroll({ left: 0, top: dest.offsetTop - margin / 2, behavior: "smooth" }); } </script> </head> <body> <div class="placeholder"> <a href="#dest" onclick="scrollToDest(event)">Let's go!</a> </div> <div id="dest">ARRIVAL</div> <div class="placeholder"></div> </body> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM