モーダル(Modal)を自作する方法

モーダル(Modal)を自作する方法

今回はモーダルダイアログを自作してみます。jQueryも使わない方法です。

自作する方法はいくらでもあるとは思いますが、今回は2パターン紹介します。今後、モーダルダイアログの自作方法が増えていくかもしれませんが、とりあえず、第1弾ということにしておきましょう。

モーダルダイアログ(シンプル)

サンプル

HTMLコード

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
   <title>Modal Box Sample(1)</title>
   <style type="text/css">
      /* モーダル(背景)*/
      .modal {
        position: fixed;
        z-index: 1; 
        left: 0;
        top: 0;
        width: 100%; 
        height: 100%; 
        overflow: auto; 
        background-color: rgb(0,0,0); 
        background-color: rgba(0,0,0,0.5); 
        transition: 0.6s;
        visibility: hidden;
        opacity: 0;
      }
      
      /* モーダルダイアログ */
      .modal-content {
        background-color: #fefefe;
        margin: 15% auto;
        padding: 20px;
        border: 1px solid #888;
        width: 50%; 
      }
      
      /* 閉じるボタン*/
      .close {
        color: #aaa;
        float: right;
        font-size: 28px;
        font-weight: bold;
      }
      /* 閉じるボタン(ホーバー/フォーカス時)*/
      .close:hover,
      .close:focus {
        color: black;
        text-decoration: none;
        cursor: pointer;
      }
   </style>
</head>
<body>
   <!-- モーダル表示ボタン -->
   <button id="myBtn">モーダルを開く</button>
   <!-- モーダル -->
   <div id="myModal" class="modal">
     <!-- モーダルダイアログ -->
     <div class="modal-content">
       <span class="close">&times;</span>
       <p><h3>タイトル</h3><p>
       <p>
          ここにモーダルダイアログの内容を表示します。
       </p>
     </div>
   </div>
   <script type="text/javascript">
      // モーダル取得
      var modal = document.getElementById("myModal");
      // モーダルを開くボタン取得
      var btn = document.getElementById("myBtn");
      // 閉じる×ボタン取得
      var span = document.getElementsByClassName("close")[0];
      // モーダルを開くボタンクリック時
      btn.onclick = function() {
        modal.style.visibility = "visible";
        modal.style.opacity = 1;
      }
      // ×ボタンクリック時
      span.onclick = function() {
        modal.style.visibility = "hidden";
        modal.style.opacity = 0;
      }
      // 背景のオーバーレイクリック時
      window.onclick = function(event) {
        if (event.target == modal) {
          modal.style.visibility = "hidden";
          modal.style.opacity = 0;
        }
      }
   </script>
</body>
</html>

デモ

補足

背景色や透明度を変えるには?

モーダルの背景色や透明度を変えるにはCSSクラス『modal』の定義を直してください。

.modal {
  position: fixed;
  z-index: 1; 
  left: 0;
  top: 0;
  width: 100%; 
  height: 100%; 
  overflow: auto; 
  background-color: rgb(0,0,0); 
  background-color: rgba(0,0,0,0.5); 
  transition: 0.6s;
  visibility: hidden;
  opacity: 0;
}

現状では、背景色が黒で透明度「0.5」に透けた背景になっています。

モーダル表示に効果(アニメーション)を加えるには?

サンプルではダイアログ表示に0.6秒かけて表示されるように、効果(アニメーション)が設定されていると思います。これはCSSとJavascriptによって実装されています。

まず、モーダルのCSSクラス『modal』で3点の定義を入れてあります。

  • transtion: 0.6s:0.6秒で表示
  • visibility: hidden: 『display:none』ではない
  • opacity:0 : 透明度0で完全透明
.modal {
  position: fixed; /* Stay in place */
  z-index: 1; 
  left: 0;
  top: 0;
  width: 100%; 
  height: 100%; 
  overflow: auto; 
  background-color: rgb(0,0,0); 
  background-color: rgba(0,0,0,0.5); 
  transition: 0.6s;
  visibility: hidden;
  opacity: 0;
}

次に、モーダル表示時に以下のJavascriptを使って、モーダルダイアログを表示させます。

      // モーダルを開くボタンクリック時
      btn.onclick = function() {
        modal.style.visibility = "visible";
        modal.style.opacity = 1;
      }

まず、visibilityに『visible』を設定し、モーダルを表示させます。

かつ、完全透明であったモーダルレイヤーに1を設定し、透明度を完全になくします。

この結果、CSSのプロパティ「transition」に設定した時間をかけて、モーダルが表示されます。

なお、モーダルを閉じるときには逆の処理を行います。

      // モーダルを開くボタンクリック時
      btn.onclick = function() {
        modal.style.visibility = "visible";
        modal.style.opacity = 1;
      }

モーダルダイアログ(効果あり:上部より出現)

サンプル

