用途
- divとかのボックスに半透明の背景画像を付けたい。
- ただし中の要素まで半透明にされると困る。
- レスポンシブ対応で、ボックスの縦横比が変わっても背景画像はボックス全体をカバーするように。
課題
背景画像を設定し、普通にopacityをかけると中の要素まで半透明になって困る。
解決法
考え方
背景画像を設定したボックスにopacityを付けると、子要素まで半透明になるのなら、子要素の入らないbefore疑似要素に背景画像を設定すればいい。
before疑似要素をposition: absolute;を使ってボックス全体をカバーすれば目的は達成できる。
なお、after疑似要素でも同じことができるけど、ここはclearfixが使えるように開けておきたい。
コード構成
HTML
<div class="background-opacity"> コンテンツ類 </div>
.background-opacity { position: relative; z-index: 0; } .background-opacity::before { content: " "; display: block; width: 100%; height: 100%; position: absolute; top: 0; left: 0; background-image: url(背景画像のパス); background-size: cover; background-position: center center; opacity: 0.35; } .background-opacity * { position: relative; }
コード解説
.background-opacity::before
まず、contentプロパティにスペースを入れることでbefore疑似要素を有効にします。。
content: " ";
次に、before疑似要素を親要素である.background-opacityの領域全体に広げます。
display: block; width: 100%; height: 100%; position: absolute; top: 0; left: 0;
display: block;でwidth, heightプロパティを使えるようにしています。
これはブロックレベル要素であればよいので、display: inline-block;やdisplay: table;でも同じような動作をしてくれるはずです。
そしてposition: absolute;を使って、.background-opacityの子要素がbefore疑似要素に重複するようにします。
また、top と left プロパティは、デフォルトではbefore疑似要素が.background-opacityのpaddingなどの影響を受けてしまうので、0の値を入れます。
最後にメインディッシュの背景画像の半透明化です。
background-image: url(背景画像のパス); background-size: cover; background-position: center center; opacity: 0.35;
背景画像は、画像のボケを許容する場合はボックスより小さいサイズでもOKです。ボケを発生させたくない場合は、画像の高さ、幅とも、想定される最大値を超えるようにしなければなりません。つまり、パソコンの画面で想定される最大幅以上の幅、スマホの縦長のサイズにしたときの最大の高さ以上の高さとなる画像を用意します。
background-sizeは、基本的にcoverを使って、ボックスからあふれる分はトリミングされるようにしています。デザインによっては他の値を入れてもよいでしょう。
background-positionは、今回の例では画像の中央が常に表示され、端の方はトリミングされてもOK,という形になっています。写真によって配置場所は変えるとよいでしょう。
最後に、opacityで写真の透明度を設定し、before疑似要素の調整は終了です。
.background-opacity
これはbefore疑似要素の親要素になるため、position:relative;を設定する必要があります。
position: relative; z-index: 0;
z-index: 0;の設定が地味に重要で、デフォルトだとbefore疑似要素が他の子要素の上を覆ってしまいます。
.background-opacity *
position: relative;
最後に、.background-opacity の子要素全てにposition: relative;を設定します。
この設定にはz-index: 1;が隠れています。(デフォルトの設定)
これで全ての子要素がbefore疑似要素より上に配置されます。
カラーフィルター効果への応用
試してはいませんが、背景画像を.background-opacityに設置、before疑似要素にbackground-colorをrgbaでセットすると、背景画像へのカラーフィルター効果が得られるはずです。もしかしたらz-indexの値を.background-opacityは0、before疑似要素は1、.background-opacity * には2を設定する必要があるかもしれません。