見出し画像

フルページスクロールの実装について - (1)まずは全画面表示のページを作成

要件

  1. フルページで遷移したい(fullPage.js の様な挙動をさせたい)

  2. スマホのスクロールでアドレスバーが隠れて画面の高さが変わってしまう問題を対応する

  3. 画面内に収まらないコンテンツはスクロールして全体を表示できるようにする
    (次のコンテンツが表示されるまでは自動的にスクロールさせない)

  4. フッターまできたら普通にスクロール

  5. PC表示では1画面2分割されているコンテンツが、スマホ時は2画面となり、各画面フルページスクロールで遷移する

  6. 一通りページのコーディングが終わせて、最後にクラスを付与するだけでフルページスクロールが実現できるようにしたい

※太字部分が今回の対応内容

今回の対応内容

  • 全画面表示のコンテンツを作成

  • PC時は1画面2分割のコンテンツだが、スマホ時は2画面のコンテンツとして表示させる

  • とりあえずUA、UADataによるスマホ判定を入れる
    (未だコレといった代替方法が決まらないので…)

①HTMLを準備

ざっくり全画面表示とPC時2分割表示のコンテンツを用意。

index.html
---

<!DOCTYPE html>

<html lang="ja" dir="ltr">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>フルページスクロールの実装について<br> - (1)まずは全画面表示のページを作成</title>
<link rel="stylesheet" href="css/destyle.css" />
<link rel="stylesheet" href="css/style.css" />
</head>

<body>
<div class="l-wrapper">
<header class="l-header">
<h1>フルページスクロールの実装について<br> - (1)まずは全画面表示のページを作成</h1>
</header>

<main class="l-main">
<section class="p-section">
<h2>要件</h2>
<ol>
<li>フルページで遷移する(fullpage.jsの様な挙動をさせたい)</li>
<li>スマホのスクロールでアドレスバーが隠れて画面の高さが変わってしまう問題を対応する</li>
<li>1画面内に収まらないコンテンツはスクロールして全体を表示できるようにする<br>(次のコンテンツが表示されるまでは自動的にスクロールさせない)</li>
<li>フッターまできたら普通にスクロール</li>
<li>PC表示では1画面2分割されているコンテンツが、スマホ時は2画面フルページで遷移する</li>
<li>一通りコーディングが終わってからクラスを付与するだけでフルページスクロールできるようにしたい</li>
</ol>
</section>

<section class="p-section bg-gray">
<h2>1. まずはマークアップ</h2>
<p>とりあえずシンプルに1コンテンツ1セクションとしてマークアップ。</p>
</section>

<section class="p-section">
<h2>2. 1コンテンツが全画面表示となるようスタイル作成</h2>
<p><code>.p-section</code>に<code>height: 100vh;</code>を設定。</p>
<p>要件2. の対応について、今回はスマホによる表示時(※2)<code>.p-section</code>に<code>padding-bottom: 72px;</code>を設定。</p>
<p>※ <code>height: 100svh;</code>はFirefoxが非対応のため使わない。<br>【参考】<a href="https://caniuse.com/?search=svh" target="_blank">svh | Can I use</a></p>
<p>※2 スマホ表示時htmlタグ等に<code>.ua-mobile</code>を付与するUA判定処理をJSで追加予定</p>
</section>

<div class="p-column">
<section class="p-section bg-gray">
<h2>3. 要件3. の対応</h2>
<p>1画面2分割されたコンテンツが、スマホ表示では2画面コンテンツになる。</p>
</section>

<section class="p-section bg-gray2">
<h2>スマホ時には全画面コンテンツとなる</h2>
<p>ここのコンテンツが、PCでは右側に表示され、スマホでは次の全画面コンテンツになる。</p>
</section>
</div>
</main>

<footer class="l-footer">
<h2>ここはフッター</h2>
<p>フッターに来たら普通のスクロール。</p>
</footer>
</div>

<script src="js/app.js"></script>
</body>
</html>

全画面表示のコンテンツは、.p-section とした。
また、2分割のコンテンツは 2つの .p-section 要素を .p-column で囲んだ。

②スタイルの準備

今回、リセットCSSは destyle.css を使用する。(これは何でも良い)
作成するスタイルは style.css に記述する。

