Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What is going on with this article?
@naoki1218shirota

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

More than 1 year has passed since last update.

モーダルウィンドウを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を追加するだけです。
これで完成です。

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

2
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
naoki1218shirota
学生 勉強したことを忘れないために載せてます。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
2
Help us understand the problem. What is going on with this article?