ページ内リンクをスムーズスクロールで行いたい場合はどのようにすればよいでのしょうか?

jQueryを利用すれば簡単に対応できますが、非jQueryの案件ですと悩みものです。

筆者は12年前にjQuery非依存のスムーズスクロールのJavaScriptライブラリ「smoothScroll.js」をリリースしていますがお世辞にも今の時代に利用するのに適したライブラリではありません。

今回は2019年に適したスムーズスクロールの方法をご紹介いたします。

CSSでスムーズスクロール

もっとも簡単に利用できるのはCSSのみでスムーズスクロールを実装する方法です。
html要素に scroll-behavior: smooth; を適用することでページ内リンクがスムーズスクロールに変化します。

以下は実際に適用した簡単なサンプルです。

動作サンプル / スクリプト

すごく便利ですが対応ブラウザが少し限定的です。主なブラウザではChrome(Android含む)とFirefoxのみで、IE11はもちろんのことMS Edge、Safariにも対応していません。プログレッシブ エンハンスメントとして対応ブラウザにのみ適用できる要件でないと利用は難しいでしょう。

参考:scroll-behavior – CSS: カスケーディングスタイルシート | MDN

また、すべてのスクロールがスムーズスクロールに変わってしまうのでSPAのようにページ遷移ごとにスクロール位置の調整が必要な場合にスムーズスクロールになってしまい微妙な挙動になってしまいます。

JavaScriptでスムーズスクロール

個人的にはJavaScriptで制御する方法がお薦めです。

scrollIntoViewでスクロール

scrollIntoView は指定した要素が画面内に収まるようにスクロールさせるためのメソッドです。

スクロール位置に設定したい要素に対して実行でき、オプションで behaviorsmooth に、 blockstart に設定することで先程のCSSと同じような挙動にすることができます。

以下はclass属性「js-smooth-scroll」がある要素がクリックされた場合にスムーズスクロールされるようにしたサンプルです。

動作サンプル / スクリプト

こちらも対応ブラウザが限定的です。主なブラウザではChrome(Android含む)とFirefoxのみで、IE11はもちろんのことMS Edge、Safariにも対応していません。(メソッド自体は存在するのでエラーにはならないのですがオプションの指定が無視されます。)

参考: Element.scrollIntoView() – Web API | MDN

ただし、smooth scroll behavior polyfillというpolyfillパッケージが公開されておりこちらを読み込むことで以下のモダンブラウザでもスムーズスクロールが実現可能です。

  • Safari 6+
  • Internet Explorer 9+
  • Microsoft Edge 12+

polyfill を利用するには npm よりパッケージのインストールを行い

利用したい箇所で読み込んで実行するだけで上記のブラウザでbehaviorオプションが有効になります。

以下がpolyfillを読み込んだバージョンです。

動作サンプル / コード

多くのケースではこれで事足りるでしょう。

window.scrollでスクロール

scrollIntoViewでは細かい制御ができません。例えば指定した要素の50px上の位置に移動したいなどといった対応ができません。

そういった場合は古くから利用されている window.scroll() でスクロールを行います。

window.scroll() でもbehaviorオプションが利用できるようになっておりスムーズにスクロールさせることが可能です。

例えば、以下のようにすると目的の要素の50px上部までスクロールして移動が可能です。

以下はclass属性「js-smooth-scroll」がある要素がクリックされた場合にスムーズスクロールされるようにしたサンプルです。(別ウィンドウで確認)

動作サンプル / コード

このように最近ではブラウザのネイティブの機能でスムーズスクロールが利用でき、対応していないブラウザでもpolyfillを導入することで可能になっていますのでこれらを利用するのがよいでしょう。