• Login
    • ログインしていません

  • Tool Set
    • 1ページ戻る

    • 1ページ進める

    • お気に入りに登録

    • しおりを挟む

  • Save
    • ページの復元をする

      サイトにアクセスした際に、前回閲覧していたページへ自動的に遷移するようにセットします。

  • Toppage Button
    • ボタンを非表示にする

  • Scroll Direction
    • ボタンによる
      スクロール方向を逆転

Basis

  • HOME

  • Basis

  • Scroll-behaviorでSmoothScrollを実現する

scroll-behaviorでSmoothScrollを実現する

アンカーリンクによるページ内移動の移動を、
JavascriptのSmoothScrollを使用せず、cssのみで表現できる方法を解説していきたいと思います。
この実装方法は、メリットデメリットがあり、
今現在(2023/02/22)では
Mac, iOS のSafariで対応範囲に含まれるかもしれない ver 15.4 より以前のバージョンに対応できないので、
上記を踏まえた上での導入をお願い致します。

css: scroll-behavior

SmoothScrollはJavascriptによって表現されていましたが、
scroll-behavior の登場で、Javascriptを書くことなく表現できる様になりました。

デモを用意したので、実際の動きをこちらから確認してください。
scroll-behaviorのdemo

Demo1について

特に何も設定していないので、
ページ内リンクで表示場所が瞬時に移動する形で表示されます。
表示位置もヘッダー(アンカーリンク一覧)の後ろに潜り込んだ形で表示されています。

Demo2について

scroll-behavior を設定しないで、
新たに scroll-margin-top を設定することで、
瞬時に移動する形だけれども、ヘッダーにかぶることなく丁度いい位置に止まって表示されています。

Demo3について

scroll-behavior に smooth を設定し、
scroll-margin-topも設定することで、スクロール移動しながらも丁度いい位置に止まる様になりました。

Demo4について

scroll-behavior に smooth を設定するのですが、
scroll-margin-topが登場する前に設定していた方法になります。
padding-top でヘッダー分の高さを出し、さらに negative margin によって位置を持ち上げることで、
丁度いい位置に止まる様にする方法を並べました。
こちらは若干問題があり、境界近くにリンクなどを置くとマウスが反応しなくなるため、
今後は、よほどのことがない限り使用することはないと思います。
対応策としては、 z-index でレイヤーの位置関係を変更するだけでリンクが押せる様になります。
(結構大掛かりになりそうですし、このためだけに設定するのもナンセンスかと思います)

Mac, iPhone での視差効果を減らすについて

Mac, iPhone共に「視差効果を減らす」にチェックをつけていても、
スクロールアニメーションは起こってしまうので、
そこを考慮するためには下記の設定が必要になってきます。
demo2,3,4は視差効果を減らすにチェックをつけてもアニメーションが起こります。

// デフォルトではスクロールアニメーションを起こす
html {
  scroll-behavior: smooth;
}
// 視差効果を減らすにチェックがついている場合にアニメーションをOFFにする設定
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

// もしくは
// 視差効果を減らすにチェックがついていない場合にアニメーションを設定する
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

cmd + f によるページ内キーワード検索

通常ページ内のキーワード検索をした場合、瞬時にそのキーワードの位置に移動するかと思います。
しかしながら、scroll-behavior によるアニメーションがONになっていた場合、
こちらの際の移動もアニメーションで移動する形になります。

下記にチェックボックスを用意したので、切り替えて実際の挙動を試してみてください。

こちらを回避するためには下記の設定に修正する必要があります。

html:focus-within {
  scroll-behavior: smooth;
}

新たに擬似クラスが登場しました。
:focus-withinは、
その要素もしくはその要素の子、子孫要素に focus があたったもしくはあたっている場合にという擬似クラスになります。