HTMLコード

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
   <title>Modal Box Sample</title>
   <style type="text/css">
      /* モーダル(背景)*/
      .modal {
        display: none; 
        position: fixed; 
        z-index: 1;
        padding-top: 100px; /* モーダルダイアログの画面上部位置 */
        left: 0;
        top: 0;
        width: 100%; /* 幅 */
        height: 100%; /* 高さ */
        overflow: auto; /* スクリールを自動 */
        background-color: rgb(0,0,0); 
        background-color: rgba(0,0,0,0.4); 
      }
      /* モーダルダイアログ */
      .modal-content {
        position: relative;
        background-color: #fefefe;
        margin: auto;
        padding: 0;
        border: 1px solid #888;
        width: 80%;
        box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
        -webkit-animation-name: animatetop;
        -webkit-animation-duration: 0.4s;
        animation-name: animatetop;
        animation-duration: 0.4s
      }
      /* アニメーション追加 */
      @-webkit-keyframes animatetop {
        from {top:-300px; opacity:0} 
        to {top:0; opacity:1}
      }
      @keyframes animatetop {
        from {top:-300px; opacity:0}
        to {top:0; opacity:1}
      }
      /* 閉じるボタン */
      .close {
        color: white;
        float: right;
        font-size: 28px;
        font-weight: bold;
      }
      .close:hover,
      .close:focus {
        color: #000;
        text-decoration: none;
        cursor: pointer;
      }
      /* モーダルヘッダー */
      .modal-header {
        padding: 2px 16px;
        background-color: #d9d9d9;
      }
      /* モーダルボディー */
      .modal-body {padding: 2px 16px;}
      /* モーダルフッター */
      .modal-footer {
        padding: 2px 16px;
        background-color: #d9d9d9;
      }
   </style>
</head>
<body>
   <!-- モーダル表示ボタン -->
   <button id="myBtn">モーダルを開く</button>
   <!-- モーダル -->
   <div id="myModal" class="modal">
      <!-- モーダルダイアログ -->
      <div class="modal-content">
        <div class="modal-header">
          <span class="close">&times;</span>
          <h2>ヘッダー</h2>
        </div>
        <div class="modal-body">
          <p>
             ここにモーダルダイアログの内容を表示します。
          </p>
        </div>
        <div class="modal-footer">
          <h3>フッター</h3>
        </div>
      </div>
   </div>
   <script type="text/javascript">
      // モーダル取得
      var modal = document.getElementById("myModal");
      // モーダルを開くボタン取得
      var btn = document.getElementById("myBtn");
      // 閉じる×ボタン取得
      var span = document.getElementsByClassName("close")[0];
      // モーダルを開くボタンクリック時
      btn.onclick = function() {
        modal.style.display = "block";
      }
      // ×ボタンクリック時
      span.onclick = function() {
        modal.style.display = "none";
      }
      // 背景のオーバーレイクリック時
      window.onclick = function(event) {
        if (event.target == modal) {
          modal.style.display = "none";
        }
      }
   </script>
</body>
</html>

デモ

補足

ダイアログを上部から表示させるには?

CSSの「@keyframes」を使い、アニメーションを定義します。

      /* アニメーション追加 */
      @-webkit-keyframes animatetop {
        from {top:-300px; opacity:0} 
        to {top:0; opacity:1}
      }
      @keyframes animatetop {
        from {top:-300px; opacity:0}
        to {top:0; opacity:1}
      }

Fromは効果開始時のCSS定義、toは効果終了時のCSS定義になります。

サンプルではFromの「top」がマイナスなので、画面上部の見えない位置からスタートし、最後には0を指定し、画面上部に位置させます。

次に、定義したアニメーション定義をCSSに設定します。

      /* モーダルダイアログ */
      .modal-content {
        position: relative;
        background-color: #fefefe;
        margin: auto;
        padding: 0;
        border: 1px solid #888;
        width: 80%;
        box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
        -webkit-animation-name: animatetop;
        -webkit-animation-duration: 0.4s;
        animation-name: animatetop;
        animation-duration: 0.4s
      }

CSSのプロパティ「animation-name」で定義した効果名を指定し、かつ、「animation-duration」に効果の適用時間を定義してください。

モーダルダイアログ(効果あり:下部より出現)

サンプル

