IMUZA.com

Xserver<<WordPress(ConoHa)<<はてなブログ

ホーム / CSS / CSS:scroll-behavior:smooth を使わないわけ

CSS:scroll-behavior:smooth を使わないわけ

2021/07/12 CSS, javascript, はてなテーマ

ページ内のリンクをスムーズに移動するには、CSSのみ、jQuery、素の Javascript といろいろ方法があり、とにかく一番簡単なのは一行ですむ CSS による方法ですが、残念ながらイージングが指定できません。

  • 比較用デモサイト
  • CSS によるスムーススクロール
    • 問題点
  • javascript scrollIntoView()による
    • 問題点
  • オリジナル Javascript による
  • smooth-scroll.jsによる
  • 汎用オリジナル smooth scroll
  • ライセンス等

比較用デモサイト

スムーススクロールの動きを比較できるデモサイトをつくってみました。

CSSによるもの、javascript scrollIntoView()によるもの、オリジナル Javascript によるもの、smooth-scroll.jsによるものの4つが比較できます。4種類のナビが下の画像のように右に固定してありますので試してみてください。smooth-scroll.js のイージングは easeOutQuint が指定してあります。

  • スムーズスクロールのデモページ – imuza.work

CSS によるスムーススクロール

一行ですべてのページ内リンク <a href="#hogehoge"><a> がスムーススクロールに変わります。

html{
    scroll-behavior: smooth;
}
  • scroll-behavior – CSS: カスケーディングスタイルシート | MDN

問題点

  • イージングが指定できなくlinear(等速)のみ
  • スピードもブラウザ依存(多分)
  • すべてのページ内リンクがスムーススクロールになる
  • Safari が未対応、Edge は対応済み
    “scroll-behavior” | Can I use… Support tables for HTML5, CSS3, etc

javascript scrollIntoView()による

上の CSS と同様のことが Javascript の scrollIntoView() メソッドで可能になります。

  • Element.scrollIntoView() – Web API | MDN

サンプルとしてページトップに戻るコードを簡潔に書いたものです。

<div>
略
</div>
<div id="toTop">ページトップへ</div>
<script>
document.getElementById('toTop').addEventListener('click', () => {
    document.body.scrollIntoView({behavior: 'smooth'});
});
</script>

問題点

CSS とほぼ同じです。

  • イージイングが指定できなくlinear(等速)のみ
  • スピードもブラウザ依存(多分)
  • Safari が未対応、ただし polyfill があるらしい(未確認)
    GitHub – iamdustan/smoothscroll: Scroll Behavior polyfill

オリジナル Javascript による

このサイトに使っているものです。

考え方は、現在位置から移動先位置までのピクセル値を 1/20 ずつ移動し、その都度現在位置を変更していく方法で、それですといつまでたっても移動先に到達できませんので移動ピクセル値に 1 を足しています。
スクロール時間は移動ピクセル値に依存しますので 1/20 の分母を大きくすればゆっくりになりますし、小さくすれば速くなります。

<div>
略
</div>
<div id="toTop">ページトップへ</div>
<script>
const smoothScroll = () => {
    let startY = window.pageYOffset;
    const scroll = () => {
        startY = window.pageYOffset;
        let y = startY - (startY - 0) / 20 - 1;
        window.scrollTo(0, y);
        if (y < 0) return;
        requestAnimationFrame(scroll);
    };
    requestAnimationFrame(scroll);
};
document.getElementById('toTop').addEventListener('click', smoothScroll);
</script>

まずシンプルにページトップへ戻る部分だけ抜き出しています。もう少し汎用性のあるものはこの記事の最後です。スクロールの最後にムニュっと止まるところが気に入って使っています。

smooth-scroll.jsによる

おそらくこれが一番使われているのではないかと思うライブラリです。jQuery は必要ありません。

  • GitHub – cferdinandi/smooth-scroll: A lightweight script to animate scrolling to anchor links.

イージングはもちろんのことオプションも豊富ですのでかなり汎用性は高いと思います。

サンプルは単純にページトップに戻るコードです。

<div>
略
</div>
<a data-scroll href="#">ページトップへ</a>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/smooth-scroll/16.1.0/smooth-scroll.min.js"></script>
<script>
    var scroll = new SmoothScroll('a[href*="#"]', {easing: 'easeOutQuint'});
</script>

使用していませんので問題点があるかないかもわかりませんが、スムーススクロールを除外するオプションもありますのでかなり使いやすいのではないかと思います。カスタムイージングも可能なようです。

