19930


背景要素に`filter: brightness`を使い，明度を暗くした後，その前面に白い文字を表示したいと思っています．

[code]

    #background {
      z-index: -1000;
      
      height: 300px;
      width:  100%;
      
      background-color: #555;
    
      filter: brightness(20%);
      -webkit-filter: brightness(20%);
      -moz-filter: brightness(20%);
      -o-filter: brightness(20%);
    }
    
    #content {
      z-index: 1000;
      
      height: 300px;
      width: 100%;
      
      margin-top: -300px;
      color: #FFF;
      
      text-align: center;
    }
[/code]

[code]

    <div id="background">
    </div>
    <div id="content">
      <h1>
      テスト
      </h1>
    </div>
[/code]

firefoxでは正常に表示できるのですが，Safari，Chrome等Webkit系では文字が表示されていないようです．  
また，`-webkit-filter: brightness`を削除することで文字は表示されるようになるのですが，今度はfilterが効きません．

本番環境では，背景として画像を使用したいと思っているため，できれば`filter: brightness`を使って明度を下げたいと考えています．

何か良い解決策はないでしょうか？


CC BY-SA 4.0
2015-12-13T03:09:18.793
19926
2019-12-13T17:49:17.250
2019-12-13T17:49:17.250
32986
7227
question
html css
背景にCSSのfilterを使用すると，前面の文字が表示されない


`z-index` を指定する際には `position` に static 以外を指定する必要がありますが、あなたのコードでは `#background`
`#content` のどちらにもこれが指定されていません。

これがなくても動くのは Firefox のバグのような気がします。

* * *

以下解説。

画像編集ソフトでいうところのレイヤーのように、Webページのレンダリングには **スタックコンテキスト** という概念があり、これは `opacity`
`transform` などを指定した際や、 `position` と `z-index` を組み合わせた場合に作成されます。

  * [要素の重なりについて本気出して考えてみた（z-indexとか何とかとか） – No.1026](http://no1026.com/archives/104)
  * [スタック文脈 - Web developer guide | MDN](https://developer.mozilla.org/ja/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context)

描画順をざっくり書くと、次のようになります。（今回関係するもののみ）

  * `z-index` がマイナスのスタックコンテキスト
  * スタックコンテキストを作らない要素
  * `z-index` が `auto` や 0 のスタックコンテキスト  
（`position` \+ `z-index` 以外で作られたスタックコンテキストもここ）

  * `z-index` が 1 以上のスタックコンテキスト

例:

[code]

    body { background: #fdd; }
    
    .z-1 { z-index: -1; background: #efe; }
    .za { z-index: auto; background: #ada; }
    .z0 { z-index: 0; background: #5b5; }
    .z1 { z-index: 1; background: #090; }
    
    .c div { height: 40px; }
    .c :nth-child(2) { margin-top: -30px; margin-left: 100px; }
    .c :nth-child(3) { margin-top: -30px; margin-left: 200px; }
    .c :nth-child(4) { margin-top: -30px; margin-left: 300px; }
    
    .with-pos div { position: relative; }
[/code]

[code]

    <h2>position: static （デフォルト値）</h2>
    
    <div class="c">
      <div class="z-1">z-index: -1</div>
      <div class="za">z-index: auto</div>
      <div class="z0">z-index: 0</div>
      <div class="z1">z-index: 1</div>
    </div>
    <div class="c">
      <div class="z1">z-index: 1</div>
      <div class="z0">z-index: 0</div>
      <div class="za">z-index: auto</div>
      <div class="z-1">z-index: -1</div>
    </div>
    
    <h2>position: relative</h2>
    
    <div class="c with-pos">
      <div class="z-1">z-index: -1</div>
      <div class="za">z-index: auto</div>
      <div class="z0">z-index: 0</div>
      <div class="z1">z-index: 1</div>
    </div>
    <div class="c with-pos">
      <div class="z1">z-index: 1</div>
      <div class="z0">z-index: 0</div>
      <div class="za">z-index: auto</div>
      <div class="z-1">z-index: -1</div>
    </div>
[/code]

それを踏まえて、今回のケースを考えてみます。

まず、 [`filter` を指定した段階](http://jsfiddle.net/fq7o70uf/1/)ではネガティブマージンで引き込んだ
`#content` が見えなくなっています。これは `#background`
にスタックコンテキストが生成されたことにより、スタックコンテキストを持たない `#content` より上に描画されるためです。

> A computed value of other than none results in the creation of a stacking
> context the same way that CSS opacity does.  
>  \--- <https://drafts.fxtf.org/filters/#FilterProperty> より引用

そして順番を指定しようと `z-index` を指定されたようですが、static 以外の `position`
が指定されていない、つまり位置指定されていないので、本来効果はありません。これは `filter` がスタックコンテキストを生成していても同じです。

> **位置指定されたボックスでは** 、z-index プロパティは次の定義を行います:
>
>   1. 現在のスタック文脈における、ボックスのスタックレベル
>   2. ボックスがローカルなスタック文脈を作るかどうか
>

>
> \--- <https://developer.mozilla.org/ja/docs/Web/CSS/z-index>
> より引用。強調は私によるものです。

例えば、先ほど引用した個所でも例示されていた `opacity` の場合、Firefox でも Chrome でも `z-index` は無視されています。

[code]

    #background {
      /* position: relative; */
      /* ↑を足すとz-index通り下に潜る */
      
      z-index: -1000;
      
      height: 300px;
      width:  100%;
      
      background-color: #555;
    
      opacity: 0.99;
    }
    
    #content {  
      height: 300px;
      width: 100%;
      margin-top: -300px;
      
      color: #FFF;
      text-align: center;
    }
[/code]

[code]

    <div id="background">
    </div>
    <div id="content">
      <h1>
      テスト
      </h1>
    </div>
[/code]

にもかかわらず、Firefox では `filter` を指定しただけで `z-index` が機能していますね。

また、前述の描画順を考えると、

  * `#background` の z-index をマイナスにする
  * `#content` の z-index を 1 以上にする

のどちらかで十分とも言えます。（もちろん `position` は必要です）


CC BY-SA 4.0
2015-12-13T06:33:02.613
19930
2019-12-13T17:48:58.877
2019-12-13T17:48:58.877
32986
8000
19926
answer