こんにちは。mamenoです。
今回は、fullpage.jsのような、1スクロールで1セクション移動するデザインをコーディングしたときに、Edgeではまって後悔したので備忘録として残しておこうと思います。
デモはこちら(コードペンが開きます)。
- はじめにやったこと
- scroll-snap-typeがEdgeでスムーズにいかない
- 考えを変えて、スライダーのライブラリを使ってみる
- swiper.jsでのフルページスクロールの作り方
- フルページの実装の際に気をつけるべきだと思ったこと
はじめにやったこと
fullpage.js 使わない で検索しました。 Fullpage.jsはどうやら商用利用の際はお金がかかるそうなので、それを使わない実装方法を検索。
そしたら、こんな記事がありました。
モダンなJSとCSSで作るライブラリ不要の全画面スクロール演出(2019年版)
デモもあったので確認したら、まさに求めていた動き! こちらを利用させてもらって中身のコーディングをすすめました。
しかし、この時点で私は考慮すべきことを忘れていました。
そう、chrome以外のブラウザでの確認です。
scroll-snap-typeがEdgeでスムーズにいかない
Edge + マウスでの動作確認の際、 動きがカクつく現象が発生しました。
確認してみると、そもそも参考にしたデモサイトでも同じような動きになっていました...
今後こういった広範囲に関係する実装をする時は、デモサイトも主要ブラウザで確認しようと強く思いました...
ということで、scroll-snap-typeがEdgeでカクつく現象をどうにかする方法はないかと調べました。
chatGPTにも聞いたら、以下の対応をしてみてはどうかと提案を受けましたのでやってみました。
1. スクロールパフォーマンスの最適化
スムーズスクロールの有効化: Edge では scroll-behavior: smooth; を使用して、スクロールの挙動をスムーズにすることができます。
html { scroll-behavior: smooth; }
もともとやっておりました。なので効果なし。
2. スクロールスナップのプロパティ調整
scroll-snap-type の値を調整してみてください。mandatory から proximity に変更することで、ユーザーがページをスクロールした際の挙動が改善される場合があります。
.container { scroll-snap-type: y proximity; }
- mandatory...現在表示しているセクションか、次のセクション、どちらかを強制的にスナップさせる(前後のセクションが見切れることがない)
- proximity...強制的にスナップさせず、スナップ位置に近ければスナップ位置に合わせる。各スナップ位置の中間地点でスクロールが止まっている場合はその位置でとまる(前後のセクションが見切れることがある)。
proximityはそもそもの要件には満たないこと(確実にどちらかのセクションでスナップさせたかった)、実際やってみても効果を感じられなかったのでこちらもなし。
3. ハードウェアアクセラレーションの利用
CSS の will-change プロパティを使用して、ブラウザにどのプロパティが変更される可能性があるかを事前に知らせ、ハードウェアアクセラレーションの利用を促します。スクロールパフォーマンスが向上することがあります。
.scroll-container { will-change: scroll-position; }
こちらのプロパティは知りませんでした。
とりあえず適用してみましたが効果なし。
ただ、今調べていたらこんな記事が。
will-changeを使ってなめらかなアニメーションを作成しよう
Edgeはサポートしていないので代わりが必要??っぽかったです。
詳しくなくてすみません。気になる方は調べてみてください。
ということで、いまいち解決策が見つからなかったので別の手段で実装できないか考えることにしました。
考えを変えて、スライダーのライブラリを使ってみる
いろいろ考えているうちに、
要はこれって、フルスクリーンのスライドが縦に動いてるってことだよねと考え、だったらswiper.jsに代表されるスライダーのライブラリでいい感じにできるのではないかと思いました。
swiper.jsでのフルページスクロールの作り方
大体ググれば説明してくれているのがありますが、こちらにも一応書いておきます。
1. CDNの読み込み
実際の案件ではCDNではなくnpmなどでインストールするのがいいとは思いますが、簡単なデモなのでCDNで書いておきます。
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> //CDN読み込み <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"/> <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js" defer></script> </head> <body> </body> </html>
2. オリジナルCSSの作成
style.cssを作成し、head内にリンクおき、以下を記述
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"/> //CSSよみこみ <link rel="stylesheet" href="style.css"> <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js" defer></script> </head> <body> </body> </html>
style.css
/* 全てのmargin・paddingを0に */ *, *::after, *::before { margin: 0; padding: 0; } section.fullpage-wrapper { position: relative; height: 100vh; overflow: hidden; } section.fullpage-wrapper .fullpageSwiper { height: 100%; background: #f1f1f1; } .swiper-slide { display: flex; align-items: center; justify-content: center; font-weight: bold; -ms-touch-action: auto; touch-action: auto; } /* わかりやすいように色を変えているだけ */ .swiper-slide.slide1, .swiper-slide.slide3, .swiper-slide.slide5 { background: #acacac; }
3. swiperの設定をオリジナルのJSファイルに書く
script.jsを作成し、head内にリンクをおき、以下を記述
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"/> <link rel="stylesheet" href="style.css"> <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js" defer></script> //JSよみこみ <script src="script.js" defer></script> </head> <body> </body> </html>
script.js
var swiper = new Swiper(".fullpageSwiper", { direction: "vertical", slidesPerView: 1, mousewheel: true, autoHeight: true, speed: 1000, keyboard: { enabled: true, }, mousewheel: { releaseOnEdges: true, forceToAxis: true, sensitivity: 1, }, pagination: { el: ".swiper-pagination", clickable: true, }, });
以上です。
デモはこちら(コードペンが開きます)。
フルページの実装の際に気をつけるべきだと思ったこと
最近流行りの?横スクロールもそうですが、縦幅が短い、横長のPCでの考慮をしないと、縦にコンテンツがはみ出してしまって上下みきれてしまう現象が発生してしまいます。
参考元:
コンテナを100vhにして、overflow:hiddenに設定すると、このような現象になってしまいます。 こちらについても考慮する必要があるなと感じました。
ひとまず気をつけるべきは上下の余白設定。 px・rem・emなどの固定値ではなく、vh・%での指定や、@media screen and (max-height: ●●px)など、こまかい指定が必要だと思いました。