1
2

More than 3 years have passed since last update.

JavaScriptでモーダルウィンドウ実装の仕方

Last updated at Posted at 2020-02-02

モーダルウィンドウをjQueryを使わず、JavaScriptのみで実装

覚えたものを備忘録を兼ねてまとめました。

今回実装するのは簡単に説明すると、『詳細をみる』ボタンをクリックすると、デフォルトでつけているhiddenクラスが外されてモーダルとマスクが出現し、『閉じる』ボタンまたは、周りのマスクをクリックすれば、hiddenクラスがついてモーダルが閉じる仕様となっています。

早速雛形のファイルを作っていきます。

ソース

HTML

index.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">
  <title>モーダル</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div id="open">
    詳細をみる
  </div>
  <div id="mask"></div>
  <section id="modal">
    <p>これは簡単なモーダルウィンドウです。</p>
    <div id="close">
      閉じる
    </div>
  </section>
  <script src="script.js"></script>
</body>

</html>


JavaScriptでhtml要素を取得するため、idをふっています。

openはモーダル表示、maskはモーダル周りの黒っぽい背景、modalはモーダル、closeは閉じるボタンです。

CSS

style.css
body {
    font-size: 16px;
  }

  #open,
  #close {
    cursor: pointer;
    width: 200px;
    border: 1px solid #ccc;
    border-radius: 4px;
    text-align: center;
    padding: 12px;
    margin: 16px auto 0;
    background: #4caf50;
    color: white;
  }

これで一度展開してみましょう。

image.png

このようになればひとまず大丈夫です。

次にmaskとmodalのcss作っていきます。

マスクとモーダルのCSS

style.css
#mask {
  background: rgba(0, 0, 0, 0.4);
  position: fixed;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  z-index: 1;
}

#modal {
  background: #fff;
  color: #555;
  width: 300px;
  padding: 40px;
  border-radius: 4px;
  position: absolute;
  top: 40px;
  left: 0;
  right: 0;
  margin: 0 auto;
  z-index: 2;
}

#modal p {
  margin: 0 0 20px;
}

maskはposition: fixed;とrgbaで画面全体を黒っぽくしています。
modalと#maskにz-indexを設定していますが、#maskは#modalより下に来ないと、#modalまで覆いかぶさって黒くなってしまうので、#modal>#maskに設定しています。

この時点で下の画面のようになるはずです。

image.png

マスクとモーダルは標準時には隠しておきたいので、cssを用いて見えない状態にしておきます。

display: none;とtransform: translateで隠しておく。

index.html
<div id="mask" class="hidden"></div>
  <section id="modal" class="hidden">
style.css
#mask.hidden {
  display: none;
}

#modal.hidden {
  transform: translate(0, -500px);
}

htmlで”#maskと#modalにhiddenクラスを命名し、cssで隠します。
maskはdisplay: none;で普通に非表示にしていますが、今回モーダルは上から表示させたいので、
modalはtransform: translate(0,500px);で、500px上に隠しておきます。

image.png

消えていたら、JavaScriptに入ります。

JavaScriptでマスクとモーダルを操作する

今回は、『openをクリックすると、#modalと#maskのhiddenクラスが取り除かれて表示する』という設計なので、openにクリックイベントをつけていきます。

script.js
'use strict';
{
  const open = document.getElementById('open');
  const close = document.getElementById('close');
  const modal = document.getElementById('modal');
  const mask = document.getElementById('mask');

  open.addEventListener('click', function () {
    modal.classList.remove('hidden');
    mask.classList.remove('hidden');
  });
}

これで、”詳細をみる”をクリックすることで、モーダルとマスクのhiddenクラスが外されて、表示されるのが確認できるはずです。
しかし、再び非表示にすることはできないので、今度はhiddenクラスを再クリックで付与できるようにします。
また、マスク部分を押しても非表示にできた方がユーザビリティ的にも自然なので、maskにもクリックイベントを適用します。

script.js
'use strict';
{
  const open = document.getElementById('open');
  const close = document.getElementById('close');
  const modal = document.getElementById('modal');
  const mask = document.getElementById('mask');

  open.addEventListener('click', function () {
    modal.classList.remove('hidden');
    mask.classList.remove('hidden');
  });
  close.addEventListener('click', function () {
    modal.classList.add('hidden');
    mask.classList.add('hidden');
  });
  mask.addEventListener('click', function () {
    modal.classList.add('hidden');
    mask.classList.add('hidden');
  });
}

最後にアニメーションを

モーダルを上からにゅっと表示させるため、transitionを追加してやります。すぐに出来ます。

style.css
#modal {
  background: #fff;
  color: #555;
  width: 300px;
  padding: 40px;
  border-radius: 4px;
  position: absolute;
  top: 40px;
  left: 0;
  right: 0;
  margin: 0 auto;
  z-index: 2;
  transition: 0.4s;
}

modalにtransitionを追加するだけです。
これで完成です。

ご閲覧ありがとうございます。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2