1

You can scroll to an element using a url with a hashtag and the elements ID:

window.location.href = "#ID"

This will scrol so that the top of the element is at the top of the browser. How would I scroll to an element so that it's vertically centered?

1
  • Why close it anyone? Commented Oct 29, 2014 at 8:16

3 Answers 3

1

you can scroll up right after the navigation happens:

addEventListener("hashchange", function(){
    setTimeout(function(){ 
          document[
             document.documentElement.scrollTop ? 
             "documentElement":
             "body"
          ].scrollTop-= (innerHeight/2.1);
     }, 1); 
}, false);

this will cause the focused element to appear half-way up the screen, vertically centered. the 2.1 causes it to scroll just under half the screen, since there will be some room at the top already. you can adjust the ".1" to match your desired effect (baseline, middle, etc).

obligatory fiddle link: http://jsfiddle.net/ckhafLzq/2/

Sign up to request clarification or add additional context in comments.

4 Comments

innerHeight is the height in pixels of the current viewport, what's not to understand?
dandavis in that case I've misunderstood your answer cause (innerHeight/2.1) will not center an item in the viewport. The math is really simple: scrollToElement - ((viewportHeight - elementHeight) / 2) ... or I'm missing something?
hm... your fiddle does not work in FF and also the OP asked for " to an element so that it's vertically centered?"
@RokoC.Buljan: silly quirks, here's one that works in firefox and chrome: jsfiddle.net/ckhafLzq/2 , thanks for the head's up!
1

This is what I have achieved:

function centerScroll(element) {
    if (!(element instanceof Element)) {
        throw new TypeError("Element expected");
    }

    var bodyRect = document.body.getBoundingClientRect();
    var elementRect = element.getBoundingClientRect();

    var left = elementRect.left - bodyRect.left;
    var top = elementRect.top - bodyRect.top;

    var windowWidth = window.innerWidth;
    var windowHeight = window.innerHeight;

    var elementWidth = element.offsetWidth;
    var elementHeight = element.offsetHeight;

    var x = left - Math.max(0, (windowWidth - elementWidth) / 2);
    var y = top - Math.max(0, (windowHeight - elementHeight) / 2);

    window.scrollTo(x, y);

    return [x, y];
}

Comments

0

No, there's no built-in way, you'd have to write that yourself:

function center_element_vertically(elt) {
    var rect = elt.getBoundingClientRect();
    window.scrollTo(0, rect.top + window.pageYOffset - 
        (window.innerHeight - rect.height)/2);
}

Alternatives without writing your own code: you could scroll so that the element was at the bottom by passing false to scrollIntoView, or scroll only if the element is not already visible by calling scrollIntoViewIfNeeded, available only in Chrome AFAIK.

9 Comments

And like how would I write such function?
By doing some computation involving the size and current position of the element (use getBoundingClientRect). Is your question literally "is there any way?", or is it actually "how do i?"?
Shouldn't ` + window.pageYOffset` be ` - document.getBoundingClientRect().top`?
document does not have a getBoundingClientRect method, it's a method on HTMLElement. Is there something wrong with window.pageYOffset?
Sorry, I meant document.body I wondered since I saw this: stackoverflow.com/questions/442404/… (See the most upvoted answer)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.