【CSSだけ】scroll-behaviorで超簡単にスムーススクロール実装する方法を徹底解説

【CSSだけ】scroll-behaviorで超簡単にスムーススクロール実装する方法を徹底解説

この記事の監修者

粟飯原匠 |プロデューサー

マーケティングを得意とするホームページ制作会社PENGINの代表。教育系スタートアップで新規事業開発を経験し、独立後は上場企業やレガシー産業のホームページ制作・SEO対策・CVR改善の支援を行うPENGINを創業。「ワクワクする。ワクワクさせる。」を理念に掲げてコツコツと頑張っています。

「ページ内のスムーススクロールができるようになりたい」と思い、JavaScriptやjQueryでの実装方法を調べようとしている方も多いと思います。

ただ、CSSだけで実現出来る「scroll-behavior」というプロパティがあるのをご存知ですか?

この記事を読んでほしい方
  • CSSだけでスムーススクロールがカンタンに実装してみたい
  • scroll-behaviorのデメリットを理解し、jsとの使い分けができるようになりたい

この記事を読んで、コーディングの幅を広げましょう!

scroll-behaviorとは

scroll-behaviorとは、ページ内リンクをクリックした際、該当箇所へ時間をかけてスクロールするイベント(スムーススクロール)を発生させるプロパティです。

scroll-behavior: smoothでスムーススクロール

scroll-behavior: smooth;

scroll-behaviorプロパティは、CSS1行だけでスムーススクロールが実現できます!

JavaScriptやライブラリのjQueryで実装する場合と比べて手軽なので、今後活用していきたいプロパティですね。

scroll-behaviorのブラウザ対応状況

引用:“scroll-behavior” | Can I use…

主要なブラウザの最新版ではほとんどが対応してますが、一部注意が必要です。

Safariには注意が必要

Safariではバージョン15.4からのみscroll-behaviorプロパティに対応しています。

iOSアップデート状況(Apple公式サイトより引用)
引用:App Store – Support – Apple Developer(2024.01時点)

Appleの公式サイトによると、全iPhoneデバイスの内6%程度はiOS14以前のバージョン利用者がいるようです。

国内のスマホはAppleのシェアが半数以上を占めているため、取り入れる場合は少し注意した方がいいかもしれません。

scroll-behaviorプロパティの構文

scroll-behaviorプロパティの初期値はautoで、スクロールスピードを変えるためにはsmoothを指定します。

/* 即時に遷移する */
html {
	scroll-behavior: auto;
}

/* ゆっくり遷移する */
html {
	scroll-behavior: smooth;
}

基本的にrootとなるhtmlタグに対して設定します。

ルート要素に指定することでビューポート(画面上)に適用されますが、bodyタグに指定してもビューポートには適用されません。

scroll-behaviorを使ったスムーススクロールのサンプル

上のサンプルの重要な部分のみ抜粋して解説します。

<header>
  <nav>
    <ul class="header-inner">
      <li><a href="#section1">section1</a></li>
      <li><a href="#section2">section2</a></li>
      <li><a href="#section3">section3</a></li>
      <li><a href="#section4">section4</a></li>
      <li><a href="#section5">section5</a></li>
    </ul>
  </nav>
</header>

固定ヘッダーのリンク(aタグ)にはアンカーリンクを設定します。

<main>
  <h2 id="section1" class="section">section1</h2>
  <h2 id="section2" class="section">section2</h2>
  <h2 id="section3" class="section">section3</h2>
  <h2 id="section4" class="section">section4</h2>
  <h2 id="section5" class="section">section5</h2>
  <p class="back-btn"><a href="#">Topに戻る</a></p>
</main>

次に遷移先にidでアンカーリンク名を設定します。

また、ページ右下のボタンリンク(aタグ)にはアンカーリンクではなく#だけ設定してページトップを指定します。

html {
	scroll-behavior: smooth;
}

デザイン部分は省略しますが(CodePenに記載あります)、CSSにはhtmlタグにscroll-vehavior: smoothを指定するだけです。

これだけでユーザーがページ内のリンクをクリックした際にスムーススクロールが実現できます。

scroll-behaviorの注意点

