ホーム

レスポンシブレイアウト

レスポンシブレイアウト

概要

異なる画面サイズに応じたスタイルを適用しています。これにより、デスクトップ、タブレット、モバイルデバイスでの表示が最適化されます。縦スクロールには多くの人がなれていますが、横スクロールは一般的ではありません。そのため、デバイスによって決まる画面の横幅で、CSS によるデザインを切り替えることが一般的です。

方法

画面幅に応じて適用するスタイルを変えるメディアクエリを活用する方法が主流です。

###  メディアクエリを活用

基本構文

メディアクエリの基本構文は以下の通りです:

@media (条件) {
  /* スタイル */
}

メディアクエリの条件

メディアクエリでは、以下のような条件を使用してスタイルを適用します:

  • min-width: 適用される画面の最小幅を指定します。

  • max-width: 適用される画面の最大幅を指定します。

  • orientation: 適用される画面の向きを指定します(landscape または portrait)。

  • min-height: 適用される画面の最小高さを指定します。あまり使いません。

  • max-height: 適用される画面の最大高さを指定します。あまり使いません。

以下に、メディアクエリを使用して異なる画面サイズに応じたスタイルを適用する例を示します。

  1. デスクトップ用スタイル
@media (min-width: 1024px) {
  .container {
    background-color: #d0d0d0;
  }
}
  1. タブレット用スタイル
@media (min-width: 768px) and (max-width: 1023px) {
  .container {
    background-color: #b0b0b0;
  }
}
  1. モバイル用スタイル css
@media (max-width: 767px) {
  .container {
    background-color: #909090;
  }
}

ベストプラクティス

  • モバイルファースト: 最初にモバイル用のスタイルを定義し、次にデスクトップ用のスタイルを追加する方法が推奨されます。これにより、モバイルデバイスでのパフォーマンスが向上します。

  • 共通スタイルの一元管理: 共通のスタイルは、メディアクエリの外で定義し、特定のデバイス用のスタイルのみをメディアクエリ内で定義します。

  • 適切なブレークポイントの設定: デバイスの種類や画面サイズに応じて適切なブレークポイントを設定します。一般的なブレークポイントは、320px(モバイル)、768px(タブレット)、1024px(デスクトップ)です。

CSS ファイルを分ける

以下のように、import ルールによりファイルを分割することもできます。

/* main.css */
@import url("styles/desktop.css") screen and (min-width: 1024px);
@import url("styles/tablet.css") screen and (min-width: 768px) and
  (max-width: 1023px);
@import url("styles/mobile.css") screen and (max-width: 767px);

しかし、現在のフロントエンド開発では何らかのフレームワークを用いることが一般的です。 フレームワークの利用においては、ヘッダーごと、カスタムボタンごとなど、コンポーネントやパーツごとに HTML ファイルや CSS ファイルに相当するファイルを作成していきます。 そのため、多くのパーツのファイルが必要になり、パーツごとに CSS ファイルを作成するため、 ファイル数も多くなる傾向があり、一つのファイルの中でパーツごとにメディアクエリを使うことが一般的です。

javascript との組み合わせ

モバイルの横幅では、javascript と組み合わせ、動的にメニューやサイドバーを表示することが多いです。 下記にその例を示します。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Responsive Grid Layout Example</title>
    <style>
      body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 0;
      }

      .container {
        display: grid;
        grid-template-areas:
          "header header header"
          "sidebar main main"
          "footer footer footer";
        grid-template-columns: 1fr 2fr;
        grid-template-rows: auto 1fr auto;
        height: 100vh;
      }

      header,
      footer {
        background-color: #333;
        color: white;
        padding: 10px;
        text-align: center;
      }

      /* header {
            grid-area: header;
            position: relative;
        } */

      header {
        grid-area: header;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        z-index: 3;
      }

      .menubar {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding-left: 10px;
        padding-right: 20px;
      }

      footer {
        grid-area: footer;
      }

      .sidebar {
        grid-area: sidebar;
        background-color: #f4f4f4;
        padding: 10px;
        margin-top: 60px;
        /* ヘッダーの高さ分の余白を追加 */
      }

      .main {
        grid-area: main;
        padding: 10px;
        margin-top: 60px;
        /* ヘッダーの高さ分の余白を追加 */
      }

      .toggle-button {
        display: none;
      }

      .overlay,
      .sidebar-mobile {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        height: 100%;
        z-index: 1;
      }

      .overlay {
        width: 100%;
        background-color: rgba(0, 0, 0, 0.5);
      }

      .sidebar-mobile {
        width: 250px;
        background-color: #f4f4f4;
        padding: 10px;
        z-index: 2;
      }

      /* モバイル用スタイル */
      @media (max-width: 767px) {
        .container {
          grid-template-areas:
            "header"
            "main"
            "footer";
          grid-template-columns: 1fr;
          grid-template-rows: auto 1fr auto;
        }

        .sidebar {
          display: none;
        }

        .toggle-button {
          display: block;
          background-color: #555;
          color: white;
          border: none;
          padding: 10px;
          cursor: pointer;
        }
      }
    </style>
  </head>

  <body>
    <div class="container">
      <header>
        <section class="menubar">
          <span>ヘッダー</span>
          <button class="toggle-button" onclick="toggleSidebar()">
            メニュー
          </button>
        </section>
      </header>
      <div class="sidebar" id="sidebar">サイドバー</div>
      <div class="main">
        メインコンテンツ<br />
        メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />メインコンテンツ<br />
      </div>
      <footer>フッター</footer>
    </div>
    <div class="overlay" id="overlay" onclick="toggleSidebar()"></div>
    <div class="sidebar-mobile" id="sidebar-mobile">サイドバー</div>

    <script>
      function toggleSidebar() {
        // サイドバーとオーバーレイの要素を取得
        var sidebarMobile = document.getElementById("sidebar-mobile");
        var overlay = document.getElementById("overlay");

        // サイドバーが非表示または初期状態(サイドバーが一度も表示されたことがない)場合
        if (
          sidebarMobile.style.display === "none" ||
          sidebarMobile.style.display === ""
        ) {
          // サイドバーとオーバーレイを表示
          sidebarMobile.style.display = "block";
          overlay.style.display = "block";
        } else {
          // サイドバーとオーバーレイを非表示
          sidebarMobile.style.display = "none";
          overlay.style.display = "none";
        }
      }

      // 画面サイズが変更されたときにサイドバーとオーバーレイを非表示にする
      window.addEventListener("resize", function () {
        if (window.innerWidth > 767) {
          document.getElementById("sidebar-mobile").style.display = "none";
          document.getElementById("overlay").style.display = "none";
        }
      });
    </script>
  </body>
</html>