HTMLコード

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
   <title>Modal Box Sample</title>
   <style type="text/css">
      /* モーダル(背景)*/
      .modal {
        display: none; 
        position: fixed; 
        z-index: 1;
        left: 0;
        top: 0;
        width: 100%; /* 幅 */
        height: 100%; /* 高さ */
        overflow: auto; /* スクリールを自動 */
        background-color: rgb(0,0,0); 
        background-color: rgba(0,0,0,0.4); 
        -webkit-animation-name: fadeIn; 
        -webkit-animation-duration: 0.4s;
        animation-name: fadeIn;
        animation-duration: 0.4s
      }
      /* モーダルダイアログ */
      .modal-content {
        position: fixed;
        background-color: #fefefe;
        bottom:0;
        padding: 0;
        border: 1px solid #888;
        margin-left:10%;
        margin-right:10%;
        margin-bottom: 20px; /* モーダルダイアログの画面上部位置 */
        width: 80%;
        -webkit-animation-name: slideIn;
        -webkit-animation-duration: 0.4s;
        animation-name: slideIn;
        animation-duration: 0.4s
      }
      /* アニメーション追加 */
      @-webkit-keyframes slideIn {
        from {bottom: -300px; opacity: 0} 
        to {bottom: 0; opacity: 1}
      }
      @keyframes slideIn {
        from {bottom: -300px; opacity: 0}
        to {bottom: 0; opacity: 1}
      }
      @-webkit-keyframes fadeIn {
        from {opacity: 0} 
        to {opacity: 1}
      }
      @keyframes fadeIn {
        from {opacity: 0} 
        to {opacity: 1}
      }
      /* 閉じるボタン */
      .close {
        color: white;
        float: right;
        font-size: 28px;
        font-weight: bold;
      }
      .close:hover,
      .close:focus {
        color: #000;
        text-decoration: none;
        cursor: pointer;
      }
      /* モーダルヘッダー */
      .modal-header {
        padding: 2px 16px;
        background-color: #d9d9d9;
      }
      /* モーダルボディー */
      .modal-body {padding: 2px 16px;}
      /* モーダルフッター */
      .modal-footer {
        padding: 2px 16px;
        background-color: #d9d9d9;
      }
   </style>
</head>
<body>
   <!-- モーダル表示ボタン -->
   <button id="myBtn">モーダルを開く</button>
   <!-- モーダル -->
   <div id="myModal" class="modal">
      <!-- モーダルダイアログ -->
      <div class="modal-content">
        <div class="modal-header">
          <span class="close">&times;</span>
          <h2>ヘッダー</h2>
        </div>
        <div class="modal-body">
          <p>
             ここにモーダルダイアログの内容を表示します。
          </p>
        </div>
        <div class="modal-footer">
          <h3>フッター</h3>
        </div>
      </div>
   </div>
   <script type="text/javascript">
      // モーダル取得
      var modal = document.getElementById("myModal");
      // モーダルを開くボタン取得
      var btn = document.getElementById("myBtn");
      // 閉じる×ボタン取得
      var span = document.getElementsByClassName("close")[0];
      // モーダルを開くボタンクリック時
      btn.onclick = function() {
        modal.style.display = "block";
      }
      // ×ボタンクリック時
      span.onclick = function() {
        modal.style.display = "none";
      }
      // 背景のオーバーレイクリック時
      window.onclick = function(event) {
        if (event.target == modal) {
          modal.style.display = "none";
        }
      }
   </script>

</body>
</html>

デモ

補足

ダイアログを下部から表示させるには?

CSSの「@keyframes」を使い、アニメーションを定義します。

      /* アニメーション追加 */
      @-webkit-keyframes slideIn {
        from {bottom: -300px; opacity: 0} 
        to {bottom: 0; opacity: 1}
      }
      @keyframes slideIn {
        from {bottom: -300px; opacity: 0}
        to {bottom: 0; opacity: 1}
      }
      @-webkit-keyframes fadeIn {
        from {opacity: 0} 
        to {opacity: 1}
      }
      @keyframes fadeIn {
        from {opacity: 0} 
        to {opacity: 1}
      }

Fromは効果開始時のCSS定義、toは効果終了時のCSS定義になります。

サンプルではFromの「top」がマイナスなので、画面下部の見えない位置からスタートし、最後には0を指定し、画面下部に位置させます。

次に、定義したアニメーション定義をCSSに設定します。

      /* モーダル(背景)*/
      .modal {
        display: none; 
        position: fixed; 
        z-index: 1;
        left: 0;
        top: 0;
        width: 100%; /* 幅 */
        height: 100%; /* 高さ */
        overflow: auto; /* スクリールを自動 */
        background-color: rgb(0,0,0); 
        background-color: rgba(0,0,0,0.4); 
        -webkit-animation-name: fadeIn; 
        -webkit-animation-duration: 0.4s;
        animation-name: fadeIn;
        animation-duration: 0.4s
      }
      /* モーダルダイアログ */
      .modal-content {
        position: fixed;
        background-color: #fefefe;
        bottom:0;
        padding: 0;
        border: 1px solid #888;
        margin-left:10%;
        margin-right:10%;
        margin-bottom: 20px; /* モーダルダイアログの画面上部位置 */
        width: 80%;
        -webkit-animation-name: slideIn;
        -webkit-animation-duration: 0.4s;
        animation-name: slideIn;
        animation-duration: 0.4s
      }

ご参考

関連ページ