このチュートリアルでは、ユーザーがスクロールすると、あるフルスクリーンセクションから別のセクションにスナップするページを作成します。 この効果は、 fullpage.js
ライブラリによって普及しました。 しかし今では、フルページへのライセンスの変更(今はそれを支払う必要があります)、新しいCSSスクロールスナップモジュール、および交差オブザーバーAPIの完全なブラウザーサポートにより、より良いオプションがあります。
したがって、fullpage.jsの代替を探している場合は、ライブラリ全体が必要ない場合もあります。自分でコーディングするだけです。
実際、スナップ効果は100%CSSです。 JSは、画面が「スナップ」して表示されるときに要素をフェードインするために使用されます。
インスピレーションを得るために、CodePenで入手可能なMichelleBarkerによるこの「DinosaurParkスクロールスナップデモ」を利用します。
CSSをIntersectionObserverと組み合わせて使用することで、ページの各フルスクリーンセクションをスナップスクロールし、ビューポートに入るときにコンテンツをフェードインします。
さらに良いことに、それはわずか30行のJSコードです! アニメーションはCSSで行われます。 私たちがする必要があるのは、セクションとコンテンツがJSでビューポートに入るタイミングを理解することだけです。
1)ページを作成する
まず、ページを作成するか、この単純な効果と互換性があるように既存のページを構成する必要があります。 ここで注意すべきことが2つあります。
セクションを含む<main>
要素を使用しています。 このメイン要素は100vhであり、その中の各<section>
要素も同様です。
HTML:
<main> <section class = "section section-1"> <div class ="section__content"data-content>内部のコンテンツ</div></ section> <section class = "section section-2"> <div class = "section__content"data-content>コンテンツ内部</div></ section> <section class = "section section-3"> <header class = "section__header"> <h3class="section__title">探索と発見</h3 > </ header> <div class ="section__content"data-content>内部のコンテンツ</div></ section> </ main> CSS:
/*スクロール動作*/@media(min-height:30em){main {scroll-snap-type:y必須; 高さ:100vh; オーバーフロー-y:スクロール; }} .section {色:白; 位置:相対; scroll-snap-align:center; 表示:フレックス; フレックス方向:列; 最小-高さ:100vh; } @media(min-height:30em){.section {height:100vh; }} 2)CSSでスナップを構成する
ここでは、高さが100vhのセクションが複数あることがわかります。
<main>要素も100vhで、overflow-y:scrollがあります。
ユーザーにとって、スクロールの動作はデフォルトのWebページと同じです。
上記のCSSを追加した場合、スナップ効果はすでに機能しています。 それがどのように機能するかを見てみましょう。
まず、「 @media (min-height: 30em)
」クエリは、高さが短いモバイル画面サイズのスナップ効果を無効にします。 メインセクションの下に、スナップを有効にする1つのプロパティがあります。
main {.... scroll-snap-type:y必須; ....} これは、「スクロールコンテナが存在する場合に、スナップポイントがスクロールコンテナにどの程度厳密に適用されるかを設定する」(MDN)というかっこいい小さなプロパティです。
そして、私たちのセクションの下に、私たちは持っています:
.section {.... scroll-snap-align:center; ....} このプロパティは、「ボックスのスナップ位置を、スナップコンテナのスナップポート(位置合わせコンテナとして)内のスナップ領域(位置合わせサブジェクトとして)の位置合わせとして指定します」(MDN)。
CSSスクロールスナップモジュールの詳細については、こちらをご覧ください。
そして、それはそれと同じくらい簡単です。 <main>コンテナ(すべてのセクション)内の直接の子は、<main>コンテナの中央にスクロールスナップします。 メインとセクションの両方が100vhであるため、スクロールはセクションからセクションにスナップします。
3)交差点オブザーバーを使用してコンテンツをフェードする
現在、全ページのスクロール効果があります。他に何もしたくない場合は、このセクションをスキップしてWebサイトを楽しむことができます。 ただし、各フルページセクションが表示されたら、その中のコンテンツをフェードインしたいと思います。これは、ユニークでクールな効果です(fullpage.jsでも可能です)。
これを行うには、交差オブザーバーを使用して、<main>ビューポート内のセクションの位置を理解します。
const section = [... document.querySelectorAll( "section")]; let options = {rootMargin: "0px"、threshold:0.75、}; const callback =(entries、observer)=> {entries.forEach((entry)=> {const {target} = entry; if(entry.intersectionRatio> = 0.75){target.classList.add( "is-visible") ;} else {target.classList.remove( "is-visible");}}); }; constobserver = new IntersectionObserver(callback、options); section.forEach((section、index)=> {const sectionChildren = [... section.querySelector( "[data-content]")。children]; sectionChildren.forEach((el、index)=> {el.style .setProperty( "-delay"、 `$ {index * 250} ms`);});observer.observe(section);}); ここで行われていることは2つあります。 まず、セクションがビューポートにあることを識別し、セクションが入ると、CSSクラス.is-visible
を追加します。 ビューポートを離れると、そのクラスが削除されます。
さらに、このセクションがビューポートに入ると、連続して(次々に)子要素のそれぞれに250msの遅延のプロパティが設定されます。 これにより、千鳥状のフェードイン効果が得られます。
これは、データコンテンツの属性を持つ要素内の子に対してのみ行われます。 したがって、フェードインを有効にする場合は、ページコンテンツのラッパーに追加する必要があります。
ここで、これを機能させるには、.is-visibleクラスが追加された要素のフェードインアニメーションを設定する必要があります。
@media(min-height:30em){.section__content> * {不透明度:0; 変換:translate3d(0、4rem、0); 遷移:不透明度800ms var(-delay)、変換800msキュービックベジェ(0.13、0.07、0.26、0.99)var(-delay); }} .is-visible .section__content> * {不透明度:1; 変換:translate3d(0、1rem、0); } .is-visible .section__img {不透明度:0.75; } 最初のデモからHTMLを参照すると、.section__contentのクラスとdata-content属性を持つコンテンツをラップアラウンドするdivがあることがわかります。
<main> <section class = "section section-1"> <div class ="section__content"data-content>内部のコンテンツ</div></ section> <section class = "section section-2"> <div class = "section__content"data-content>コンテンツ内部</div></ section> <section class = "section section-3"> <header class = "section__header"> <h3class="section__title">探索と発見</h3 > </ header> <div class ="section__content"data-content>内部のコンテンツ</div></ section> </ main> これにより、JSとCSSが結び付けられます。 ビューポートに入るときに交差オブザーバーによって.is-visible
クラスが追加されるまで、コンテンツの不透明度は0です。 離れると、不透明度0に戻るため、スクロール方向に関係なく、常にフィードが有効になります。
最後に、各子要素に連続して適用されるdelay
は、フェードイン効果をずらします。
3番目のセクションに注意してください。 セクションヘッダーはデータコンテンツセクション内にないため、フェードインしません(すでに存在します)。
すべてのコード
デモは次のとおりです。
デモで使用したすべてのコードは次のとおりです。
HTML
<main> <section class = "section section-1"> <div class = "section__content" data-content> <img class = "section__img section__img--left" src = "https:// s3-us-west-2 .amazonaws.com / s.cdpn.io / 85648 / trex.svg "alt =" T-rex"/><h2>内部のコンテンツ</h2><p> blah blah blah </ p> </ div> < / section> <section class = "section section-2"> <div class = "section__content"data-content><h2>内部のコンテンツ</h2><p> blah blah blah </ p> </ div> </ section> <section class = "section section-3"> <header class = "section__header"> <h3class="section__title">探索と発見</h3></ header> <div class = "section__content"data-content ><h2>内部のコンテンツ</h2><p> blah blah blah </ p> </ div> </ section> </ main> CSS
@media(min-height:30em){main {scroll-snap-type:y必須; 高さ:100vh; オーバーフロー-y:スクロール; }} .section {色:白; 位置:相対; scroll-snap-align:center; 表示:フレックス; フレックス方向:列; 最小-高さ:100vh; } @media(min-height:30em){.section {height:100vh; }} @media(min-height:30em){.section__content> * {不透明度:0; 変換:translate3d(0、4rem、0); 遷移:不透明度800ms var(-delay)、変換800msキュービックベジェ(0.13、0.07、0.26、0.99)var(-delay); }} .is-visible .section__content> * {不透明度:1; 変換:translate3d(0、1rem、0); } .is-visible .section__img {不透明度:0.75; } JS
const section = [... document.querySelectorAll( "section")]; let options = {rootMargin: "0px"、threshold:0.75、}; const callback =(entries、observer)=> {entries.forEach((entry)=> {const {target} = entry; if(entry.intersectionRatio> = 0.75){target.classList.add( "is-visible") ;} else {target.classList.remove( "is-visible");}}); }; constobserver = new IntersectionObserver(callback、options); section.forEach((section、index)=> {const sectionChildren = [... section.querySelector( "[data-content]")。children]; sectionChildren.forEach((el、index)=> {el.style .setProperty( "-delay"、 `$ {index * 250} ms`);});observer.observe(section);}); 結論
これは、フルスクリーンセクション間のスナップだけで止まらない完璧なfullpage.jsの代替手段です。 また、交差オブザーバーAPIを使用して、セクションがページに入るタイミングを理解し、千鳥アニメーションを動的に適用しました。 この基本的な例を使用して、最小限のバニラJSとCSSで構築し、いくつかの本当にクールな効果を作成できます。