@container scroll-state()は、CSSコンテナークエリーの一種です。従来はJavaScriptを使って実装していた、「スクロールされたらヘッダーのスタイルを切り替える」等のインタラクションをCSSだけで実装できるようになります。

本記事では、scroll-state()の使い方とできることを作例で紹介します。
コンテナークエリーは、記事『要素の幅でレスポンシブ対応を行える!コンテナークエリーの使い方』で紹介しています。コンテナー幅でのレイアウト制御にかかわらず、インタラクティブなUI構築にも役立ちます。コンテナークエリーの可能性の広さを感じ取っていただけたら嬉しいです。
※本記事の作例は、Chrome 133・Edge 133(2025年2月)以上でご覧ください。
@container scroll-state()の使い方
このクエリーは、container-type: scroll-stateが指定された要素の子要素に対して利用できます。@container scroll-state()の丸かっこ内には、stuck、scrollable、snappedのいずれかを指定します。それぞれを利用できる条件は以下の通りです。
stuckposition: stickyで要素が固定されている
scrollable- 上下左右いずれかの方向に要素をスクロールできる
snappedscroll-snap-typeプロパティで要素がピタッと止まる
それぞれコロン(:)のあとに、topやbottom、inlineやblockといった検知のタイミングを指定します。
▼stuckの記述例
<div class="item-container">
<div class="item"></div>
</div>
.item-container {
container-type: scroll-state;
position: sticky;
top: 0;
left: 0;
}
.item {
@container scroll-state(stuck: top) {
/* .item-container が固定されたときのスタイルを記述する */
}
}
本記事では紹介しないものもあるので、詳しくはMDNの以下のページを参考にしてください。
次の章からは、stuck、scrollable、snappedのそれぞれで、どのようなUI構築ができるか紹介します。
stuck: 要素が固定された瞬間を検知する
@container scroll-state(stuck: top)を指定すると、position: stickyで画面上部へ固定された瞬間にスタイルを適用できます。次の作例では、画面の最上部にいるかどうかで、ヘッダーの背景色を切り替えています。画面の最上部から少しでもスクロールすると、背景色が白に変わります。

固定したら要素を追加表示する
次の作例では、画面上部にボタンが到達した瞬間に、ボタンの横幅を広げています。

※この作例は、キーボードでの操作やスクリーンリーダーでの読み上げはうまく動かない可能性があります。
固定が終わったらスタイルを適用する
@container scroll-state(stuck: bottom)とnot条件(@container not scroll-state())を利用することで、position: stickyの固定が終了した瞬間にスタイルを適用できます。次の作例では、「セクション01」に配置したボタンを画面下部に固定表示し、スクロールで通過したらボタンにスタイルを追加します。

scrollable: スクロールできることを検知する
@container scroll-state(scrollable: top)を指定すると、要素が上方向へスクロールできるときにスタイルを適用できます。次の作例は、上方向へスクロールできるとき、画面上部に補助メッセージを追加表示しています。

snapped: 要素がピタっと止まることを検知する
@container scroll-state(snapped: y)を指定すると、scroll-snap-typeプロパティで要素が止まる瞬間にスタイルを適用できます。次の作例では、要素を少し拡大して強調表示しています。

カルーセルUIに適用する
次の作例は、記事『JavaScript不要! HTMLとCSSでつくるカルーセルUI』で紹介したカルーセルUIに適用したものです。「▶」ボタンのクリック時に写真が水平方向にスライドしますが、スライド中だけサイズが縮小するような効果を与えています。snappedの値には、インライン方向を示すinlineを指定しています。

▼追加したCSSを抜粋
.item {
container-type: scroll-state;
img {
transition: scale 0.3s;
transition-delay: 0.2s;
@container not scroll-state(snapped: inline) {
scale: 0.85;
transition-delay: 0s;
}
}
}
対応ブラウザ
scroll-state()は、2025年5月末時点ではChrome 133・Edge 133(2025年2月)以上で利用できます。
- 参照:Can I use…

まとめ
@container scroll-state()でできることを紹介しました。これまでJavaScriptでしか実現できなかった「スクロールの状態に応じたスタイル変更」をCSSだけで実装できます。
まだ対応ブラウザが限られていますが、多くの場面で活用できる機能です。CSSでシンプルな演出を追加したいときに、ぜひ活用してみてください。

