スクロールスナップを理解し使いこなす:サンプルコード集
スクロールスナップの仕組み
従来のスクロールでは、コンテンツは滑らかに動き、ユーザーは任意の位置で停止できました。一方、スクロールスナップ では、コンテンツを特定の領域(スナップポイント)に自動的に吸着させる機能が追加されます。まるで磁石のように、コンテンツがスナップポイントにピタッと収まるイメージです。
scroll-snap-align の役割
scroll-snap-align は、スナップポイントにおけるコンテンツの整列位置を決定します。具体的には、以下の2つの軸方向における整列を制御できます。
- インライン軸方向
横方向のスクロールの場合、要素の左端、中央、右端などを指定できます。 - ブロック軸方向
縦方向のスクロールの場合、要素の開始位置、中央、終了位置などを指定できます。
scroll-snap-align の構文
scroll-snap-align プロパティは、以下の値をカンマ区切りで2つ指定します。
- 2つ目の値
インライン軸方向における整列位置 - 1つ目の値
ブロック軸方向における整列位置
それぞれの方向に以下のいずれかの値を指定できます。
- align-items
要素の align-items プロパティの値に準拠 - nearest
スクロール方向に最も近い整列位置に整列 - end
要素の終了位置に整列 - center
要素の中央に整列 - start
要素の開始位置に整列
例
.container {
scroll-snap-type: mandatory; /* スナップを強制 */
scroll-snap-align: center start; /* 中央揃えかつ左揃え */
}
この例では、.container
要素は常に中央揃えかつ左揃えにスナップされます。
スクロールスナップ動作の調整
scroll-snap-type プロパティと併用することで、スクロールスナップの動作をさらに調整できます。scroll-snap-type の主な値は以下の通りです。
- proximity
スナップポイントに近い場合のみスナップ - mandatory
スナップを強制(常にスナップポイントに留まる) - none
スナップを無効化
例
.container {
scroll-snap-type: proximity; /* スナップポイントに近い場合のみスナップ */
scroll-snap-align: center start;
}
この例では、.container
要素は、スクロール位置がスナップポイントに十分近づいた場合のみ中央揃えかつ左揃えにスナップされます。
実用的な例
例1:セクションをページング
この例では、scroll-snap を使用して、セクションをページングのように表示します。
<div class="container">
<section class="page">...</section>
<section class="page">...</section>
<section class="page">...</section>
</div>
.container {
display: flex;
flex-direction: column;
overflow-y: auto;
scroll-snap-type: mandatory;
scroll-snap-align: start;
}
.page {
flex: 1; /* 各セクションが同じ高さを占めるように設定 */
}
例2:横方向にスナップするギャラリー
この例では、scroll-snap を使用して、画像を横方向にスナップするギャラリーを作成します。
<div class="container">
<img src="image1.jpg" class="item">
<img src="image2.jpg" class="item">
<img src="image3.jpg" class="item">
</div>
.container {
display: flex;
overflow-x: auto;
scroll-snap-type: mandatory;
scroll-snap-align: start center;
}
.item {
flex: 0 0 50%; /* 各画像が幅50%になるように設定 */
margin: 0 10px; /* 画像
基本的な例
この例は、scroll-snap-align を使ってセクションを垂直方向にスナップする方法を示しています。
<div class="container">
<section class="page">セクション 1</section>
<section class="page">セクション 2</section>
<section class="page">セクション 3</section>
</div>
.container {
display: flex;
flex-direction: column;
overflow-y: auto;
scroll-snap-type: mandatory;
scroll-snap-align: center start;
}
.page {
flex: 1;
text-align: center;
padding: 20px;
border: 1px solid #ccc;
margin-bottom: 10px;
}
説明
.page
にpadding: 20px; border: 1px solid #ccc; margin-bottom: 10px;
を設定することで、セクションに余白とボーダーを追加します。.page
にtext-align: center;
を設定することで、セクション内のテキストを中央揃えにします。.page
にflex: 1;
を設定することで、各セクションが均等な高さを占めるようにします。.container
にscroll-snap-align: center start;
を設定することで、セクションを中央揃えかつ左揃えにスナップします。.container
にscroll-snap-type: mandatory;
を設定することで、スクロールをスナップポイントに強制的に吸着させます。.container
にoverflow-y: auto;
を設定することで、垂直方向のスクロールバーを表示します。.container
にdisplay: flex; flex-direction: column;
を設定することで、セクションを縦方向に並べます。
実行結果
このコードを実行すると、ブラウザウィンドウよりも背の高い3つのセクションが表示されます。ユーザーは、セクション間を上下にスクロールし、各セクションが中央揃えかつ左揃えにスナップされる様子を確認できます。
横方向スナップ
この例は、scroll-snap-align を使って画像を横方向にスナップする方法を示しています。
<div class="container">
<img src="image1.jpg" class="item">
<img src="image2.jpg" class="item">
<img src="image3.jpg" class="item">
</div>
.container {
display: flex;
overflow-x: auto;
scroll-snap-type: mandatory;
scroll-snap-align: start center;
}
.item {
flex: 0 0 50%; /* 各画像が幅50%になるように設定 */
margin: 0 10px;
border: 1px solid #ccc;
}
説明
.item
にmargin: 0 10px; border: 1px solid #ccc;
を設定することで、画像に余白とボーダーを追加します。.item
にflex: 0 0 50%;
を設定することで、各画像が幅50%になるようにします。.container
にscroll-snap-align: start center;
を設定することで、画像を左揃えかつ中央揃えにスナップします。.container
にscroll-snap-type: mandatory;
を設定することで、スクロールをスナップポイントに強制的に吸着させます。.container
にoverflow-x: auto;
を設定することで、横方向のスクロールバーを表示します。.container
にdisplay: flex;
を設定することで、画像を横方向に並べます。
実行結果
このコードを実行すると、ブラウザウィンドウよりも幅の広い3つの画像が表示されます。ユーザーは、画像間を左右にスクロールし、各画像が左揃えかつ中央揃えにスナップされる様子を確認できます。
JavaScript によるプログラム制御
- イベントリスナーとスクロール制御
JavaScript でイベントリスナーを使用してスクロールイベントを検出し、それに応じて要素をプログラムでスナップさせることもできます。この方法は柔軟性がありますが、scroll-snap-align よりも複雑でコード量が多くなります。 - ライブラリ使用
Smooth Scrolling Libraryなどのライブラリを使用することで、JavaScriptでスナップ機能を再現できます。これらのライブラリは、scroll-snap-align の互換性や、より高度なアニメーション機能を提供する場合があります。
場合によっては、scroll-snap-align の代替として以下のCSSプロパティが役立ちます。
- transform: translateX/Y
JavaScriptを使用して、要素をプログラムで移動させ、スナップ効果をシミュレートすることができます。高度なアニメーションや動的なレイアウトに適しています。 - position: sticky
要素を画面内に固定し、スクロールしても常に表示させることができます。ナビゲーションバーなどに適しています。
最適な代替方法の選択
最適な代替方法は、要件や状況によって異なります。
- 特定のユースケース に適した代替方法もあります。例えば、ナビゲーションバーには position: sticky 、アニメーションには transform が適しています。
- より高度な機能や柔軟性が必要な場合は、JavaScriptによるプログラム制御 を検討してください。
- **シンプルでクロスブラウザ互換性に優れた方法が必要な場合は、scroll-snap-align がおすすめです。