🎉

CSSでなめらかなスクロールができるらしい

2022/11/15に公開

はじめに

リンクを押下してページ内の任意のアンカーに移動する場合、普通はぱっと瞬間的に移動します。
これを任意のスムーズに移動させようとするとJsを利用するものだと思っていたのですが、今はCSSでできるそうなので試してみました。

尚、以下の記事を見て知りました。

https://black-flag.net/css/20220518-7635.html

試す

普通の移動

こんな感じで、ぱっと移動します。
これをアニメーションで滑らかに移動させようとすると、Jsを利用するのが当たり前だと考えていたのですが今時はCSSとの事です。

CSSで滑らかに移動してみる

CSSで滑らかに移動するには以下を利用します。

scroll-behavior: smooth;

今回の例では * に記述しましたが、スクロールバーが表示されている要素に記述するのが標準なのでしょうか。 なので、ページ全体のスクロールバーであれば html に対して記述するのが良い…?

headerを固定してみる

これまでの例だと、ヘッダー部分を固定していないのでリンクを押下して移動するとヘッダー部分もスクロールしました。 次はよくあるヘッダー固定を実装してみます。

CSSの変更点は以下です。

:root {
+ --header-height: 7rem;
  --content-width: 50vw;
}
* {
  margin: 0;
  scroll-behavior: smooth;
}
header {
  color: #fff;
  background-color: rgba(10,10,10,0.9);
  text-align: center;
  
+ position: fixed;
+ top: 0;
+ width: 100vw;
+ height: var(--header-height);
}
header nav {
  width: var(--content-width);
  margin: 0 auto;
}
header a {
  color: #fff;
  margin: 1rem;
}
main {
  width: var(--content-width);
- margin: 0 auto;
+ margin: calc(var(--header-height) + 1rem) auto;
}
main section {
  margin-top: 1rem;
}
main h2 {
  border-bottom: 2px solid #000;
}
main p {
  margin: 2rem;
}

ヘッダーが固定されてリンクを押下すると滑らかに移動してくれるのですが、止まってほしいところでは止まってくれないですね。 アンカーの箇所がヘッダー部分の裏に隠れてしまうので、ヘッダーの高さ分ずらして止まってもらわないといけません。 ヘッダーの高さは 7rem としているので、Jsで制御する時はこの高さの分を加味してスクロールしなければなりませんでしたがCSSでの制御だと scroll-margin なるもので制御できる様です。

スクロール時にヘッダー分の高さを加味してもらう

scroll-margin を移動時のアンカー要素となっている section に設定してみます。

main section {
  margin-top: 1rem;
+ scroll-margin-top: calc(var(--header-height) + 1rem);
}

これだけでいい感じにスクロールしてくれる様になりました。 Jsでやるよりかなり簡単にできる気がします。

今回は上部のマージンのみ指定したいので scroll-margin-top を利用していますが、 bottom left right もある様です。 普通は topleft とを利用するくらいですかね…?

おわりに

今までJsで頑張っていた事がCSSのみでできる様になるのは便利で助かりますね。 しかし、次々出てくるので追いかけるのが大変でフロントエンド専門でやっていないとなかなか難しいですね…。
もちろん、ブラウザによる実装の差異にも注意が必要です。 利用する際はご注意ください。

Discussion