CSSでスクロールスナップ(scroll-snap)の実装方法【デモ有】

スライド(スワイプ)で簡単に要素を切り替えることが出来るCSS「スクロールスナップ」についてご紹介します。

JavaScript(jQuery)で今までやらざるを得なかったスライド動作をCSSのみで軽快に行うことが出来ます。

現在は対応ブラウザも増えているため、用途が合えば採用してみましょう。

スクロールスナップとは?

スクロールスナップとは、ユーザーがスライド動作、スマホではスワイプ動作を行った時に、要素を特定の位置で静止させるスクロールが実現できます。

実際に見たほうが分かりやすいので、下記のGIFアニメーションをご確認ください。
このページで公開しているサンプルをスマホで操作した時の動きです。

こんな風に、要素毎にスクロールをスナップすることが出来ます。

1枚めくるような動作になるため、漫画やプレゼン資料を公開したい時などに向いています。

スクロールスナップ用プロパティの対応状況

スクロールスナップの実現は「scroll-snap-type」を親要素に指定することで実装できます。

ただし、出来たばかりのプロパティということで、古いブラウザには対応していない可能性があることは注意しておきましょう。

最新の(19年7月)の対応状況はこちらで、ほとんどの最新ブラウザは動作できます。

参考:scroll-snap-type :CSS

ただし、各ブラウザ毎に挙動が違い、中でもPC版Google Chromeはかなり使いづらい動きを取ります。

スワイプとの関連性という意味でも、スマホユーザー向きなプロパティと言えます。

スマホではAndroidのGalaxyなどが標準採用しているサムスンブラウザは対応していませんが、スクロール自体は問題なく動きます。

横スライドのスクロールスナップ

横スライドで動作するスクロールスナップについて、ソースコードと表示デモです。

横スライドのCSS+HTML

「以下デモ用のデザイン」は、各々の好みに合わせて調整してください。

.slider-x{
    /* 以下の設定は必須 */
    scroll-snap-type: x mandatory;
    width: 100%;
    overflow-x: scroll;
    display: flex;
    -webkit-overflow-scrolling: touch; /* スマホ対応のため必須 */
    overflow-scrolling: touch; /* スマホ対応のため必須 *
    
    /* 以下デモ用のデザイン */
    height: 100px;
}
.slider-x > div{
    /* 以下の設定は必須 */
    scroll-snap-align: center;
    height: 100%;
    width: 100%;
    flex: none;
    
    /* 以下デモ用のデザイン */
    color: #FFF;
    font-size: 150%;
    font-weight: bold;
    /* 文字の上下左右中央寄せのための記述 */
    display: flex;
    align-items: center;
    justify-content: center;
}

