スクロール時のスナップ制御を設定できる、scroll-snapを試してみます。
対応ブラウザ
scroll-snapの実装で使用する主要なプロパティはscroll-snap-typeとscroll-snap-alignになります。
scroll-snap-typeの対応ブラウザとscroll-snap-alignの対応ブラウザですが、主要なブラウザでは特に問題なくサポートされています。
scroll-snap-type
それぞれのプロパティについて動作を確認してみます。
まずはscroll-snap-typeですが、コンテナ要素に対してスクロールの方向と種類を指定するプロパティになります。
スクロールの方向を試してみます。
<div class="contents-x"> <div class="item">A</div> <div class="item">B</div> <div class="item">C</div> <div class="item">D</div> <div class="item">E</div> </div> <div class="contents-y"> ~ 略 ~ </div>
方向の設定にはscroll-snap-typeにxやyを指定します。
CSSは必要な部分のみ抜粋しています。
.contents-x { display: flex; overflow-x: scroll; scroll-snap-type: x; } .contents-y { height: 500px; overflow-y: scroll; scroll-snap-type: y; } .item { scroll-snap-align: start; } .contents-x .item { flex-shrink: 0; }
xの場合は水平方向、yの場合は垂直方向になります。
scroll-snap-typeのデモページ1
方向の指定にはxやyの他にも、inlineやblock、bothがあります。
inlineとblockについてはxとyとイメージは近いですが、writing-modeに影響する(縦書きの場合は逆になる)という違いがあります。
bothは水平方向と垂直方向の両方になります。
scroll-snap-typeの残りの値のmandatoryとproximityも試してみます。
<div class="contents mandatory"> ~ 略 ~ </div> <div class="contents proximity"> ~ 略 ~ </div>
mandatoryは近いスナップ位置に必ずスナップ、proximityはユーザーのスクロール速度に応じて、スナップ位置が近い場合にのみスナップします。
.contents { display: flex; overflow-x: scroll; } .contents.mandatory { scroll-snap-type: x mandatory; } .contents.proximity { scroll-snap-type: x proximity; }
PCよりスマホのスワイプで確認した方が違いが分かりやすいかもしれません。
scroll-snap-typeのデモページ2
scroll-snap-align
次はscroll-snap-alignで、コンテナ内の子要素に対してスナップする位置を指定するプロパティになります。
<div class="contents start"> ~ 略 ~ </div> <div class="contents center"> ~ 略 ~ </div> <div class="contents end"> ~ 略 ~ </div>
値にはstartかcenter、endを取ります。
.contents { display: flex; overflow-x: scroll; scroll-snap-type: x; } .item { flex-shrink: 0; } .contents.start .item { scroll-snap-align: start; } .contents.center .item { scroll-snap-align: center; } .contents.end .item { scroll-snap-align: end; }
scroll-snap-stop
scroll-snap-stopは各スナップ位置にスナップするかどうかを指定します。
<div class="contents normal"> ~ 略 ~ </div> <div class="contents always"> ~ 略 ~ </div>
値はnormalかalwaysを取り、alwaysの場合は各スナップ位置で停止するようになります。
.contents { display: flex; overflow-x: scroll; scroll-snap-type: x mandatory; } .item { flex-shrink: 0; scroll-snap-align: start; } .contents.normal .item { scroll-snap-stop: normal; } .contents.always .item { scroll-snap-stop: always; }
scroll-padding
scroll-paddingはコンテナ要素に対して、スナップ位置にオフセットを設定する(位置をずらす)指定になります。
<div class="contents"> ~ 略 ~ </div>
例えば以下の場合、start(左)から100pxの位置にスナップするようになります。
.contents { display: flex; overflow-x: scroll; scroll-snap-type: x mandatory; scroll-padding: 100px; } .item { scroll-snap-align: start; flex-shrink: 0; }
scroll-margin
scroll-marginはコンテナ内の子要素に対して、スナップ範囲を広げる指定になります。
<div class="contents"> ~ 略 ~ </div>
.contents { display: flex; overflow-x: scroll; scroll-snap-type: x mandatory; } .item { scroll-snap-align: start; flex-shrink: 0; } .item:nth-child(2) { scroll-margin: 30px; } .item:nth-child(3) { scroll-margin: -30px; } .item:nth-child(4) { scroll-margin: -10px; } .item:nth-child(5) { scroll-margin: 10px; }
コメントが承認されるまで時間がかかります。