
こんにちは!今回は、Chrome 153のBetaで導入された注目のCSS新機能「単一軸スクロールコンテナ(Single-axis scroll containers)」について解説します。
これまで、Web制作で横スクロールコンテナ(カルーセルや横長テーブルなど)を作る際、position: sticky が意図通りに動かずに悩んだ経験はありませんか? この新機能によって、その長年のイライラが解消できるようになります!
1. 「単一軸スクロールコンテナ」とは?
従来のCSSでは、overflow: auto や overflow: scroll を指定すると、実質的に両方向(あるいは意図しない軸)へのスクロールやレイアウトへの影響が発生し、position: sticky の挙動に悪影響を及ぼすことがありました。
Chrome 153でサポートされた新機能では、overflow プロパティが拡張され、clip キーワードと組み合わせて指定できるようになりました。
- 指定方法の例:
overflow: scroll clip;やoverflow: auto clip;
これにより、「一方の軸はスクロール可能にするが、もう一方の軸は完全にクリップ(独立)させる」という厳密な単一軸のコントロールが可能になります。
2. 何が解決するのか?(具体例)
よくあるユースケースとして、「横スクロールするカード一覧(カルーセル)」の中に、要素を配置する場面を考えてみます。
これまで、横スクロールコンテナの中に position: sticky な要素を置くと、親のスクロールコンテナの仕様によってstickyがうまく機能しない、あるいは予期せぬスクロールが発生するといった問題がありました。
従来のコード(問題が起きがち)
CSS
.carousel-wrapper {
overflow: auto; /* 両方向、または意図しない軸の判定になる */
white-space: nowrap;
}
新しい書き方(単一軸の指定)
CSS
.carousel-wrapper {
/* 横方向はスクロール、縦方向はclipで完全に独立させる */
overflow-x: scroll;
overflow-y: clip;
/* または一括指定 */
overflow: scroll clip;
}
これにより、横方向には滑らかにスクロールしつつ、縦方向のレイアウトや position: sticky などの祖先要素とのインタラクションが、余計な干渉を受けずに正常に動作するようになります。
具体例:縦・横のラベルを両方「Sticky」させたいテーブル
「スマホなどの狭い画面で、大きな表(テーブル)を見るときに、上部のヘッダー(列見出し)と左側のラベル(行見出し)の両方を画面に固定(Sticky)させたい」というケースを考えてみます。
従来のCSSでは、表全体をスクロールさせようとすると、縦横どちらの軸もスクロールコンテナと判定されてしまい、意図した軸で position: sticky がうまく機能しない、あるいは不要な軸まで動いてしまうジレンマがありました。
今回の新機能(overflow: scroll clip)を使うと、「横方向はスクロール、縦方向はページ側のスクロールに追従(または完全にクリップ)」といった制御が美しく決まります。
| 項目 / 月 | 1月 | 2月 | 3月 | 4月 | 5月 |
|---|---|---|---|---|---|
| Aプラン | 100 | 120 | 140 | 160 | 180 |
| Bプラン | 200 | 220 | 240 | 260 | 280 |
| Cプラン | 300 | 320 | 340 | 360 | 380 |
HTML
<div class="wp-custom-table-container">
<table>
<thead>
<tr>
<th class="sticky-corner">項目 / 月</th>
<th>1月</th>
<th>2月</th>
<th>3月</th>
<th>4月</th>
<th>5月</th>
</tr>
</thead>
<tbody>
<tr>
<th class="sticky-row">Aプラン</th>
<td>100</td>
<td>120</td>
<td>140</td>
<td>160</td>
<td>180</td>
</tr>
<tr>
<th class="sticky-row">Bプラン</th>
<td>200</td>
<td>220</td>
<td>240</td>
<td>260</td>
<td>280</td>
</tr>
<tr>
<th class="sticky-row">Cプラン</th>
<td>300</td>
<td>320</td>
<td>340</td>
<td>360</td>
<td>380</td>
</tr>
</tbody>
</table>
</div>
CSS
.wp-custom-table-container {
max-width: 100%;
margin: 20px 0;
/* 【新機能】横方向はスクロール、縦方向はclipで独立させる */
overflow-x: scroll;
overflow-y: clip;
border: 1px solid #e0e0e0;
border-radius: 4px;
}
.wp-custom-table-container table {
border-collapse: collapse;
width: 100%;
min-width: 600px;
white-space: nowrap;
}
.wp-custom-table-container th,
.wp-custom-table-container td {
padding: 12px 16px;
border: 1px solid #e0e0e0;
background: #ffffff;
text-align: center;
}
.wp-custom-table-container th:first-child,
.wp-custom-table-container td:first-child {
text-align: left;
}
.wp-custom-table-container thead th {
position: sticky;
top: 0;
z-index: 2;
background: #f8f9fa;
}
.wp-custom-table-container .sticky-row {
position: sticky;
left: 0;
z-index: 1;
background: #f8f9fa;
}
.wp-custom-table-container .sticky-corner {
position: sticky;
top: 0;
left: 0;
z-index: 3;
background: #e9ecef;
}
3. 同時に入った「scroll-axis-lock」も要チェック
Chrome 153では、単一軸スクロールコンテナと合わせて、スクロールの軸をロックする scroll-axis-lock プロパティ も導入されています。
こちらもスクロールの挙動をよりリッチに、意図通りにコントロールするための強力な武器になるため、あわせてチェックしておきたい機能です。
まとめ
Chrome 153で登場した「単一軸スクロールコンテナ」は、UIのちょっとした「スクロールのバグ・違和感」をスマートに解決してくれる玄人好みのアップデートです。
まだデベロッパーテストの段階ではありますが、今後の標準化を見据えて、レイアウトの引き出しの一つとしてぜひ覚えておきましょう!