Menu

Scroll an element into the center of the viewport

Published on by Hidde de Vries in code .

Say your page displays a list of names and you want a certain person to be highlighted and scrolled into view. There’s a browser API for that: Element.scrollIntoView(), which scrolls an element into view.

Element.scrollIntoView() can take two types of elements: a boolean or an object. The object argument gives developers more control over how elements ‘in view’ are aligned, but has slightly less browser support. Let’s look at what we can do with both.

The boolean argument

Say, you have a couple of people in a list:

<ul>
  <li id="alice">Alice Cruz</li>
  <li id="daniel">Daniel Ho</li>
  …
  <li id="julie">Julie Howard</li>
  …
</ul>

(Example on Codepen)

If you want Julie to be scrolled into view, find the relevant element, then call scrollIntoView():

const julie = document.getElementById('julie');

julie.scrollIntoView();

This scrolls the element into view. With a boolean argument, you can have some control over alignment. If you pass true (default), the browser will scroll so that the element is at the top of your viewport or other scrollable element. With false, it scrolls so the element is at the bottom of the viewport:

julie.scrollIntoView(true) // align top
julie.scrollIntoView(false) // align bottom

Note that the underlying terminology is not ‘top’ or ‘bottom‘, I’ll get into that in the next section.

For most use cases, this boolean argument may be all you need. It lets you choose if you want the element to align top or bottom.

This isn’t always ideal, sometimes you may have a sticky header, so scrollling an element to the top of the document would not actually get it into view. If something like that is the case in your project, the object argument comes in handy. It gives more control over alignment and allows for smooth scroll.

The object argument

In the latest version, you can also pass Element.scrollIntoView() an object, which lets you set two things:

julie.scrollIntoView({
  behavior: smooth | auto;
  block: start | center | end | nearest;
  inline: start | center | end | nearest;
});

Smooth scroll

With the behavior parameter, you can set whether scrolling should be instant, so the page just jumps to the element, or smoothly, over a number of seconds (to be decided by the browser).

Unsurprisingly, the smooth value triggers smooth scroll. The auto value triggers instant scroll, as long as the element’s computed value for the scroll-behavior in CSS is not smooth.

Alignment

Where I’ve been saying ‘top’ and ‘bottom’, I should have said ‘start‘ or ‘end’. They are the logical properties that you might recognise from other recent CSS specs like Grid Layout and flexbox.

As a quick reminder, the inline direction is the direction in which your text runs: it is the direction in which the words of this article are added. The block direction is the opposite of that, it is where block level elements are stacked, or where paragraphs of this text are added.

In a page with a vertical scrollbar, on the block axis, start means top, end means bottom. That’s the case on this page, for instance. But if your page uses vertical writing mode, you’d scroll horizontally, like in Hui-Jing Chen’s example of Chinese typography; in those cases, start means right, end means left on the block axis.

Fallbacks can be tricky

All browsers that understand element.scrollIntoView() accept the boolean argument. But only some accept the object argument. The good thing is, browsers will fallback for you. The default for the boolean argument is true, which sets the equivalent to block: start. If you use the object argument to use block: center or block: end, browsers that don’t do the object argument, will regard the argument to be true (because objects are truthy). So you’ll end up with block: start in those browsers. That’s often great, except when it is the opposite of what you’re fallbacking for.

If your interface requires precisely control over scroll alignment, fallbacks can be tricky. As an alternative you can also roll your own alignment with element.scrollTo(), as Jan Hoogeveen pointed out (thanks Jan!). If you end up going for that, I would recommend using coordinates as an argument, as the object argument does not work in some recent browsers, including Edge. See also window.scrollTo on MDN.

In the works: scroll snap

If you find scrollIntoView interesting, you may be interested in Scroll Snap, too. This is new CSS, currently being worked on, which lets you define things like a padding for the scroll container. Rachel Andrew has written a guide on the basic concepts of Scroll Snap on MDN. Some of the properties are already available in some browsers.

Comments & mentions (21)

Chris Heilmann replied: Scroll an element into the center of the viewport hiddedevries.nl/en/blog/2018-1…
David liu replied: RT codepo8: Scroll an element into the center of the viewport hiddedevries.nl/en/blog/2018-1…
Web Platform News replied: Scrolling an element into the center of the viewport:

elem.scrollIntoView({ block: 'center' });

Safari and Edge don’t support this option and fall back to aligning the element to the top of the viewport.
Ilya Streltsyn replied: Оказывается, теперь можно делать scrollIntoView не только к верхнему/нижнему краю окна, но и к центру — через объектную нотацию (правда, с фолбэками есть нюансы)
CSS Basics replied: Heading structures are tables of contents, by @hdv hiddedevries.nl/en/blog/2018-0…
CSS Basics replied: Heading structures are tables of contents, by @hdv hiddedevries.nl/en/blog/2018-0…
Marc Stalfoort likes this
Anselm Hannemann likes this
Jan Hoogeveen likes this
Koen Kivits likes this
TvGeest likes this
Scott O'Hara likes this
Designer+Developer Day replied: [For Developer - JS] Scroll an element into the center of the viewport.

hiddedevries.nl/en/blog/2018-1…?
Designer+Developer Day replied: [For Developer - performance] Up to speed with web performance. hiddedevries.nl/en/blog/2018-1…
Unknown replied: Scroll an element into the center of the viewport - no weighty frameworks or additional markup. » (https://hiddedevries.nl/en/blog/2018-12-10-scroll-an-element-into-the-center-of-the-viewport)
Calum Ryan | calumryan.com replied: Scroll an element into the center of the viewport - no weighty frameworks or additional markup. » (hiddedevries.nl/en/blog/2018-1…) (calumryan.com/note/2251)
CSS-Tricks replied: Scroll an element into the center of the viewport hiddedevries.nl/en/blog/2018-1…
HTML & CSS replied: css: Scroll an element into the center of the viewport hiddedevries.nl/en/blog/2018-1…
Mr. HAW ✪ replied: Scroll an element into the center of the viewport hiddedevries.nl/en/blog/2018-1… #js #webdesign
Momin Riyadh replied: Scroll an element into the center of the viewport !

hiddedevries.nl/en/blog/2018-1… https://t.co/3gdAYUs0OI
rajakvk replied: Nice method, never knew before !!!
Scroll an element into the center of the viewport
hiddedevries.nl/en/blog/2018-1…
Leave a comment
Posted a response to this?

This website uses Webmentions. You can manually notify me if you have posted a response, by entering the URL below.