CSSのみでフォントは不透過でその背景色のみを乗算でそのまた背景の画像に重ねる

仕上がりイメージは斯うです。

先ずは最下層に背景画像があります。 上の例では神社の写真が其れに当たります。 其の上に帯がのり、其の上、左方に白のアイコン、右方に白のフォント文字が乗ります。 アイコンとフォント文字を包含した帯は元は紺色ですが、 乗算で其のまた背景画像に重ねられており、 唯に単色の不透過色の場合とは異なる深みを感じさせるイメージを醸し出しています。 此れを皆、CSSのみで実現したく試行錯誤しました。

参考のために唯に単色の不透過の紺色の帯の場合を下に貼り置きましょう。 随分イメージが異なるのがはっきりします。

スポンサーリンク

此れは画像編集ソフトの定番、フォトショップなどでは簡単です。 しかし一旦Webサイト上で実現しようとするとなかなかの難事です。 乗算画像をフォトショップで用意して背景画像に指定すれば簡単ですが、 其れではCSSのみでの実装にはなりませんし、実装後にも自由が効きません。 なんとかCSSのみで冒頭画像のイメージが実現できる様にするのは レスポンシブ(Webデザイン)時代の要請でもあるでしょう。

渡されたデザインデータを見て アイコンとフォントを乗せた帯レイヤーが乗算処理されているのに気付いたのは レスポンシブで其のデザインをWebサイト上に実現すべく 背景画像とアイコンを分離して用意し、 HTMLを書き、CSSを書きオンライン上で確認した時でした。

.main-img {
  background: url(main-img.jpg) no-repeat center top;
  h2 {
    width: 400px;
    height: 120px;
    color: #fff;
    background: url(icon.png) no-repeat left center;
    background-color: rgba(47, 61, 88, 0.6);
  }
}

此の時は背景色の透過で実現出来ると思っていたのでした。 しかし、デザインデータと比べると上のCSSコードを書いて見た 帯の透過される部分の背景画像に重なる色が汚いことに気付きます。 因みにCSSコードは見易さの為にSassの書式に拠っており、以降のコードも準じます。

帯レイヤーの透過度を幾ら変えて見ても、 雰囲気は到底冒頭画像には及びません。 実は画像編集ソフト上で帯レイヤーは乗算で設定されていたのでした。 此処から試行錯誤が始まります。

どうやら透過した背景色を設定するだけでは 望む効果が得られないのに気付いて、 ネットを適当なCSSプロパティを求めて繰れば background-blend-mode: multiply; が見付かりました。 CSS3から追加されたプロパティの様で 何とCSSのみで乗算が実現出来ると言う優れものです。 以下のWWW WATCHの2013年12月6日の記事などが参考サイトとして挙げられるでしょう。

background-blend-mode プロパティで背景をブレンドしてみよう

此の時、不透過単色から引き続きH2と背景画像の2要素で実現できると思っています。 従って以下の様なコーディングを施しました。

.main-img {
  background: url(main-img.jpg) no-repeat center top;
  h2 {
    width: 400px;
    height: 120px;
    color: #fff;
    background-image: url(icon.png) no-repeat left center;
    background-blend-mode: multiply;
  }
}

処が此の記述では唯の不透過の背景色となってしまい、其のまた背景が見えなくなってしまいます。 background-colorプロパティに問題があるのだと思い、 背景画像で試すべく書いて見たのが下になります。

.main-img {
  background: url(main-img.jpg) no-repeat center top;
  h2 {
    width: 400px;
    height: 120px;
    color: #fff;
    background-image: url(icon.png), url(title-bg.png);
    background-repeat: no-repeat, repeat;
    background-position: left center, left top;
    background-blend-mode: normal, multiply;
    background-size: auto auto, auto auto;
  }
}

しかしやはり背景色は不透過のままで望むべく効果は得られません。 仕方なく、H2と背景画像の2要素で実現すべく 再びネットで別の方法を探すと background-blend-mode: multiply; の他に mix-blend-mode: multiply; と言うCSSプロパティが見付かりました。 実は上の参考サイトにも情報は記載されていたのですが、見過ごしていました。 mix-blend-mode については以下など参考になるかも知れません。

