CSSで半透明にすると内部のコンテンツ枠も透明になってしまう - CSS

CSSで半透明にすると内部のコンテンツ枠も透明になってしまう現象と対処法を紹介します。

概要

CSSでモーダルのダイアログを作成した際など内部のコンテンツのレイヤーも半透明になってしまう場合があります。 この記事では、コンテンツの枠が半透明になってしまう現象の確認と対処法を紹介します。

現象の確認

コード

以下のHTML, CSSファイルを作成します。
FadeDialogTransparent.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title></title>
  <link rel="stylesheet" href="FadeDialogTransparent.css" />

  <script type="text/javascript">
    function showDialog() {
      var target = document.getElementById("fadeLayer");
      target.style.visibility = "visible";
    }
  </script>

</head>
<body>
  <h1>ページ</h1>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です <a href="javascript:void(0);" onclick="showDialog();">ポップアップウィンドウのダイアログ表示</a></div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>

  <div id="fadeLayer">
    <div id="dialogFrame">ポップアップウィンドウのレイヤーです。</div>

  </div>
</body>
</html>
FadeDialogTransparent.css
.Frame {
  width:100%;
  height:4rem;
  border:1px solid #C0C0C0;
}

#fadeLayer {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;

  background-color: #000020;
  opacity: 0.5;
  visibility: hidden;
  z-index: 1;
}


#dialogFrame {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -160px; /*widthの半分にする*/
  margin-top: -100px; /*heightの半分にする*/

  padding-left: 8px;
  padding-right: 8px;
  padding-top: 8px;
  border: 5px solid #FF0000;
  width: 320px;
  height: 200px;
  background-color: #FFFFFF;
  z-index: 2;
}

解説

[ポップアップウィンドウのダイアログ表示]のリンクをクリックすると、 以下のJavaScriptを実行し、fadeLayerをページ全体に表示します。
fadeLayer内にコンテンツの枠の要素もあり、コンテンツも同時に表示される動作を期待しています。
    function showDialog() {
      var target = document.getElementById("fadeLayer");
      target.style.visibility = "visible";
    }

動作確認

上記のHTMLファイルをWebブラウザで表示します。下図のページが表示されます。


ページ内の[ポップアップウィンドウのダイアログ表示]のリンクをクリックします。 オーバーレイのレイヤーでページ全体がフェードし、ポップアップのエリアが表示されますが、 背景が半透明の状態で下のページの内容が透過して見えてしまっています。

原因

入れ子になった子要素には親要素の透明度(opacity)が適用されるため、コンテンツのエリアも半透明になってしまいます。

対処法

対策方法はコンテンツの要素は半透明の要素(オーバーレーレイヤー)の子要素にしない方法があります。 半透明レイヤーとコンテンツのレイヤーを同じレベルの要素として記述します。

コード

以下のHTML,CSSファイルを作成します。
FadeDialog.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title></title>
  <link rel="stylesheet" href="FadeDialog.css" />

  <script type="text/javascript">
    function showDialog() {
      elems = document.getElementsByTagName("body");
      for (var item of elems) {
        item.style.overflow = "hidden";
      }

      var target = document.getElementById("overlay");
      target.style.visibility = "visible";
    }

    function closeDialog() {
      elems = document.getElementsByTagName("body");
      for (var item of elems) {
        item.style.overflow = "";
      }

      var target = document.getElementById("overlay");
      target.style.visibility = "hidden";
    }
  </script>

</head>
<body>
  <h1>ページ</h1>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です <a href="javascript:void(0);" onclick="showDialog();">ポップアップウィンドウのダイアログ表示</a></div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>
  <div class="Frame">枠です</div>

  <div id="overlay">
    <div id="dialogFrame">ポップアップウィンドウのレイヤーです。</div>
    <div id="fadeLayer" onclick="closeDialog();">
  </div>
</body>
</html>
FadeDialog.css
.Frame {
  width:100%;
  height:5rem;
  border:1px solid #C0C0C0;
}

#overlay {
  position: fixed;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  visibility: hidden;
}


#fadeLayer {
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;

  background-color: #000020;
  opacity: 0.5;

  z-index: 1;
}


#dialogFrame {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -160px; /*widthの半分にする*/
  margin-top: -100px; /*heightの半分にする*/

  padding-left: 8px;
  padding-right: 8px;
  padding-top: 8px;
  border: 5px solid #00FF00;
  width: 320px;
  height: 200px;
  background-color: #FFFFFF;
  z-index: 2;
}

解説

overlay の枠には透明度を設定せず、overlay枠内部のfadeLayer枠で半透明のカラーopacity: 0.5;を設定します。 コンテンツはfadeLayerと同じ階層のdialogFrame枠で設定します。こちらの枠は不透明に設定します。
  <div id="overlay">
    <div id="dialogFrame">ポップアップウィンドウのレイヤーです。</div>
    <div id="fadeLayer" onclick="closeDialog();">
  </div>

JavaScriptで、overlay枠のvisibility を制御します。また、オーバーレイ表示時にはスクロールできない状態にするための overflow プロパティを設定しています。 overflowプロパティの動作の詳細についてはこちらの記事を参照してください。
  function showDialog() {
    elems = document.getElementsByTagName("body");
    for (var item of elems) {
      item.style.overflow = "hidden";
    }

    var target = document.getElementById("overlay");
    target.style.visibility = "visible";
  }

  function closeDialog() {
    elems = document.getElementsByTagName("body");
    for (var item of elems) {
      item.style.overflow = "";
    }

    var target = document.getElementById("overlay");
    target.style.visibility = "hidden";
  }

実行結果

上記のページをWebブラウザで表示します。下図のページが表示されます。


[ポップアップウィンドウのダイアログ表示]のリンクをクリックします。


オーバーレイのレイヤーが表示され、ページ全体が暗くなり、中央にポップアップウィンドウの枠が表示されます。 コンテンツの枠が半透明にならないことが確認できます。また、スクロールバーが非表示になり、スクロールできない状態になります。


オーバーレイのレイヤー部分をもう一度クリックすると、ポップアップの枠が非表示になり、スクロールできる状態になります。


半透明にすると内部のコンテンツ枠も透明になってしまう現象を改善できました。

著者
iPentecのメインデザイナー
Webページ、Webクリエイティブのデザインを担当。PhotoshopやIllustratorの作業もする。
掲載日: 2023-11-24
iPentec all rights reserverd.