/* デモ用のデザイン */
.slider-x > div:nth-child(1){background-color: #C7000B}
.slider-x > div:nth-child(2){background-color: #D28300}
.slider-x > div:nth-child(3){background-color: #DFD000}
.slider-x > div:nth-child(4){background-color: #00873C}
.slider-x > div:nth-child(5){background-color: #005AA0}
<div class="slider-x">
    <div>子要素1</div>
    <div>子要素2</div>
    <div>子要素3</div>
    <div>子要素4</div>
    <div>子要素5</div>
</div>

横スライドのデモ

パソコンの方はスライドバーで移動を、スマホの方は横方向にスワイプを試してみてください。

子要素1
子要素2
子要素3
子要素4
子要素5

スマホはフレキシブルに動きますが、パソコンのGoogle Chromeブラウザでは、スクロールバーを長押ししないと移動しないため、中々不便かも。

そもそもパソコンのユーザーに横スクロールを強いるのはユーザビリティが悪いので、スマホユーザー向けのデザインと言えそうです。

また、レイアウトはcssのフレックスボックス(display:flex)を採用しています。

フレックスボックスが分からない方は解説記事もご確認ください。

CSSのdisplay:flexとは?サンプルコードで解説

カルーセルスライダー風のデモ

子要素のwidthを33.33%などに狭めると、一度に3要素まで表示されるカルーセルのようなデザインにも出来ます。

子要素1
子要素2
子要素3
子要素4
子要素5

画像を大量に見せたいギャラリーなどで活躍しそうですね。

PCは縦並び、スマホは横並びのレスポンシブデザイン

前述しましたが、パソコンで横スクロールを強いるのはユーザーに優しくないため、パソコンなどの画面領域が広いデバイスは、縦並びに変更できます。

media設定を入れてあげることで、パソコンの場合は「縦並び」表示にもできますのでお試しください。

/* PC用縦並びレイアウト */
@media screen and (min-width: 1030px){
    .slider-x{
        scroll-snap-type: none;
        overflow-x: visible;
        height: auto;
        -webkit-flex-direction: column;
        flex-direction: column;
    }
    .slider-x.responsible > div{
        height: 100px;
        width: auto;
    }
}

こちらは画面サイズで縦並びと横並びが切り替わるデモです。

子要素1
子要素2
子要素3
子要素4
子要素5

縦スライドのスクロールスナップ

縦スライドは、横スライドと少し仕様を変えていますので、ソースコードをご確認ください。

縦スライドのCSS+HTML

.slider-y{
    /* 以下の設定は必須 */
    scroll-snap-type: y mandatory;
    position: relative;
    width: 100%;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
    overflow-scrolling: touch;
    
    /* 以下デモ用のデザイン */
    height: 100px;
}
.slider-y > div{
    /* 以下の設定は必須 */
    scroll-snap-align: start;
    height: 100%;
    width: 100%;
    
    /* 以下デモ用のデザイン */
    color: #FFF;
    font-size: 150%;
    font-weight: bold;
    /* 文字の上下左右中央寄せのための記述 */
    display: flex;
    align-items: center;
    justify-content: center;
}

.slider-y > div:nth-child(1){background-color: #C7000B}
.slider-y > div:nth-child(2){background-color: #D28300}
.slider-y > div:nth-child(3){background-color: #DFD000}
.slider-y > div:nth-child(4){background-color: #00873C}
.slider-y > div:nth-child(5){background-color: #005AA0}
<div class="slider-x">
    <div>子要素1</div>
    <div>子要素2</div>
    <div>子要素3</div>
    <div>子要素4</div>
    <div>子要素5</div>
</div>

縦スライドのデモ

パソコンの方はスライドバーやマウスホイールでスクロールを、スマホの方は縦方向にスワイプを試してみてください。

子要素1
子要素2
子要素3
子要素4
子要素5

画面全体をスクロールスナップ化して、縦スクロールで画面を変化させていくオシャレなホームページをたまに見かけますが、そのような動きを再現できそうですね。

scroll-snap-alignで停止位置を決定

子要素に設定するscroll-snap-alignのプロパティを変更することで、停止位置を決めることが出来ます。

子要素が親要素の大きさに対して小さい場合、複数の子要素が映る場合にどのようにスライドさせたいかを決定できます。

3つのプロパティのデモを用意しましたのでご確認ください。。
※デモ用に、子要素は親要素に対して横幅を80%に設定しております。

.slider-x > div{
    width: 80%;
    scroll-snap-align: start; /*center, endも下記デモで掲載*/
}

scroll-snap-align:start

scroll-snap-align:startは要素の始点を基準に切り替えます。

子要素1
子要素2
子要素3
子要素4
子要素5

scroll-snap-align:center

scroll-snap-align:centerは要素の中央位置を基準に切り替えます。

子要素1
子要素2
子要素3
子要素4
子要素5

scroll-snap-align:end

scroll-snap-align:endは要素の終了地点を基準に切り替えます。

子要素1
子要素2
子要素3
子要素4
子要素5

このような動的な動きは、基本的にJavaScript(jQuery)だよりで実装していたのはもう過去の話。

このようなオシャレな挙動も、CSSで実装できるのは楽な時代になりましたね。

使いどころを見極めれば、サイトを彩る動きを取り入れることが出来ますので、是非お試しください。

以上、CSSでスクロールスナップ(scroll-snap)の実装方法、でした。

CSS