スナップ(ひっかかり)のあるスクロールをするのに昔はJSを利用してましたが、CSSのscroll-snapだけでも実現できるようです。実際に作ってみたら、まったくカン・タン・だった。それではいきましょう!
【目次】
- スナップなしのスクロール
- 縦スクロールのスナップ(scroll-snap-type: y mandatory)
- 横方向のスナップ(scroll-snap-type: x mandatory)
- scroll-snapの対応ブラウザ
- 最後に
スナップなしのスクロール
まずはscroll-snapを未設定の画面
See the Pen scroll-snap 1 by イイダリョウ (@i_ryo) on CodePen.
架空の映画予告編風w
HTMLコード
<div class="slide"> <p>この夏!</p> <p>全日本が!</p> <p>全米が!</p> <p>そして…</p> <p>全世界が!!</p> <p>この映画で、</p> <p>泣くことになる!!!</p> <p>監督 イイダリョウ</p> <p>主演 イイダリョウ</p> <p>『クモのようにコツコツと』</p> <p>近日公開</p> </div>
. slideの中にpタグがいくつか入っている。
CSSコード
.slide { width: 100vw; height: 100vh; overflow: scroll; } .slide p { width: 100vw; height: 100vh; line-height: 100vh; text-align: center; font-size: 50px; font-family: sans-serif; font-weight: bold; color: #fff; background: #000; } .slide p:nth-child(2n) { background: #222; }
. slide:幅、高さ共に画面いっぱい。オーバーフローはスクロールあり。.slide p:幅、高さ共に画面いっぱい。文字色は白、背景は真っ黒#000.slide p:nth-child(2n):偶数番目を少し薄い黒#222に変更
画面いっぱいにする設定はvhとvw。詳しくはこちら。
※参考:もしかしてだけどCSSのvwやvhを使うとメディアクエリ無しでレスポンシブ対応できちゃうんじゃないの?(オマケにvmin、vmaxも) - クモのようにコツコツと
縦スクロールのスナップ(scroll-snap-type: y mandatory)
縦スクロールにスナップ設定をしてみた。
See the Pen scroll-snap 2 by イイダリョウ (@i_ryo) on CodePen.
HTMLコードは変更なし。CSSコードの変更点
.slide { /*中略*/ scroll-snap-type: y mandatory; } .slide p { /*中略*/ scroll-snap-align: start; }
.slideにscroll-snap-typeプロパティを設定。値はy mandatory.slide pにscroll-snap-alignプロパティを設定。値はstart
scroll-snap-typeの値の一つ目は方向でyは縦。mandatoryがあると途中で止まらずに必ず境界まで画面がスナップする。ない場合は境界に近いときだけスナップする。
※参考:scroll-snap-type - CSS: カスケーディングスタイルシート | MDN
子要素のpタグにはscroll-snap-align: startを設定する。これで親要素のスナップ設定と紐づく。
横方向のスナップ(scroll-snap-type: x mandatory)
今度は横方向にスナップしてみる。
See the Pen scroll-snap 3 by イイダリョウ (@i_ryo) on CodePen.
スライドみたいな動き。
CSSコード
.slide { /*中略*/ overflow-x: scroll; display: flex; scroll-snap-type: x mandatory; } .slide p { /*中略*/ flex: none; scroll-snap-align: start; }
.slideのoverflowプロパティをoverflow-xプロパティに
display: flexを設定
scroll-snap-typeプロパティのyをxに.slide pにflex: noneを追加
overflowのスクロールは横方向のみにしたいのでoverflow-xプロパティにする。
子要素(pタグ)を横並びにしたいのでdisplay: flexにしたが、子要素の横幅設定が保持されず画面内に等分されたため、子要素にはflex: noneを設定した。
flexについてはこちらを参照。
※参考:flex-CSSリファレンス
flexプロパティは、フレックスコンテナ内のアイテムの幅についてまとめて指定する際に使用します。 flex-growプロパティ・ flex-shrinkプロパティ・ flex-basisプロパティ の値を、flexプロパティ一つでまとめて指定できるので便利です。
flex-growプロパティの値では、フレックスコンテナ内のアイテムの伸び方の比率を指定
flex-shrinkプロパティの値では、フレックスコンテナ内のアイテムの縮み方の比率を指定
最後のflex-basisについては下記の記事で触れた。
※参考:固定幅と可変幅の組み合わせにはflex-basisが まったく カン・タン・だ! - クモのようにコツコツと
そしてnoneの設定は0 0 auto。 flex-grow、flex-shrinkともに無効になる。
scroll-snapの対応ブラウザ
scroll-snapはほとんどのブラウザで対応している。IEやEdgeはベンプレ-msが必要みたい。でも、scroll-snapがなくても最初の例のようなスナップなしの動きになるだけなので、たいした影響はないかもしれない。
※参考:Can I use... Support tables for HTML5, CSS3, etc
最後に

ということで、スナップ機能はまったくカン・タンに実装できました!ストーリーテリング的なサイトとか、プレゼンのスライドを再現するのに良さそうです!HTMLがシンプルなのもいいですね。それではまた!
※参考:ネイティブHTML & CSSやってみたシリーズ
qiita.com