【Javascript】Javascript/Cssでモーダルを作ってみた

# 初めに
ボタンを押したら周りの背景が薄暗くなり、画面の真ん中に出てくるウィンドウが気になり、javascriptとcssを使って実装してみました。また、自分なりに学習し学んだ内容を記事にしてみました。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

# モーダルとは
英語でmodal。「様式の」「形態の」の意味で、ボタンを押したらブラウザ上に現れるウィンドウのこと。閉じるボタンを押すまで他の操作ができなくなる画面のこと。

# 実装における主な概念
❶HTMLのタグとCSSのz-indexを利用し3つの層を作る
❷overlayという名前のタグを作り、ベースとなる画面を被せる薄暗いレイヤーを用意する
❸ボタンを押した時に画面の一番手前に出てくるmodalという名前のタグを作る。
❹hiddenというクラス名をmodalタグやoverlayタグにあらかじめ付けておく
❺cssでhiddenの属性を「display: none」にセットする
❻Javascriptでボタンを押した際に「hidden」タグを付けたり外したりする処理をする

# ３つのレイヤの構成
イメージとしてはベースがあってその上にoverlay、modalが重なる感じ。overlayとmodalはボタンを押したときに現れ、閉じるボタンを押すと隠れる。
![スクリーンショット 2021-04-26 8.16.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/180d8b36-8765-90cb-8041-4688e533ff55.png)


# HTML側の実装
modalとoverlayというクラス名を持つ２つのタグを用意します。また、２つのタグにはhiddenというクラス名を別途付けておきます。

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

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <link rel="stylesheet" href="style.css" />
  <title>モーダルウィンドウ</title>
</head>

<body>
  <div class="overlay hidden"></div> <!-- overlay -->

  <button class="show-modal">モーダルボタン</button> <!-- モーダルを表示されるボタン -->

  <div class="modal hidden">
    <!-- モーダル-->
    <button class="close-modal">&times;</button> <!-- モーダルを閉じるボタン -->
    <p>
      モダールウィンドウです。
    </p>
  </div>

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

</html>
```

# CSSの実装

```css
* {                     /* ブラウザ全体の余白を消す */
  margin: 0;
  padding: 0;
}

body {
  font-family: sans-serif;
  height: 100vh;
  position: relative;      /* body要素にflexboxを指定する */
  display: flex;
  align-items: flex-start;
  justify-content: center;
  background: linear-gradient(to top left, #f76060, #ebd407);    /* body要素の背景をグラデーションにする */
}

.show-modal {
  font-size: 20px;      /* modalを開くボタン */
  font-weight: 600;
  padding: 10px 30px;
  border: none;
  margin-top: 100px;
  background-color: #fff;
  color: #444;
  border-radius: 20px;
  cursor: pointer;
}

.close-modal {
  position: absolute;              /* modalを閉じるボタン */
  top: 4px;
  right: 22px;
  font-size: 40px;
  color: #333;
  cursor: pointer;
  border: none;
  background: none;
}

p {
  font-size: 20px;
}

.hidden {
  display: none;            /* hiddenクラスが付与されている場合は表示させないようにする */
}

.modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 70%;
  color: rgb(255, 0, 0);
  background-color: white;
  padding: 6rem;
  border-radius: 5px;
  box-shadow: 0 10px 10px rgba(0, 0, 0, 0.3);   /* modalに影を作る */
  z-index: 10;           /* z-indexでmodalを一番上に位置させる */
}

.overlay {
  position: absolute; /* overlayの絶対位置を左上を起点にし幅と高さを100%にする */
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.6);    
  backdrop-filter: blur(3px); /* 一番下のbody領域をぼやかす */
  z-index: 5; /* z-indexの数字を0と10の間の数字にし、bodyとmodalの真ん中に位置させる */
}
```
bodyとmodal、overlayのz-indexをそれぞれ0,5,10にします。こうすることによってbody要素が一番下、その上にmodalウィンドウがあり、一番上がoverlayという層になります。また、hiddenクラスのdisplayをnoneにしておき、このクラスが付与された時に要素が見えないようにします。

# Javascriptの実装

```javascript
"use strict";

const modal = document.querySelector(".modal"); //modalを指定
const overlay = document.querySelector(".overlay"); //overlayを指定
const btnOpenModal = document.querySelector(".show-modal"); //modalを開くボタンを指定
const btnCloseModal = document.querySelector(".close-modal"); //modalを閉じるボタンを指定

//modalとoverlayのhiddenクラスを消す（modalとoverlayが見えるようにする）処理
const openModal = () => {
  modal.classList.remove("hidden");
  overlay.classList.remove("hidden");
};

//modalとoverlayのhiddenクラスを追加する（modalとoverlayが見えないようにする）処理
const closeModal = () => {
  modal.classList.add("hidden");
  overlay.classList.add("hidden");
};

//modalの開くボタンと閉じるボタンをクリックした時の処理
btnOpenModal.addEventListener("click", openModal);
btnCloseModal.addEventListener("click", closeModal);

```
modal,overlay,モーダルの開くボタン、閉じるボタンをquerySelectorで指定し、それぞれの要素にhiddenクラスを付けたり、外したりしています。また、addEventListenerでclickした場合にボタンの処理を行うようにしています。

# 結果物
①モーダルを開く前
![スクリーンショット 2021-04-26 22.29.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/7035a515-e396-a8b1-9fa9-afbbde2c8503.png)
②開いた場合
![スクリーンショット 2021-04-26 22.29.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/c8a80843-8fe7-9d43-801d-4391efc2fcd6.png)



# 参考サイト
https://goworkship.com/magazine/modal-windows-mobileui/
https://developer.mozilla.org/ja/docs/Web/CSS/backdrop-filter