[CSS] テーブルのスクロール可能領域を表す影をanimation-timelineで付ける方法
5 min read
概要
テーブルのスクロール可能領域を視覚的に示すために、水平スクロール時に影を付ける手法が存在する。
これまでの方法だと、スクロール可能領域の端に影を付けるためにJavaScriptを使用してスクロール位置に応じて影の位置を調整したり、そのためにラッパー要素を用意するなどして実装が複雑になるような手法が主だった。
JavaScriptやラッパー要素を用いず、テーブル要素に対してCSSだけでスクロール可能領域を表す影を付ける実装をする。既存のHTML構造を変更せずに実現できるため、汎用性が高くなる。
実現方法
デモ
コード
:root {
--table-shadow-color: hsla(0, 0%, 87%, 0.9);
--table-shadow-size: 0.5rem;
--table-shadow-spread: calc(var(--table-shadow-size) * -0.5);
}
@keyframes scroll-table-shadow-inset {
0% {
box-shadow:
inset calc(var(--table-shadow-size) * -2) 0 var(--table-shadow-size) var(--table-shadow-spread)
var(--table-shadow-color),
inset 0 0 var(--table-shadow-size) var(--table-shadow-spread) var(--table-shadow-color);
}
10%,
90% {
box-shadow:
inset calc(var(--table-shadow-size) * -1) 0 var(--table-shadow-size) var(--table-shadow-spread)
var(--table-shadow-color),
inset var(--table-shadow-size) 0 var(--table-shadow-size) var(--table-shadow-spread) var(--table-shadow-color);
}
100% {
box-shadow:
inset 0 0 var(--table-shadow-size) var(--table-shadow-spread) var(--table-shadow-color),
inset calc(var(--table-shadow-size) * 2) 0 var(--table-shadow-size) var(--table-shadow-spread)
var(--table-shadow-color);
}
}
table {
display: block; /* テーブルの内側をスクロール用 */
overflow-x: auto; /* テーブルの内側をスクロール用 */
max-width: 100%; /* テーブルの内側をスクロール用 */
animation: scroll-table-shadow-inset linear; /* 影のアニメーション */
animation-timeline: scroll(self x); /* スクロール連動 */
}
解説
先述のコードを解説する。
テーブルの内側をスクロールする
table {
display: block;
overflow-x: auto;
max-width: 100%;
}
display: block;
width
やheight
プロパティが効くようになり、オーバーフローやスクロールの制御が可能になる
overflow-x: auto;
- 指定された横幅を超える場合、スクロールバーが有効になる
- 内容が収まる場合、スクロールバーは表示されない
さらにth,td
要素にwhite-space: nowrap;
を指定して、テキストが折り返されないようにしておくと良い。
@keyframes scroll-table-shadow-inset
@keyframes scroll-table-shadow-inset {
0% {
/* 左側に濃い影、右側に薄い影 */
box-shadow:
inset calc(var(--table-shadow-size) * -2) 0 var(--table-shadow-size) var(--table-shadow-spread)
var(--table-shadow-color),
inset 0 0 var(--table-shadow-size) var(--table-shadow-spread) var(--table-shadow-color);
}
10%,
90% {
/* 左右両側に均等な影 */
box-shadow:
inset calc(var(--table-shadow-size) * -1) 0 var(--table-shadow-size) var(--table-shadow-spread)
var(--table-shadow-color),
inset var(--table-shadow-size) 0 var(--table-shadow-size) var(--table-shadow-spread) var(--table-shadow-color);
}
100% {
/* 右側に濃い影、左側に薄い影 */
box-shadow:
inset 0 0 var(--table-shadow-size) var(--table-shadow-spread) var(--table-shadow-color),
inset calc(var(--table-shadow-size) * 2) 0 var(--table-shadow-size) var(--table-shadow-spread)
var(--table-shadow-color);
}
}
- アニメーションの定義:
@keyframes scroll-table-shadow-inset
で、スクロールに応じて変化する影の状態を定義する- 影は
box-shadow
を使用してテーブルの内側(inset
)に表現する- 0%(開始時): 左側に濃い影、右側に薄い影
- 10%〜90%(中間): 左右両側に均等な影
- 100%(終了時): 右側に濃い影、左側に薄い影
- 影は
- アニメーションの適用:
テーブル要素にanimation: scroll-table-shadow-inset linear;
とanimation-timeline: scroll(self x);
を指定することで、水平スクロールに連動してアニメーションする - スクロール連動:
animation-timeline: scroll(self x);
は、要素自体の水平スクロール位置に基づいてアニメーションを制御する
これにより、スクロール位置に応じて影の位置が変化し、スクロール可能領域を視覚的に示すことができる
注意点
執筆当時、animation-timeline
が一部のブラウザでしかサポートされていない。
Chrome | Edge | Firefox | Safari |
---|---|---|---|
✅ 115 | ✅ 115 | ❌1 | ❌ |
https://caniuse.com/mdn-css_properties_animation-timeline
参考
注釈
Firefox は
layout.css.scroll-driven-animations.enabled
フラグをtrue
にすることでバージョン110から有効になる。 ↩