便利なscroll-behaviorプロパティですが注意点もあります。

すべてのページ内リンクがスムーススクロールになる

scroll-behaviorは文書のrootに設定するため、文書全体に対して制御がかかります。つまり、ページ内リンクはすべてスムーススクロールになります。

リンクによって挙動を設定できない点に注意しましょう。

移動速度の設定ができない

JavaScriptであればスクロールの移動スピードを指定できますが、scroll-behaviorプロパティでは速度を指定できません。

速度(イージング)はブラウザ依存となります。

遷移先の位置を指定できない

JavaScriptであれば移動先の位置を指定できますが、scroll-behaviorプロパティでは移動先の細かい位置は指定できません。

遷移先のブロックに対し、paddingやmarginなどで上方向に余白を設けることで調整する必要があります。

URLにアンカーリンクがつく

jsでスムーススクロールを実装した場合
JavaScriptのスムーススクロールだとURLは変化しない

上はJavaScript(jQuery)で実装したスムーススクロールですが、URLは変わりません。

CSSでスムーススクロールを実装した場合
scroll-behaviorだとURLにアンカーリンクが付与される

それに対し、scroll-behaviorプロパティで実装すると、上の画像のようにリンクをクリック時にURLにアンカーリンクが付与されます。

JavaScriptでURLの状態を取得するような機能がある場合、影響が出てしまう可能性はあります。

スクロール先がずれる時の対策

固定ヘッダーの場合、スクロール位置とヘッダーが被るなど、ズレが発生してしまうことがあります。

scroll-behaviorプロパティはスクロールするとアンカーポイントの位置をブラウザの一番上に表示しようとします。

スクロール先とヘッダーが被ってしまう例
スクロール先がヘッダーと被ってしまう例

対策していない場合、図のようにアンカーポイントを設定した部分がヘッダーの後ろに隠れて見えなくなってしまいます。

こちらの対策としてよく使われるのが、padding-top と margin-topのネガティブマージンで相殺する方法です。

.section {
	margin-top: -80px;
	padding-top: 80px;
}

この方法の場合、paddingで要素の大きさを広げる分、見た目上の余白もできてしまいます。

そこで使えるのが scroll-padding-top プロパティです。

.section {
	scroll-margin-top: 80px; /* 追記 */
}

遷移先にscroll-margin-topプロパティと任意の値を指定すると、スクロールしたときにだけ適用する余白を指定できます。

scroll-margin-topでズレを解消する例
scroll-margin-topでスクロール時のズレを解消

画像ではヘッダー高さが80pxだったため、scroll-margin-topにも同じ値を指定します。

見た目上の余白は変わっていませんが、スクロール時のみ余白が確保されることでズレが解消できています。

scroll-behaviorの代替案

scroll-behaviorでは理想の動作を実装する事ができないかもしれません。そんな時に知っておきたい代替案を2つ紹介します。

scroll-behaviorのpolyfill

「scroll-behavior-polyfill」というパッケージが配布されています。古いバージョンのブラウザに対応するときに利用できるでしょう。

次のページからCDNのファイルのURLを確認することができます。

<script src="https://cdn.jsdelivr.net/npm/scroll-behavior-polyfill@2.0.13/dist/index.min.js"></script>

こちらがCDNのコードです。

使い方はGitHubにも記載がありますが、インストールをしてJavaScriptのファイルで呼び出すと利用できます。

また、「smooth scroll behavior polyfill」のページで動作を確認することもできます。

js(jQuery)で実装する方法

コード量だけで見ると、jQueryで実装する方法もカンタンです。

$(function () {
  $('a[href^="#"]').click(function () {
    var href = $(this).attr("href");
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top;
    var speed = 500;
    $("html, body").animate({
      scrollTop: position
    }, speed, "swing");
    return false;
  });
});

こちらの内容は以下記事で詳細に解説しています!

まとめ

scroll-vehavior:プロパティはいくつかの注意が必要なものの、CSSだけで手軽にスムーススクロールのアニメーションを加えることのできる便利なプロパティです。

手軽に実装したい場合は取り入れていきたいところ。

実務ではブラウザ要件やデメリットを確認し、問題なければ取り入れるようにしましょう!