はじめに
2, 3ヶ月ほど前、勧告候補である「CSS Scroll Snap Module Level 1」のプロパティ群が、Google Chromeで使用できるようになりました
いったいどんなことが出来るのか、気になります。そこで、さっそく使ってみました。この記事は、その際のメモです。
用意したものは、最新版のGoogle Chrome(バージョン: 70.0.3538.77
)です。
CSS Scroll Snap とは
CSS Scroll Snap
は、スクロール可能な領域内のスクロール位置を調整できる機能を提供してくれるようです。
私たちは、Webページから目的の内容を探し出すとき、スクロールをしながら、セクション内の文章を読みます。
そして、目的の内容が見つかると、スクロールを止めます。
その時に「あっ、スクロールしすぎちゃった。最初から読むためにスクロール位置を調整しなきゃ...。」なんてことがよく起こると思います。これは急いでいるときには特に煩わしい作業です。
そこで、そんな作業をしなくても済むように、CSS Scroll Snap
を使うことが出来ます。これを使えば、スクロール操作が完了した後に、スクロール位置を指定した場所まで調整してくれるのです。
押さえておくべきプロパティ
-
scroll-snap-type
プロパティ -
scroll-snap-align
プロパティ -
scroll-padding
プロパティ -
scroll-margin
プロパティ
CSS Scroll Snap
を使うなら、とりあえずこの4つを押さえておけば良いかな、と思います。
scroll-snap-type
プロパティ
scroll-snap-type
プロパティは、
- スクロール位置の調整を行うかどうか
- どの軸でスクロール位置を調整するか
- どの程度厳密に調整するか
を指定します。
このプロパティは、スクロール可能な領域(スクロールコンテナ)に対して設定します。
スクロール位置の調整を行うかどうか
スクロール位置の調整を行わない場合、このプロパティにはnone
を設定します。これが初期値です。
どの軸でスクロール位置を調整するか
-
x
:
X 軸でスクロール位置の調整を有効にする -
y
:
Y 軸でスクロール位置の調整を有効にする -
block
:
ブロック軸でスクロール位置の調整を有効にする -
inline
:
インライン軸でスクロール位置の調整を有効にする -
both
:
X, Y 軸両方でスクロール位置の調整が行われる
どの程度厳密に調整するか
-
mandatory
:
スクロール位置を調整できる場合、スクロール位置が調整される -
proximity
:
スクロール位置を調整でき、調整後のスクロール位置が現在位置から近い場合は、スクロール位置が調整される。そうでない場合、スクロール位置の調整は行われない。
使用例
これらの設定は結構重要なのですが、言葉だけでは伝わりにくい部分があるので、簡単な例を用意しました。
調整の厳密さに関する指定であるmandatory
とproximity
を並べて、比較できるようにしています。
最新版のGoogle Chromeであれば動作すると思うので、ぜひ実際に試してみてください(動作確認リンク)。
両方ぐりぐり弄っているとわかると思いますが、mandatory
では絶対にスクロール位置の調整が行われるのに対して、proximity
ではスクロール位置の調整が行われない位置があります。
<div class="container">
<div class="scroll-container">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=mandatory1" alt="">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=mandatory2" alt="">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=mandatory3" alt="">
</div>
<div class="scroll-container proximity">
<img src="http://placehold.jp/703d40/ffffff/450x450.png?text=proximity1" alt="">
<img src="http://placehold.jp/703d40/ffffff/450x450.png?text=proximity2" alt="">
<img src="http://placehold.jp/703d40/ffffff/450x450.png?text=proximity3" alt="">
</div>
</div>
.container {
display: flex;
}
.scroll-container {
display: flex;
flex-basis: 50%;
flex-direction: column;
overflow-y: scroll;
scroll-snap-type: y mandatory;
max-height: 100vh;
}
.proximity {
scroll-snap-type: y proximity;
}
img {
scroll-snap-align: start;
margin-bottom: 5px;
}
scroll-snap-align
プロパティ
scroll-snap-align
プロパティでは、
- スクロール位置の調整を行うかどうか
- スクロールコンテナ内の可視領域(スナップポート)にある要素をどのように配置するか
を指定します。
このプロパティは、スクロール可能な領域の子要素に対して設定します。
スクロール位置の調整を行うかどうか
-
none
:
none
を指定したコンテンツでは、スクロール位置の調整が行われない。つまり、スクロールが調整される場合、そのコンテンツの隣にあるコンテンツにスクロールされる。動作確認リンクを用意した。これを実行すると、2つ目のimg
要素にスクロールが調整されないことがわかる -
start
:
スクロールコンテナ内で可視領域にある要素の始端が、スクロールコンテナの始端に位置するように、スクロール位置が調整される -
end
:
スクロールコンテナ内の可視領域にある要素の終端が、スクロールコンテナの終端に位置するように、スクロール位置が調整される -
center
:
スクロールコンテナ内の可視領域にある要素の中央が、スクロールコンテナの中央に位置するように、スクロール位置が調整される
使用例
こちらも、言葉だけではいまいちわからないと思うので、例を用意しました(動作確認リンク)。
scroll-snap-align
プロパティに、start
, end
, center
を指定した時の比較をしています。
この例を実行してみるとわかると思いますが、start
を指定すると、スクロールコンテナの上端にスクロール位置が調整されるようになります。center
, end
を指定した場合も、それぞれスクロールコンテナの中央、下端にスクロール位置が調整されます。
<div class="container">
<div class="scroll-container start">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=start1" alt="">
<img src="http://placehold.jp/3d4070/ffffff/250x250.png?text=start2" alt="">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=start3" alt="">
</div>
<div class="scroll-container end">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=end1" alt="">
<img src="http://placehold.jp/3d4070/ffffff/250x250.png?text=end2" alt="">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=end3" alt="">
</div>
<div class="scroll-container center">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=center2" alt="">
<img src="http://placehold.jp/3d4070/ffffff/250x250.png?text=center1" alt="">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=center3" alt="">
</div>
</div>
.container {
display: flex;
}
.scroll-container {
display: flex;
flex-basis: 33.3%;
flex-direction: column;
overflow-y: scroll;
scroll-snap-type: y mandatory;
max-height: 100vh;
}
img {
margin-bottom: 5px;
}
.start img {
scroll-snap-align: start;
}
.end img {
scroll-snap-align: end;
}
.center img {
scroll-snap-align: center;
}
scroll-padding
プロパティ
scroll-padding
プロパティは、
- スクロールコンテナ内に
padding
を設定するかどうか
を指定できます。
scroll-padding
プロパティについては、例を使いながら説明をします。
たとえば、このような固定ヘッダーがあるページで、CSS Scroll Snap
を使用した場合を考えます。
<div class="container">
<header></header>
<div class="scroll-container start">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=start1" alt="">
<img src="http://placehold.jp/3d4070/ffffff/250x250.png?text=start2" alt="">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=start3" alt="">
</div>
</div>
body{
margin:0;
}
.container {
display: flex;
}
header {
position: fixed;
width: 100vw;
height: 100px;
background: rgba(255,0,255,.3);
top: 0;
left: 0;
}
.scroll-container {
display: flex;
flex-direction: column;
overflow-y: scroll;
scroll-snap-type: y mandatory;
max-height: 100vh;
scroll-padding-top: 150px;
}
img {
margin-bottom: 5px;
}
.start img {
scroll-snap-align: start;
}
従来の方法であれば、padding-top
を固定ヘッダーの高さ分設定することで、固定ヘッダーの部分に余白が作られ、コンテンツ全体が表示されるようになります。
しかし、CSS Scroll Snap
を使用すると、padding-top
を設定していても、スクロール位置を調整する際にpadding
を無視したスクロール位置の調整が行われます。
こちらはpadding-top
のみを設定したときの例です。一度スクロールすると、スクロール位置の調整が行われ、padding-top
分を無視したスクロール位置の調整が行われることがわかると思います。
<div class="container">
<header></header>
<div class="scroll-container start">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=start1" alt="">
<img src="http://placehold.jp/3d4070/ffffff/250x250.png?text=start2" alt="">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=start3" alt="">
</div>
</div>
body {
margin: 0;
}
.container {
display: flex;
max-height: 100vh;
}
header {
position: fixed;
width: 100vw;
height: 100px;
background: rgba(255, 0, 255, 0.3);
top: 0;
left: 0;
}
.scroll-container {
display: flex;
flex-direction: column;
overflow-y: scroll;
scroll-snap-type: y mandatory;
max-height: 100vh;
padding-top: 100px;
}
img {
margin-bottom: 5px;
}
.start img {
scroll-snap-align: start;
}
この動作を防ぐために、scroll-padding
プロパティを使うことができます。
scroll-padding
プロパティを使うことで、スクロール位置の調整にもpadding
が考慮されるようになります。
scroll-padding
プロパティを使った時の動作はこのようになります。
<div class="container">
<header></header>
<div class="scroll-container start">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=start1" alt="">
<img src="http://placehold.jp/3d4070/ffffff/250x250.png?text=start2" alt="">
<img src="http://placehold.jp/3d4070/ffffff/450x450.png?text=start3" alt="">
</div>
</div>
body {
margin: 0;
}
.container {
display: flex;
max-height: 100vh;
}
header {
position: fixed;
width: 100vw;
height: 100px;
background: rgba(255, 0, 255, 0.3);
top: 0;
left: 0;
}
.scroll-container {
display: flex;
flex-direction: column;
overflow-y: scroll;
scroll-snap-type: y mandatory;
max-height: 100vh;
padding-top: 100px;
scroll-padding-top: 100px;
}
img {
margin-bottom: 5px;
}
.start img {
scroll-snap-align: start;
}
scroll-margin
プロパティ
scroll-margin
プロパティは、
- スクロールコンテナに対する
margin
を設定するか
を指定できます。
(※このプロパティの動作については、十分に理解できていないので、この部分は改めて追記する予定です。)
ブラウザの対応状況
Can I use によると、Google Chrome, Safari はCSS Scroll Snap
をサポートしているようですが、その他のブラウザでのサポートはまだ十分ではありません。また、現在の段階ではGoogle Chrome, Safari間の実装にも差異がある可能性が残っているため、注意が必要です。
以上。