JavaScriptによるスクロールをやめて、Interaction to Next Paintを改善してください。
Core Web Vitalsに影響を与えない、美しくスムーズなスクロール体験を作成してください。
JavaScriptのスクロールを今すぐCSSに置き換える
この記事には少し歴史があります。2017年まで、一貫したスムーズスクロールを実装する唯一の方法は、JavaScriptライブラリを使用することでした。そして多くの開発者がそうしていました。当時はまだCore Web Vitalsという概念はなく、誰もがメインのJavaScriptライブラリとしてjQueryを使用していました。
現在に話を戻します。JavaScriptベースのアンカースクロールに代わる、より優れ、より高速で、より簡単な代替手段が存在します。しかし、Core Web Vitalsのコンサルタントとして、私は今でも毎日それらを目にします。
2026年2月にArjen Karelが最終確認
JavaScriptベースのスクロールが「悪い」理由

JavaScriptベースのスクロールが悪い理由は2つあります。複雑であることと、遅いことです。
複雑: JavaScriptベースのスクロールは不必要に複雑です。読みにくいコードを書いて保守する必要があります。Window.scrollTo()メソッドによってこのコードはずっと簡単になりましたが、それでも1行のCSSより保守ははるかに困難です。
遅い。JavaScriptはmain threadをブロックする傾向があり、常にCSSの代替手段よりも遅くなります。スクロール関数の実装方法によっては、main threadを長時間ブロックし、Interaction to Next Paint指標に大きな遅延を引き起こす可能性があります。2025 Web Almanacによると、モバイルのTotal Blocking Timeの中央値は1,916ミリ秒です。main threadを奪い合う不要なJavaScript関数はすべて、この状況を悪化させます。
CSSのスムーズスクロールが「良い」理由
JavaScriptベースのスクロールが悪い理由について説明しました。CSSベースのスムーズスクロールの場合はその逆です。次のようにスタイルシートに追加するだけで済みます。
html{ scroll-behavior: smooth;} シンプルで効果的
CSSのワンライナー html { scroll-behavior: smooth; } は実装が非常に簡単で、JavaScriptベースのソリューションよりも効率的です。この1行のコードで、保守が困難なJavaScript関数を使用せずにページ全体のスムーズスクロールを有効にできます。さらに進んで不要なJavaScriptを遅延または完全に削除すれば、INPの処理時間は改善されます。
パフォーマンスの向上
CSSベースのスムーズスクロールはブラウザによってネイティブに処理され、どのような場合でもJavaScriptの実装よりも優れたパフォーマンスを発揮します。これはブラウザのmain threadへの負担が少なくなるため、Interaction to Next Paint (INP)指標を最適化する上で特に重要です。JavaScriptのスクロールハンドラはmain threadで実行する必要があり、そこで費やされるすべてのミリ秒が、次のユーザーインタラクションを遅らせます。CSSのスクロール動作は完全にmain thread外で実行されます。インタラクション中に実行する必要があるJavaScriptがまだある場合は、main threadにyieldする方法を読んでください。
スムーズなアンカースクロールは始まりにすぎません。かつてはJavaScriptを必要としたスクロールの役割を、CSSが引き受けるようになっています。Scroll-driven animations (Chrome 115以降、Safari 26以降) を使用すると、アニメーションの進行状況をスクロール位置に連動させることができ、requestAnimationFrameのスクロールハンドラを完全に置き換えることができます。Scroll-triggered animations (Chrome 145) は、スクロールオフセットを越えたときに時間ベースのアニメーションを実行し、表示エフェクトのためのIntersectionObserverを置き換えます。そして、scroll-state container queries (Chrome 133以降) を使用すると、要素が固定されているか、スナップされているか、スクロール可能かに基づいて、JavaScriptなしでスタイルを設定できます。傾向は明確です。可能であればどこでも、スクロールロジックをJavaScriptからCSSに移行してください。
ブラウザの互換性
CanIUseによると、CSSのスムーズスクロールは世界中で95%のブラウザでサポートされています。2022年3月以降、すべての主要なブラウザでベースラインとなっています。スムーズスクロールがサポートされていない古いブラウザは、アンカーへのデフォルトの直接ジャンプに単にfallbackします。
簡単なカスタマイズ
CSSを使用すると、スクロールの動作を簡単にカスタマイズできます。例えば、scroll-margin-topプロパティを使用すると、スクロールされた要素への上部の距離を設定できます。
h1, h2, h3 {scroll-margin-top: 5rem;} あるいは、'target'疑似クラスを使用するとさらに簡単です。
:target {scroll-margin-top: 5rem;} モーション設定の尊重
ユーザーの中には、スクロールアニメーションによって乗り物酔いを経験する人がいます。スムーズスクロールをprefers-reduced-motionメディアクエリでラップすると、そうしたユーザーには代わりに瞬時のジャンプが確実に提供されます。
@media (prefers-reduced-motion: no-preference) {
html { scroll-behavior: smooth; }
} これにより、モーションの軽減をリクエストしていないユーザーにのみスムーズスクロールが適用されます。前庭障害やモーション過敏症のあるユーザーには、デフォルトの瞬時スクロールが表示されます。
完全な例
このコードの動作を確認するには、このページの上部にある目次をクリックしてください。クリックしたアンカーへのスムーズなスクロールが確認できます。
コピーして再利用できるシンプルな例を以下に示します。
<html>
<head>
<title>Smooth scroll to target</title>
<style>
html {
scroll-behavior: smooth;
}
:target {
scroll-margin-top: 5rem;
}
.largedivider {
height: 1000px;
}
</style>
</head>
<body>
<nav>
<a href="#target">scroll to target</a>
</nav>
<div class="largedivider"> -- </div>
<h2 id="target">scroll to me</h2>
<div class="largedivider"> -- </div>
</body>
</html>