scroll-snapを使ってみる

スクロール時のスナップ制御を設定できる、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-typeのデモページ

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-snap-stopのデモページ

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-paddingのデモページ

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;
}

scroll-marginのデモページ

参考サイト

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2025年8月
 12
3456789
10111213141516
17181920212223
24252627282930
31