汎用オリジナル smooth scroll

現時点では、smoothScroll(‘id名’) のように id を指定して呼べば上下どちらへもスムーススクロールするという汎用程度です。トップに戻る場合に id名ではなく数値「0」で指定するなどの改善はできそうです。

window.addEventListener('load', () => {
  const smoothScroll = (target) => {
    const targetY = document.getElementById(target).getBoundingClientRect().top + pageYOffset;
    let startY = window.pageYOffset;
    const f = ( targetY > startY ) ? true : false; // 'down' = true : 'up' = false
    if(f){
        const windowHeight = window.innerHeight;
        const documentHeight = document.body.clientHeight;
        var bottomTop = documentHeight - windowHeight;
    }
    const scroll = () => {
      startY = window.pageYOffset;
      if(f){
        let y = startY + (targetY - startY) / 20 + 1;
        window.scroll(0, y);
        if (y > targetY || y > bottomTop) return;
        requestAnimationFrame(scroll);
      }else{
        let y = startY - (startY - targetY) / 20 - 1;
        window.scrollTo(0, y);
        if (y < targetY) return;
        requestAnimationFrame(scroll);
      }
    };
    requestAnimationFrame(scroll);
  };

ライセンス等

ご使用の場合は以下の注意事項をお守りください。

  • ライセンスは IMUZA.com にあります。
  • 当記事の Javascript を使用してのはてなブログ用テーマの制作、公開は商用以外は自由です。ただし、記事内、あるいは紹介サイト内に IMUZA.com へのリンクを挿入してください。
  • 当記事の CSS への改変、公開は自由です。
  • 特別問題が発生することはありませんが自己責任でお使いください。
    問題が発生した場合は削除すればもとに戻ります。
  • お問い合わせ、バグの報告、仕様変更のご要望等は Contact Us までお願いします。
【Amazon限定ブランド】ホワイト 洗える 接触冷感 マスク オシャレマスク 日焼け防止 防塵 個包装 男女兼用 冷感マスク 夏用 立体型マスク ひんやり 洗えるマスク 日焼け止め 防塵 飛沫 花粉対策

【Amazon限定ブランド】ホワイト 洗える 接触冷感 マスク オシャレマスク 日焼け防止 防塵 個包装 男女兼用 冷感マスク 夏用 立体型マスク ひんやり 洗えるマスク 日焼け止め 防塵 飛沫 花粉対策

  • SETSUGEN

Amazon

Joomla! 3.9.28 セキュリティ & バグフィックスがリリースされています
Javascript:ページ最下部までスクロールするための最上部は?
Twitter
Facebook
ブックマーク
LINEで送る

最初のサイドバー

最新記事

2023/05/25

WordPress:リビジョン削除、回数制限

2023/05/10

WordPress:裏技的サイトリニューアル

2023/04/28

XserverへのSSH接続がエラーになってしまった

2023/04/16

正規表現の最短一致でミスる

2023/04/4

WordPress:公開中サイトをサブディレクトリでリニューアルし公開する

最新記事を一覧で見る

よく読まれている記事

よく読まれている記事を一覧で見る

カテゴリー

  • はてなブログ215
  • WebTips109
  • javascript98
  • Joomla!88
  • Wordpress70
  • Windows68
  • CSS63
  • Joomla!更新53
  • Linux49
  • はてなテーマ45
  • Google34
  • Plamo33
  • はてなプラグイン25
  • php23
  • Node.js18
  • Ubuntu16
  • SASS16
  • laravel415
  • Chrome11
  • cms-style10
  • iPhone9
  • Git入門6
  • ConoHa WING6
  • genesis6
  • Python5
  • Android5
  • PC全般4
  • Facebook4
  • スマートフォン4
  • Xserver3
  • Firefox3
  • 静的サイトジェネレーター3
  • SSD3
  • Docker3
  • Blankslate3
  • Twitter2
  • Mactype2
  • GitHub2
  • youtube1
  • はてなブクマ1
  • rails入門1
  • 映画1

Footer

My Web Sites

  • @半径とことこ60分
  • そんなには褒めないよ。映画評
  • IMUZA.com
  • GitHub

Related Sites

  • WordPress公式
  • WordPress関数リファレンス
  • PHPマニュアル

Contact Us

  • お問い合わせフォーム
  • Twitter
  • Facebook
  • Feedly

Copyright © 2023 · IMUZA.com