しかしながらこれを設定すると、
demo2,3,4はアニメーションしなくなってしまいます。
というのも、
リンクをクリックした際にリンクにフォーカスが一瞬だけ当たり、
その後移動先の要素にfocusが当たるはずなのですが、
demoで設定している移動先の要素は p要素 のため、本来focusが当たるという機能を持っていません。
なのでこれを回避するためには、
さらに遷移先にtabindex="-1"を設定する必要があります。
こちらに関してもDemo3をベースにDemoを作成したので、
挙動の違いを見ていただけたらと思います。
scroll-behaviorをfocus-withinにした際のDemo

Demo3をベースにして、検索時の挙動、視差効果の有無の違いを表現するために、
5〜7の3つのDemoを作成しました。
Demo 5,6,7 は共通の設定として、
:focus-withinを設定しまています。

Demo5について

scroll-behavior の設定を
:focus-withinで設定したことで、すべてのスクロールのアニメーションが止まってしまいました。

Demo6について

Demo5をベースに、
移動先である「Xセクション」にtabindex="-1"を設定することで、
リンククリックによるアニメーションは復活し、
ページ内検索の際はアニメーションが起こらない様になりました。

Demo7について

Demo6をベースに、
scroll-behavior の設定を、「視差効果がを減らす」にチェックがついていない時にだけアニメーションが起こる様になりました。
設定方法は下記になります。

@media (prefers-reduced-motion: no-preference) {
  html:focus-within {
    scroll-behavior: smooth;
  }
}

scroll-behaviorを使用する時におけるベストプラクティス?

Demo6で実装した内容が現時点(2023/02/24)での最終地点になるのではないかと思います。

  1. scroll-behavior は :focus-within で設定する
  2. 視差効果に配慮して、設定によって切り替えができる様にする
  3. 移動先には scroll-margin-top でヘッダー分の offset を設定する
  4. 移動先には tabindex="-1" を設定する

これで、
アンカーリンクのクリック時にはアニメーションをさせることができ
かつ
キーワード検索時にはアニメーションを止めることができ
かつ
視差効果の設定でアニメーションの切り替えができる様になりました。

メリット・デメリット

最後になりましたが、
cssでSmoothScrollを実現することのメリット・デメリットを考えていきたいと思います。

まずはJSで表現する事とcssで表現することの違いを挙げていきたいと思います。

JSとcssでの違い

・アニメーションの速度、イージングを変更をJSではできるが、cssではできない
・URLにJSではハッシュがつかず変更がかからない(ハッシュをつけるかつけないかは制御が可能)が、cssではハッシュついて変更がかかってしまう

違いはこの辺りなのかなと思います。

CSSで行うデメリット

アニメーションの速度、イージングを変更できないのはデメリットなのかなと思います。
もっとアニメーション時間を短くしたい時でも短くすることができず、
イージングも画一的な linear のような動作をしていて、
どちらも変更することはできません。

URLにハッシュがつくつかないに関しては考え方によるので、
付くことでデメリットだと感じる方は一定数いるのではないかと思います。

CSSで行うメリット

CSSだけで完結するので、
少ない記述量・ページ読み込みまでのパフォーマスを上げられるというところではないでしょうか。

ハッシュがURLに付くことについて

個人的にはこれに関して メリット だと思っています。
というのも、
リンク共有する際に、相手方にページの特定の位置から表示させたい・表示してもらいたい時に、
開発者ツールを使ってハッシュを調べて,
ページのURLに自分でハッシュをつける手間がなんとも無駄だと考えているからです。
cssで対応した場合、必ずハッシュがURLにつくので共有がしやすく、これがいいと個人的には思います。

まとめ

CSSでSmoothScrollを表現するには、
ブラウザのバージョンにまだ左右される時期ではありますが、(safariの15.4以前をサポートする必要がある時)
Javascriptの記述を減らすことができるこの技術は有用なのではないかと思います。
アクセシビリティの観点からも考慮すべきことはありますが、
それほどコストがかかるわけではないので、その点においても今後使用していけるのではと思います。

Drug用ハンドル