そして修正したコードが以下になります。

.main-img {
  background: url(main-img.jpg) no-repeat center top;
  h2 {
    width: 400px;
    height: 120px;
    color: #fff;
    background: url(icon.png) no-repeat left center #2f3d58;
    mix-blend-mode: multiply;
  }
}

上記のコードを期待に胸膨らませながら走らせるや、 喜びと落胆が綯い交ぜの結果になったのは 見事文字背景色がその背景と乗算で表示されたにも関わらず、 残念ながらアイコン及びフォント文字までが乗算になってしまったからでした。 白は乗算すれば輪郭のみ存在する透明となってしまいますから、 即ち、結果として不透過に目論んだ白いアイコン、及び白文字の部分が 透明に透き通ってしまったのでした。

しかし、CSSのみで背景色と背景画像との乗算処理が可能であるのが判明したのですから、 あと、一歩です、否、結果的に此処からはあと三歩になったのでしたが。 此処迄拘ったのはHTMLを書く際に成る可く内容と関係ない要素は用いない、と言う原則でした。 使用しているDOM要素は.main-imgとh2のみです。 原則を崩すのは遺憾ですが、此の2要素の間にデザイン的な目的のみを持つ 要素を挟み其れに乗算プロパティを設定すれば此処迄の経緯から恐らくは目論見が達成出来るだろう、 と考えた記述が以下です。

.main-img {
  margin: 0 auto;
  .ttl-base {
    width: 400px;
    height: 120px;
    background: #2f3d58;
    mix-blend-mode: multiply;
    h2 {
      width: 400px;
      height: 120px;
      color: #fff;
      background: url(icon.png) no-repeat left center #2f3d58;
    }
  }
}

此れは残念ながら上と同じ文字までが乗算になってしまう結果でしたが、 もう一歩を進めます。 恐らくは乗算処理するDOM要素に不透過にしたい要素を含むH2をネストしたのが問題だと思われますから、 乗算を施す背景要素.ttl-baseとタイトルのH2を並列の要素にして positionプロパティのabsoluteで重ねてみれば上手く行くのではないかと直ぐ閃きました。 コーディングは以下になります。

.main-img {
  position: relative;
  .ttl-base {
    width: 400px;
    height: 120px;
    background: #2f3d58;
    mix-blend-mode: multiply;
    position: absolute;
    left: ***px;
    top: ***px;

  }
  h2 {
    width: 400px;
    height: 120px;
    color: #fff;
    background: url(icon.png) no-repeat left center #2f3d58;
    position: absolute;
    left: ***px;
    top: ***px;

  }
}

此れは上手く行きました。 目論見通りの見栄えが得られたのです。 .ttl-base要素とH2要素の幅と高さを揃え、 尚且つポジション位置のtop、leftを揃えてやれば良い勘定です。

しかし出来るならば原則通り、 内容に関係なくデザインのためだけに挿入するDOM要素は避けたい処です。 従ってあと一歩進めれば目論見は完璧に達成されるのですが、 其れは其れ程難しい話ではなく、 日常スタイルシートを扱い慣れている向きなら直ぐにも思い付くでしょう、 擬似要素を用いれば良いのでした。 此処迄来れば解決は目前、 例によってこんな時用いるべき擬似要素は :before であって、然すればDOMは再び2要素となって問題は解決します。 そして最終的なコードが以下となりました。

===== HTML =====
<div class="main-img">
  <h2>TITLE</h2>
</div>

===== CSS =====
.main-img {
  position: relative;
  &:before {
    content: "";
    display: block;
    width: 400px;
    height: 120px;
    background: #2f3d58;
    mix-blend-mode: multiply;
    position: absolute;
    left: ***px;
    top: ***px;
  }
  h2 {
    width: 400px;
    height: 120px;
    color: #fff;
    background: url(icon.png) no-repeat left center;
    position: absolute;
    left: ***px;
    top: ***px;
  }
}

直上のコードにて極めてシンプルなHTMLコードで、 H2が乗せる白アイコンと白フォント文字は不透過のまま、 其の背景色のみがまた其の背景画像に乗算処理される冒頭画像の表示、 と言う要請は達成されました。

スポンサーリンク