フロントエンド開発３

この記事は、「[架空プロジェクトを通してシステム開発とドキュメント作成を体験してみる（2022 Late）](https://qiita.com/minimumskills/items/aedf6a93658db3f74747)」の記事の一部です。

# 概要
今回はレスポンシブ対応を追加します。レスポンシブとは画面の幅に応じて適用するCSSを変更する方法で、一般にはPCサイトのスマホ対応（あるいはその逆）に利用されます。
>レスポンシブ対応されていないサイトだと、スマホやタブレットでサイトにアクセスした際にデザインが崩れたり、コンテンツが見切れてしまったりします。

今回は、640pxをブレークポイントとしてPC版とモバイル版を切り替えPCファーストでマークアップする方法で実装します。レスポンシブ対応の方法の理解を目的とするため、対応内容を単純にしています。対応内容は以下のみです。

- 640px以下はナビゲーションバーを縦に列挙
- 640px以下はナビゲーションバー・フッターの色を変更
- 640px以下は問合せフォームのスタイルを見やすく微調整


# 完成イメージ

スマホ向け通常画面（TOPページ）。

<img width="300" alt="000001.jpg" src="https://drive.google.com/uc?export=view&id=1lC3kd7hkLHKWYrABVVLa8dqWspEw34Vt">

スマホ向けお問合せページ（CONTACTページ）。

<img width="300" alt="000010.jpg" src="https://drive.google.com/uc?export=view&id=1EN2JQGOPPyUV3mw_ymn-I6BoRiHmMxOP">

エラー表示時。

<img width="300" alt="000020.jpg" src="https://drive.google.com/uc?export=view&id=1oFZV9koNmHcGq9fp8_nq64rJG-AP2Xq6">


# style.css

640px以下になった際、ヘッダー・フッターの色を変更し、contact.htmlのformの幅を60%から90%にします。
またボタンサイズを少し大きくし、幅を親要素に対して100%にしてみます。

`@media`でcssを適用したい条件を指定します。`@media`で記述された部分はその条件のみで適用されるようになります。今回の場合はメディアタイプ:screen（基本これ）とメディアクエリ（条件）:幅が640x以下を条件としています。

>@mediaでCSSを切り替える方法をメディアクエリといいます。CSS3からの機能です。

style.cssの最後にスマホ対応の記述を追加していきます。

```style.css
/*スマホ対応*/
@media screen and (max-width: 640px) {
    /*ここにスクリーンの幅が640px以下になった場合の設定を記述していく*/
}
```

## ナビゲーションバー
ナビゲーションバーの色を変更し、横並びだったメニューを縦並びにします。

```diff_css:style.css
    @media screen and (max-width: 640px) {
+       .nav {
+          background-color: #0183a0;
+       }
+
+       .nav ul {
+           flex-direction: column;
+       }
    }
```

```css:コピペ用
.nav {
    background-color: #0183a0;
}

.nav ul {
    flex-direction: column;
}
```

保存して検証画面を出します。
左下「Toggle Device Toolbar」ボタンを押して、上部からデバイスを選択して、レスポンシブのスタイルが効いた状態を確認します。
ナビゲーションバーの色が変わってメニューが縦並びになりました。
![000030.jpg](https://drive.google.com/uc?export=view&id=1DvEL432BfpNiwnS4gDbmScp54B-Ln3MD)

ナビゲーションバーの色は変わりましたが高さが足りないので、高さを変更します。
また、各メニューの下に白い線を追加して見やすくします。

```diff_css:style.css
    .nav {
        background-color: #0183a0;
+       height: 150px;
    }

    .nav ul {
        flex-direction: column;
    }

+   .nav li {
+       border-bottom: solid 1px #fff;
+   }
```

```css: コピペ用
    .nav li {
        border-bottom: solid 1px #fff;
    }
```
保存して確認します。左側に余白ができています。
これは、user agent stylesheetが適用されてしまっているようです。

![000040.jpg](https://drive.google.com/uc?export=view&id=1TW6l2Pn44ZNPOgp15tkPvdo-NYoktkS-)

ulに適用されてしまっている左側の余白をなくすため下記を追加します。

```diff_css:style.css
    .nav ul {
        flex-direction: column;
+       padding: 0;
    }
```
保存して確認してみます。このようになりました。

![000050.jpg](https://drive.google.com/uc?export=view&id=19YZjtCnXtXEUsMrNT891V1LhWHx13CWL)



## フッター
フッターは色を変更するのみにしておきます。
ナビゲーションバーと同様に`@media screen and (max-width: 640px) { }`の中に記述します。

```css:style.css
.footer {
    background-color: #0183a0;
}
```
保存して確認します。フッターの色が変更されました。

![000060.jpg](https://drive.google.com/uc?export=view&id=1io84oSk4y-h5nmVlsFDlB5QA_1jwrEni)


## お問合せフォーム

お問合せフォームは今のままだと、入力欄が小さくなってしまうので、ラベルと入力欄を縦並びにして、ボタンのサイズも大きく変更します。
ラベルと入力欄の幅をそれぞれ100%にして縦並びにします。ボタンの幅も100%にして高さを50pxにします。

```style.css
/* お問合せフォーム */
.form_group label {
    width: 100%;
    padding-bottom: 10px;
}

.form_group input,
.form_group textarea {
    width: 100%;
    margin: 0;
    padding: 0;
}

.submit_btn {
    width: 100%;
    height: 50px;
}
```

保存して確認します。

![000070.jpg](https://drive.google.com/uc?export=view&id=1Dbagf9q5fO73cz5_UAnjpsw0ww0gREYe)

見やすくなりました。エラーメッセージを出してみます。

![000080.jpg](https://drive.google.com/uc?export=view&id=1gzCq95AhcDuZiw9ja9Q9k0sSpLFO4_1_)

表示位置が少しおかしいので、表示位置を調整します。

```css:style.css
.form_error {
    width: 100%;
    text-align: left;
    padding: 5px 0;
}
```
保存して確認します。

![000090.jpg](https://drive.google.com/uc?export=view&id=1wkjEFsmwYqKEliDfmR5dhByePS6pZGyO)

これでレスポンシブ対応ができました。

# 最終的なコード

```style.css
html {
    height: 100%;
}

body {
    margin: 0;
    padding: 0;
    font-family: sans-serif;
    height: 100%;
}

.nav {
    /* 背景色設定 */
    background-color: #666;
}

.nav ul {
    /* 表示幅を90%に */
    width: 90%;
    /* フレックスボックス化 */
    display: flex;
    /* 先頭のポチをなくす */
    list-style: none;
    /* 余白の自動調整 （上下の余白は0、左右は自動調整）*/
    margin: 0 auto;
    /* 高さを50pxに指定 */
    height: 50px;
}

.nav a {
    /* アンダーライン削除 */
    text-decoration: none;
    /* 文字色設定 */
    color: #fff;
    /* 内側余白を上右下左の順で設定 */
    padding: 10px 20px 10px 0px;
    /*ブロックにする */
    display: block;
    /* 文字を大き目に設定 */
    font-size: large;
}

.nav a:hover {
    /* マウスオーバーした時の文字色を設定 */
    color: #aaa;
}

/* トップ */
.top {
    /* 背景にpicsum.photosから取得した画像を設定 */
    background-image: url("https://picsum.photos/1000/300");
    /* 画像をいっぱいに表示 */
    background-size: cover;
    /* 表示する高さを画面の40％に */
    height: 40vh;
    /* 表示幅を画面の90%に */
    width: 100%;
    /* フレックスボックスを指定*/
    display: flex;
    /* フレックスアイテムを使って両端から中央に配置*/
    justify-content: center;
    /* フレックスアイテムを使って上下から中央に配置 */
    align-items: center;
    /* テキストの配置を中央揃えに */
    text-align: center;
}

.top_msg {
    /* 文字色を白に */
    color: #fff;
}

.content {
    width: 90%;
    margin: 0 auto;
    text-align: center;
}

.footer {
    background-color: #666;
    height: 60px;
    color: #fff;
    display: flex;
    justify-content: center;
    align-items: center;
    position: sticky;
    top: 100vh;
}

/* Contact */
.contact_form {
    padding: 40px 20px;
    text-align: center;
}

.form_group {
    border-top: 1px solid #ddd;
    margin-top: 20px;
    padding: 20px 0px;
    width: 100%;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
}

.form_group label {
    width: 30%;
    font-weight: bold;
    font-size: 18px;
}

.form_group input,
.form_group textarea {
    border: 1px solid #ddd;
    border-radius: 6px;
    width: 60%;
    font-size: 18px;
}

.form_group input {
    height: 40px;
}

.submit_btn {
    padding: 5px 15px;
    background-color: #049dbf;
    color: #fff;
    border-radius: 5px;
    border: 0;
    font-size: 16px;
}

.submit_btn:hover {
    background-color: #0183a0;
}

.form_error {
    padding-left: 30%;
    width: 60%;
    font-size: small;
    color: red;
    text-align: start;
    padding-top: 10px;
}

.hidden {
    display: none;
}

/*スマホ対応*/
@media screen and (max-width: 640px) {
    .nav {
        background-color: #0183a0;
        height: 150px;
    }

    .nav ul {
        flex-direction: column;
        padding: 0;
    }

    .nav li {
        border-bottom: solid 1px #fff;
    }

    .footer {
        background-color: #0183a0;
    }

    /* お問合せフォーム */
    .form_group label {
        width: 100%;
        padding-bottom: 10px;
    }

    .form_group input,
    .form_group textarea {
        width: 100%;
        margin: 0;
        padding: 0;
    }

    .submit_btn {
        width: 100%;
        height: 50px;
    }

    .form_error {
        width: 100%;
        text-align: left;
        padding: 5px 0;
    }
}
```

```index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSite</title>
    <link rel="stylesheet" href="./style.css" />
</head>

<body>
    <nav class="nav">
        <ul>
            <li><a href="./index.html">WebSite</a></li>
            <li><a href="./index.html">TOP</a></li>
            <li><a href="./contact.html">CONTACT</a></li>
        </ul>
    </nav>
    <header class="top">
        <h1 class="top_msg">bluecode, Lifestyle developer.</h1>
    </header>
    <main>
        <section class="content">
            <h2>websiteの最新情報</h2>
            <p>最新の情報をご案内します。</p>
        </section>
    </main>
    <footer class="footer">
        &copy; 2022 bluecode, inc. All Rights Reserved.
    </footer>
</body>

</html>
```

```contact.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSite|お問合せ</title>
    <link rel="stylesheet" href="./style.css" />
</head>

<body>
    <nav class="nav">
        <ul>
            <li><a href="./index.html">WebSite</a></li>
            <li><a href="./index.html">TOP</a></li>
            <li><a href="./contact.html">CONTACT</a></li>
        </ul>
    </nav>
    <main class="contact_form">
        <h2>お問合せ</h2>
        <form>
            <div class="form_group">
                <label>お名前</label>
                <input type="text" id="name" />
                <span class="form_error hidden" id="name_error">お名前は必須です。</span>
            </div>
            <div class="form_group">
                <label>email</label>
                <input type="email" id="email" />
                <span class="form_error hidden" id="email_error">emailは必須かつemailの形式で入力してください。</span>
            </div>
            <div class="form_group">
                <label>お問合せ内容</label>
                <textarea id="body" rows=4></textarea>
                <span class="form_error hidden" id="body_error">お問合せ内容は必須かつ1文字以上10文字以下で入力してください。</span>
            </div>
            <button class="submit_btn" id="submit_btn">送信</button>
        </form>
    </main>


    <footer class="footer">
        &copy; 2022 bluecode, inc. All Rights Reserved.
    </footer>

    <script src="./index.js"></script>
</body>

</html>
```

# まとめ

* スマホ対応はレスポンシブデザイン（レイアウト）という手法で対応することが一般的
  * CSSのメディアクエリという機能で実現する
  * スマホ用のデザイン、CSSを考える必要があるのでその分工数は増えます
  * ここではPC版をベースにしましたが、スマホ版をベースにPC対応する場合も
* Web制作のほとんどの時間はCSS > JavaScript > HTMLという感じ。

# ドキュメント作成視点での考察

* スマホ対応や対応条件をどこにどう記述すべき？
* そもそもPC対応やその条件をどこにどう記述すべき？
* スマホ版のデザインや動作をどこでどう記述すべき？

# 関連コンテンツ

* 次：[バックエンド開発１](https://qiita.com/minimumskills/items/66514e324bcf6f4729eb)
* 前：[フロントエンド開発２](https://qiita.com/minimumskills/items/d64deacdefa077a3616a)