Web制作の現場における「ボタンを押したら特定の要素までスクロールさせたい」といった要件、本当によく出てきますよね。
例えば問い合わせフォームの最後にある送信ボタンまで誘導したいときや、ページ途中の注目コンテンツにジャンプさせたいときなど。
コレを実装するのに便利なのが scrollIntoView メソッド。
わずか1行で「要素をスクロールして表示させる」ことができるので、お世話になっている開発者は多いかもしれません。
ただし、 scrollIntoView には課題も……。スクロール領域が入れ子(ネスト)になっている場合、意図せず外側のコンテナまでスクロールしてしまい、ユーザーの使い勝手を損なう挙動になることがありました。
そんな状況で希望の光となったのが Chrome 140、このバージョンから新機能 container オプション が追加されていますよね。これを指定することで「一番近いスクロール可能な要素だけ」を動かせるようになり、より自然で直感的なスクロール体験を実現できるようになりました。
実際にどうやって使うの?
例えば、こんなHTMLとCSSがあったとしましょう。
<button id="btn">スクロール!</button>
<div class="outer">
<div class="inner">
<div class="spacer"></div>
<div id="target">ここにスクロール!</div>
<div class="spacer"></div>
</div>
</div>
<style>
.outer {
width: 300px;
height: 200px;
overflow: auto;
border: 2px solid #333;
margin-top: 20px;
}
.inner {
width: 500px;
height: 500px;
overflow: auto;
background: #f0f0f0;
}
.spacer {
height: 300px;
}
#target {
background: yellow;
padding: 10px;
border: 2px solid red;
}
</style>
この時点では #target は画面外に隠れており、ボタンを押すとスクロールによって見えるようになります。
ここに scrollIntoView を使ってスクロールを実装してみます。
従来の JS
document.querySelector("#btn").addEventListener("click", () => {
document.querySelector("#target").scrollIntoView({ behavior: "smooth" });
});
このコードを実行すると、.outer と .inner の両方がスクロールしてしまうことがあります。結果としてページ全体が大きくガタッと動き、ユーザーにとって「思った以上に動いた」という違和感につながることが少なくありません。UX にこだわる開発者であれば発狂しそうな状況ですね。
特にモーダル内フォームや入れ子構造のカードレイアウトでは、部分的なスクロールだけでよい場面が多いため、この挙動がかえって不自然に感じられるケースがありました。
Chrome 140 からの新オプション
そこで役立つのが Chrome 140 から利用できる container オプションです。
これを指定すると、最も近いスクロール可能な要素だけを動かせます。
書き換えはとてもシンプルで、JS 該当部分を次のように変えるだけ。
document.querySelector("#target").scrollIntoView({
behavior: "smooth",
container: "nearest"
});
このコードを使うと .inner だけがスクロールして #target が表示されます。.outer やページ全体は一切動かないため、ユーザーが「自然にフォーカスが移動した」と感じやすくなります。
container オプションはどんなときに役立つ?
この機能はシンプルですが、実際のユースケースを考えると応用範囲は広いです。
モーダルウィンドウ内のフォーム
先程もすこし触れましたが、モーダル内フォームの実装に役立ちます。
例えばログイン画面や問い合わせフォームなどのモーダルでは、入力欄にフォーカスを当てるとモーダル内だけをスクロールさせたい場面が多いです。従来の挙動だと背景ごとスクロールしてしまうことがありましたが、新オプションを使えば「モーダル内だけを自然に動かす」ことが可能になります。
タブやカードUI
カードの中にさらにスクロール可能な領域を持つUIでは、内側だけをスクロールさせたい場面があります。container: ‘nearest’ を指定することで、カード単位で直感的なスクロールができ、ユーザー体験の質を大きく高められます。
エディタやビューア
ドキュメントエディタやコードビューアのように複数のスクロール領域を持つアプリケーションでは、編集中の部分だけをスクロール対象にしたいことが多いです。新オプションを使えば「必要な領域だけが動く」ため、意図通りの操作感を実現できます。
ブラウザの対応状況は?
毎度のことながら「こんなに便利ならすぐにでも取り入れたい!」って思いますよね。そこをグッとこらえて、ひとまず “Can I Use…” してみましょう。
Element API
scrollIntoView: options.container parameter
真っ赤ですね。本日時点では 最新のChrome/Edge限定で利用できます。実務で利用する場合はフォールバックを用意しておくと安心です。
try {
document.querySelector("#target").scrollIntoView({
container: "nearest",
behavior: "smooth"
});
} catch (e) {
// 古いブラウザ用のフォールバック
document.querySelector("#target").scrollIntoView({ behavior: "smooth" });
}
小さな変更で大きく変わるUI/UX
scrollIntoView は、要素をスクロールで表示させるためのシンプルかつ便利なメソッドです。これまでの仕様では入れ子スクロールで良からぬ挙動になることがありましたが、Chrome 140 から追加された container: ‘nearest’ オプションを利用すれば、最も近いスクロール要素だけを動かせるようになり、より自然で直感的な操作感を実現できます。
この改善は、モーダルウィンドウやタブUI、エディタなどの実際のWebアプリケーションで特に効果を発揮します。ユーザーに余計な動きを感じさせず、必要な領域だけをスムーズにスクロールできるため、UIの使いやすさが大きく向上します。現時点では Chrome や Edge といった最新ブラウザ限定の機能ですが、今後他のブラウザにも広がっていく可能性があるため、早めに試しておくと後の開発が楽になるかもしれません。