- Native Smooth Scroll with pure CSS and JS
- Link
- Link
- Link
- Link
- Link
- Link
- Link
- Link
- Link
- Link
- Link
- Smooth scroll with javascript
- Плавный скролл до якоря.
- 1. Плавный скролл с используя jQuery
- 2. Плавный скролл для всех ссылок, начинающихся с #
- 3. Плавный скролл на чистом JavaScript — метод Element.scrollIntoView()
- 4. Плавный скролл на чистом JavaScript — метод Window.scrollBy()
Native Smooth Scroll with pure CSS and JS
Do you want a smooth scroll? Forget JQuery, we’re past that. Let me introduce you to our tools for a native smooth scroll.
Link
The CSS scroll-behavior property accepts one of three values – or two, actually, since one of those was deprecated.
- scroll-behavior: auto is the default instant scrolling behavior that we’re already used to.
- scroll-behavior: instant is the same as auto , which is why it was deprecated. If you want it, just use auto .
- scroll-behavior: smooth applies a smooth transition when a scroll event is programmatically triggered.
I say «programmatically triggered» because it’s not going to smooth scroll the mouse wheel.
Some ways of programmatically triggering a scroll event are through:
- Window.scrollTo() - Window.scrollBy() - Element.scrollTo() - Element.scrollBy() - Element.scrollIntoView() - Element.scrollLeft = x - Element.scrollTop = y
- Window.scrollTo() - Window.scrollBy() - Element.scrollTo() - Element.scrollBy() - Element.scrollIntoView() - Element.scrollLeft = x - Element.scrollTop = y
We’ll explore these methods individually.
Link
(Note) Window.scroll() and Element.scroll()
Maybe you’ve noticed that I haven’t mentioned the scroll() method.
That’s because Window.scroll() and Element.scroll() are effectively the same methods as Window.scrollTo() and Element.scrollTo() . To avoid duplicate content, I’ll just refer to scrollTo() . In practice, you can use either, just choose one and be consistent.
Link
Window.scrollTo() and Element.scrollTo()
This method is ideal for scrolling to absolute coordinates. If you have the x and y coordinates for where you want to scroll the user to, you can simply call window.scrollTo(x, y) and it’ll respect the CSS scroll-behavior of the page .
The same applies to scrollable elements. You simply call element.scrollTo(x, y) and it’ll respect the CSS scroll-behavior of the element.
There’s also a new signature for this method, which uses an object instead of two numeric arguments, and with this new signature, we can explicitly set our scroll behavior.
// For window window.scrollTo(< left: x, top: y, behavior: 'smooth' >); // For element const el = document.querySelector(. ); el.scrollTo(< left: x, top: y, behavior: 'smooth' >);
// For window window.scrollTo( left: x, top: y, behavior: 'smooth' >); // For element const el = document.querySelector(. ); el.scrollTo( left: x, top: y, behavior: 'smooth' >);
Link
Element.scrollLeft and Element.scrollTop
Setting the element .scrollLeft and .scrollTop properties is the same as calling Element.scrollTo() with the coordinates. It’ll respect the CSS scroll-behavior of the element.
const el = document.querySelector(. ); const x = 100; const y = 500; // Setting .scrollLeft and .scrollTop with smooth scroll el.style.scrollBehavior = 'smooth'; el.scrollLeft = x; el.scrollTop = y; // Is the same as calling Element.scrollTo() el.scrollTo(< left: x, top: y, behavior: 'smooth' >);
const el = document.querySelector(. ); const x = 100; const y = 500; // Setting .scrollLeft and .scrollTop with smooth scroll el.style.scrollBehavior = 'smooth'; el.scrollLeft = x; el.scrollTop = y; // Is the same as calling Element.scrollTo() el.scrollTo( left: x, top: y, behavior: 'smooth' >);
Link
(Note) Negative Element.scrollLeft
If the direction of your element’s text is rtl , scrollLeft = 0 marks the rightmost position of the horizontal scroll, and the value decreases as you go to the left.
For a scrollable element with 100px of width, 500px of scrollable width and direction rtl , the leftmost position is scrollLeft = -400 .
div id="scrollable" style="width: 100px; overflow: auto" dir="rtl"> div style="width: 500px; height: 100px; background: green">div> div> p id="output">p>
const scrollable = document.querySelector('#scrollable'); const output = document.querySelector('#output'); const updateOutput = () => < output.textContent = `scrollLeft: $`; >; updateOutput(); scrollable.addEventListener('scroll', updateOutput);
const scrollable = document.querySelector('#scrollable'); const output = document.querySelector('#output'); const updateOutput = () => output.textContent = `scrollLeft: $scrollable.scrollLeft>`; >; updateOutput(); scrollable.addEventListener('scroll', updateOutput);
Link
Window.scrollBy() and Element.scrollBy()
This method has the exact same signatures as Window.scrollTo() or Element.scrollTo() . It accepts either x and y as two numeric arguments or a single argument being an object with the optional left , top , and behavior properties.
The difference here is that we’re not passing absolute coordinates, but relative values instead. If we scrollBy(< top: 10 >) , we’re scrolling 10 pixels down from where we currently are, not 10 pixels down from the beginning of the page.
// For window window.scrollBy(< top: 10 >); // Scroll 10px down window.scrollBy(< left: 20 >); // Then 20px to the right window.scrollBy(< top: 50 >); // And then 50px down // For element const el = document.querySelector(. ); el.scrollBy(< top: 10 >); // Scroll 10px down el.scrollBy(< left: 20 >); // Then 20px to the right el.scrollBy(< top: 50 >); // And then 50px down
// For window window.scrollBy( top: 10 >); // Scroll 10px down window.scrollBy( left: 20 >); // Then 20px to the right window.scrollBy( top: 50 >); // And then 50px down // For element const el = document.querySelector(. ); el.scrollBy( top: 10 >); // Scroll 10px down el.scrollBy( left: 20 >); // Then 20px to the right el.scrollBy( top: 50 >); // And then 50px down
Link
(Note) Window.scrollByLines() and Window.scrollByPages()
Firefox goes a little further by implementing methods to scroll by a number of lines or pages. It’s a non-standard feature that only works on Firefox, so you probably don’t want to use it in production.
You can achieve a similar effect in all major browsers by converting 100vh (for a page) and 1rem (for a line) to pixels and passing that value to Window.scrollBy() .
const toPixels = require('to-px'); // From NPM const page = toPixels('100vh'); window.scrollBy(0, page); // window.scrolByPages(1) const line = toPixels('1rem'); window.scrollBy(0, line); // window.scrolByLines(1)
const toPixels = require('to-px'); // From NPM const page = toPixels('100vh'); window.scrollBy(0, page); // window.scrolByPages(1) const line = toPixels('1rem'); window.scrollBy(0, line); // window.scrolByLines(1)
Link
Most of the time though, we don’t care about any hardcoded coordinates, we just want to scroll the user to a specific element on the screen. This can easily (and more explicitly) be done with Element.scrollIntoView() .
This method can be called with no arguments, that’ll scroll the page (respecting the CSS scroll-behavior ) until the element is aligned at the top (unless the element is at the bottom of the page, in that case, it’ll scroll as much as possible).
Some space Our element More space
div style="height: 2000px">Some spacediv> div id="target" style="background: green">Our elementdiv> div style="height: 500px">More spacediv>
const target = document.querySelector('#target'); target.scrollIntoView();
const target = document.querySelector('#target'); target.scrollIntoView();
You can further customize the element’s placement in the view by passing a boolean or an object.
const el = document.querySelector(. ); // Default, aligns at the top el.scrollIntoView(true); // Aligns at the bottom el.scrollIntoView(false); // Aligns vertically at the center el.scrollIntoView(< block: 'center' >); // Vertical top and horizontal center el.scrollIntoView(< block: 'start', inline: 'center' >); // Vertical bottom and horizontal right el.scrollIntoView(< block: 'end', inline: 'end' >); // Vertical center and smooth el.scrollIntoView(< block: 'center', behavior: 'smooth' >); // Vertical nearest el.scrollIntoView(< block: 'nearest' >);
const el = document.querySelector(. ); // Default, aligns at the top el.scrollIntoView(true); // Aligns at the bottom el.scrollIntoView(false); // Aligns vertically at the center el.scrollIntoView( block: 'center' >); // Vertical top and horizontal center el.scrollIntoView( block: 'start', inline: 'center' >); // Vertical bottom and horizontal right el.scrollIntoView( block: 'end', inline: 'end' >); // Vertical center and smooth el.scrollIntoView( block: 'center', behavior: 'smooth' >); // Vertical nearest el.scrollIntoView( block: 'nearest' >);
When using an object to define the element’s placement, note that block refers to the vertical placement and inline refers to the horizontal placement. Also, the ‘nearest’ placement can be the top/left or the bottom/right, whichever is nearest, and it can also be nothing if the element is already in view.
Link
As of this writing, all major browsers – except Safari – support smooth scroll and the scrolling methods described in this article.
If you need more reassurance, there’s a very good smooth scroll polyfill that I use in my projects. It polyfills scroll() , scrollTo() , scrollBy() , scrollIntoView() and the CSS scroll-behavior . It does not support smooth scrolling by setting scrollLeft / scrollTop and it does not support the scrollIntoView() options (it always aligns the element at the top).
If you have more curiosity, I highly suggest studying the polyfill’s source code, it’s less than 500 lines in total. I made a PR to slightly improve the docs, you might find the code easier to understand with it.
Link
References for everything I’ve said and an article with demos for you to play with are in the references below.
Have a great day and see you soon.
Link
Join our Newsletter and be the first to know when I launch a course, post a video or write an article.
© 2019-2023 Lucas Paganini. All rights reserved.
Smooth scroll with javascript
Разработаем следующее: после клика по ссылке будет происходить плавный скролл до элемента на JavaScript. Реализуем это без использования плагинов, сначала при помощи библиотеки jQuery, а затем на чистом JavaScript
Плавный скролл до якоря.
- С помощью jQuery .
- Для всех ссылок, начинающихся с # .
- На чистом JavaScript — метод Element.scrollIntoView() .
- На чистом JavaScript — метод Window.scrollBy() .
Сначала в HTML реализуем обычный «грубый» переход к секции, а затем уже добавим jQuery для создания плавности скролла.
Добавим codeid секциям к которым мы хотим выполнять скролл, а ссылкам атрибут codehref в формате code#name . Решетка — означает идентификатор (id), а name — имя идентификатора.
Наш HTML файл получится примерно такой.
Атрибут href указывает к какому элементу необходимо осуществить переход.
1. Плавный скролл с используя jQuery
$('.scrollto a').on('click', function() < let href = $(this).attr('href'); $('html, body').animate(< scrollTop: $(href).offset().top >, < duration: 370, // по умолчанию «400» easing: "linear" // по умолчанию «swing» >); return false; >);
Чтобы добавить плавность перехода для необходимого элемента, просто добавьте навигации класс scrollto
Изменить скорость скролла можно поменяв значение duration
2. Плавный скролл для всех ссылок, начинающихся с #
Для этого мы обратимся к селектору атрибута тега a при помощи ^ — что будет означать, что мы выбираем все ссылки, начинающиеся с # (решётки)
$('a[href^="#"').on('click', function() < let href = $(this).attr('href'); $('html, body').animate(< scrollTop: $(href).offset().top >); return false; >);
3. Плавный скролл на чистом JavaScript — метод Element.scrollIntoView()
Будем использовать метод scrollIntoView(). Это стандартный нативный метод JavaScript.
const smoothLinks = document.querySelectorAll('a[href^="#"]'); for (let smoothLink of smoothLinks) < smoothLink.addEventListener('click', function (e) < e.preventDefault(); const document.querySelector(id).scrollIntoView(< behavior: 'smooth', block: 'start' >); >); >;
У метода scrollIntoView() есть недостаток.
Если у нас будет навигация position: fixed , то нам необходимо добавить отступ сверху на x-пикселей , т.е. высоту навигации .
Для решения данной задачи отлично подойдёт метод Window.scrollBy() .
4. Плавный скролл на чистом JavaScript — метод Window.scrollBy()
Метод Window.scrollBy() имеет параметр top в котором мы укажем количество пикселей, на сколько нам необходимо прокрутить страницу.
От общей высоты документа отнимем высоту навигации и получим необходимое смещение в пикселях по оси Y .
document.querySelectorAll('a[href^="#"').forEach(link => < link.addEventListener('click', function(e) < e.preventDefault(); let href = this.getAttribute('href').substring(1); const scrollTarget = document.getElementById(href); const topOffset = document.querySelector('.scrollto').offsetHeight; // const topOffset = 0; // если не нужен отступ сверху const elementPosition = scrollTarget.getBoundingClientRect().top; const offsetPosition = elementPosition - topOffset; window.scrollBy(< top: offsetPosition, behavior: 'smooth' >); >); >);
Если нужен отступ сверху, укажите class элемента (навигации), чтобы вычислить его высоту. Если не нужен отступ, переменной topOffset присвойте значение 0 .