LoginSignup
1
2

More than 1 year has passed since last update.

mix-blend-modeで背景だけにブレンドモードを適用する方法

Posted at

CSSのmix-blend-modeは、重なり合う要素のブレンドモードを指定するプロパティです。
このプロパティを使うと、単なる透過だけではなく、乗算などさまざまなブレンドモードで重ねることができるようになるので、デザインの幅もぐっと広がります。どんどん使っていきたいところなのですが、意外と制約が多くままならないことが多いので、実際のコーディング例をもとに気をつけるべきポイントをまとめてみました。

コーディングするデザイン

画像の上に文字が乗っており、その下に座布団(塗りつぶした長方形)が重なっているという、よくあるデザイン。
座布団だけが乗算で重なっており、その上のテキストは不透明の白で乗っています。
画像は背景ではなく、img要素としてコーディングされる必要があると仮定します。

デザイン例

コーディングの失敗例その1:文字も乗算になってしまう

まずは以下のようにコーディングしてみます。

HTML

<div class="wrapper">
    <div class="image">
        <img src="img/lunch.jpg" alt="ランチ">
    </div>
    <div class="text">
        <p class="title">Lunch</p>
    </div>
</div>

CSS

  .wrapper {
    width: 700px;
    font-family: Baskerville;
    position: relative;
  }
  .wrapper .text {
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
        -ms-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
    background-color: rgba(69, 38, 18, 0.7);
    padding: 50px 110px;
  }
  .wrapper .title {
    font-size: 70px;
    color: #ffffff;
  }

表示
スクリーンショット
このコーディングの仕方だと、座布団にmix-blend-mode: multiplyを指定すると、その子要素であるテキストも乗算で重ねられてしまいます。

コーディングの失敗例その2:乗算にならない

それでは、座布団の要素にbefore擬似要素を置いて、テキストとは兄弟関係になるようにしてみましょう。

CSS

  .wrapper {
    width: 700px;
    font-family: Baskerville;
    position: relative;
  }
  .wrapper .text {
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
        -ms-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
    padding: 50px 110px;
  }
  .wrapper .text:before {
    content: '';
    display: block;
    position: absolute;
    z-index: 1;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(69, 38, 18, 0.7);
    mix-blend-mode: multiply; 
  }
  .wrapper .title {
    font-size: 70px;
    color: #ffffff;
    position: relative;
    z-index: 2;
  }

表示
スクリーンショット
少しわかりにくいかもしれませんが、座布団の要素.text:beforeに設定したmix-blend-mode: multiplyが適用されていないことが分かります。

なぜmix-blend-modeが適用されないのか?

実は、mix-blend-modeは、同じスタックコンテキスト内にある要素同士のブレンドモードを指定するプロパティです。
このコーディング例では、座布団の要素に

transform: translate(-50%, -50%);

を指定しています。
実は、要素にtransformを指定すると、新しいスタックコンテキストが作られます。すると、その子要素であるbefore擬似要素とp要素は料理の写真のimg要素とは別のスタックコンテキストに属することになり、これらの要素の重なりには、mix-blend-modeが適用されなくなってしまうのです。

成功例

これをもとに、もう少し考えてみます。
要素の重なりと、画像の中心にテキストを置く配置を別の方法で実装します。

  .wrapper {
    width: 700px;
    font-family: Baskerville;
    position: relative;
    display: grid;
    grid-template-rows: auto;
    grid-template-columns: auto;
  }
  .wrapper .image {
    grid-row: 1 / 2;
    grid-column: 1 / 2;
  }
  .wrapper .text {
    grid-row: 1 / 2;
    grid-column: 1 / 2;
    align-self: center;
    justify-self: center;
    padding: 50px 110px;
    position: relative;
  }
  .wrapper .text:before {
    content: '';
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(69, 38, 18, 0.7);
    mix-blend-mode: multiply;
    z-index: 1;
  }
  .wrapper .title {
    font-size: 70px;
    color: #ffffff;
    position: relative;
    z-index: 2;
  }

この例では、ラッパ要素にdisplay: gridを指定しました。
そして、画像とテキストを同じグリッドセル上に配置します。
テキストの中央寄せは、

align-self: center;
justify-self: center;

で指定しました。

この時、画像とテキストの重なり順を指定しようと、z-indexを指定してしまわないように気をつけてください。
positionをstatic以外に設定し、かつz-indexがauto以外の時も、やはりスタックコンテキストが新たに作られてしまうからです。
CSS Gridでは、同じグリッドセル上にある要素は、ソースコード上で後に書かれたものが上に来る仕様になっています。上に置きたい要素を後の方に書くようにしましょう。

結果
スクリーンショット
デザイン通りの表示になりました。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2