※scss形式で記載しています。一部ブラウザでは効かないため、CSSとして利用する場合は下部に用意したサンプルコードをご確認ください。

css/style.css(scss形式で記載)
---

/* element */
html {
    min-height: 100%;
}

body {
    height: 100vh;
}


/* .l-wrapper */
.l-wrapper {
    position: relative;
    min-height: 100vh;
}


/* .l-header */
.l-header {
    display: flex;
    align-items: center;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100px;
    padding: 0 20px;
    background-color: rgba(255, 255, 255, 0.8);
    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.06);
    backdrop-filter: blur(5px);

    h1 {
        font-size: 24px;
        font-weight: 700;
        line-height: 1.5;
    }
}


/* .p-section */
.p-section {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    padding: 130px 20px 30px;

    &.bg-gray {
        background-color: rgba(0, 0, 50, 0.1);
    }

    &.bg-gray2 {
        background-color: rgba(100, 100, 150, 0.1);
    }

    h2 {
        margin: 20px 0;
        font-size: 32px;
        font-weight: 700;
        line-height: 1.5;
    }

    p,
    ol {
        width: 100%;
        margin: 20px 0;
        font-size: 16px;
        line-height: 1.75;
        text-align: left;
    }

    ol {
      list-style-type: decimal;
    }

    li {
        line-height: 1.75;
    }

    ol {
        display: flex;
        flex-direction: column;
        gap: 10px 0;
        padding: 0 0 0 35px;
        list-style-type: number;
    }

    code {
        margin: 0 5px;
        padding: 5px;
        border-radius: 3px;
        background: rgba(0, 0, 0, 0.05);
    }
}


/* .l-footer */
.l-footer {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: center;
    height: 150vh;
    background-color: #333;
    color: #fff;

    h2 {
        font-size: 18px;
        font-weight: 700;
    }

    p {
        font-size: 14px;
    }
}


/* .p-column */
.p-column {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
}


/* スマホ表示 */
@media screen and (max-width: 767px) {
    .ua-mobile .p-section {
        padding-bottom: 72px;
    }

    .p-column {
        display: block;
    }
}

全画面コンテンツである .p-section は、min-height: 100vh; とする。
(svhを使用したいところだが、Firefoxが未対応のため止む無し)
【参考】svh | Can I use

なお min-height: 100vh; の設定だけでは、iPhoneやAndroidスマホ端末でアドレスバーが表示された状態だと1画面内にコンテンツが収まらないため(アドレスバー分下方向へ押し出されてしまうため)、スマホの幅 & .ua-mobile というクラスが(HTMLタグに)付与されている場合は、.p-section に padding-bottom: 72px; する、というスタイルも追加した。
ちなみに72px というのは、最近のスマホ用ブラウザのアドレスバーの高さを一般的に定義した数値。

③JSでスマホ端末判定

この判定は特になくても良いが、個人的にUA判定がどこまで使用できるのか確認したいので入れておく感じ。(2024年7月以降の挙動を確認したい)

document.addEventListener('DOMContentLoaded', () => {
  const html = document.documentElement;
  const body = document.body;
  const wrapper = document.querySelector('.l-wrapper');

  // スマホ判定(今回はuserAgent, userAgentDataを使用)
  const setUaMobile = () => {
    const ua = navigator.userAgent;
    const iphone = ua.indexOf('iPhone') > 0;
    const android = ua.indexOf('Android') > 0 && ua.indexOf('Mobile') > 0;
    const uaData = navigator.userAgentData;
    if (iphone || android || (uaData && uaData.mobile)) {
      html.classList.add('ua-mobile');
    } else {
      html.classList.remove('ua-mobile');
    }
  };
  setUaMobile();
  window.addEventListener('resize', () => {
    setUaMobile();
  });
});

navigator.userAgent では取れなくなるというが、2024年7月以降も動くか…(ドキドキ)

※userAgentDataがnullの場合も当然あるため条件文を修正しました。

まとめ

ということで、今回はフルページスクロールの準備段階として、ベースとなる HTML・CSS と、JSの準備をした。

次回は、今回用意したコードに対し、HTMLの構成を変えることなくクラスを付与するだけで fullPage.js の様にフルページスクロールするコンテンツが作れるような JavaScript のコードを組み、スタイルを調整して完成させる。

今回のサンプル


この記事が気に入ったらサポートをしてみませんか?