クモのようにコツコツと

フロントエンドエンジニア イイダリョウのブログ。略称「クモコツ」

【CSS】scroll-snapでスナップ(引っかかり)のあるスクロールがまったくカン・タン・だ!

スナップ(ひっかかり)のあるスクロールをするのに昔はJSを利用してましたが、CSSの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に変更

画面いっぱいにする設定はvhvw。詳しくはこちら。

※参考:もしかしてだけど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;
}
  • .slidescroll-snap-typeプロパティを設定。値はy mandatory
  • .slide pscroll-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;
}
  • .slideoverflowプロパティをoverflow-xプロパティに
    display: flexを設定
    scroll-snap-typeプロパティのyx
  • .slide pflex: 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 autoflex-growflex-shrinkともに無効になる。

scroll-snapの対応ブラウザ

scroll-snapはほとんどのブラウザで対応している。IEやEdgeはベンプレ-msが必要みたい。でも、scroll-snapがなくても最初の例のようなスナップなしの動きになるだけなので、たいした影響はないかもしれない。

※参考:Can I use... Support tables for HTML5, CSS3, etc

最後に

f:id:idr_zz:20190831153116j:plain

ということで、スナップ機能はまったくカン・タンに実装できました!ストーリーテリング的なサイトとか、プレゼンのスライドを再現するのに良さそうです!HTMLがシンプルなのもいいですね。それではまた!