【CSS】背景テクスチャに色んな色を乗せるのにbox-shadowが有用な件。

コーディング

ウェブのコーディングをしていて、背景画像のテクスチャに色を乗せたい、そんな時の考え方について少しメモ。

やりたかったこと

背景をうっすらエンボスっぽい凹凸のあるテクスチャの上に色が乗ったものにしたかっただけです。

勿論、

background: url( path/to/texture.png ) center top repeat rgba( 255, 0, 0, .5);

みたいに背景色を指定しただけでは、テクスチャの下に背景色が入るので、重なりとしては逆です。

実装方法いろいろ

  1. テクスチャの画像にカラーオーバーレイをかけて書き出す・・・面倒だし、背景パターンと色の数だけ画像が必要になる。あとで色が変更になった時に画像を作り直さないといけない。

  2. 半透過色のpng画像をいろいろ作っておいて、multiple backgrounds で実装。・・・半透過色のpngさえ作れれば、まあ面倒ではない。けど、実装としてはダサいww

  3. HTMLで実装。背景にテクスチャ(background-imageで指定)、その上に半透過色のdivを重ねてやる。

    <section class="背景にテクスチャ画像を指定">
    <div class="半透過色を乗せる">
        コンテンツ
    </div>
    </section>

    あるいは

    <section class="背景にテクスチャ画像を指定">
    <div class="position:absoluteで半透過色を乗せる"></div>
    <div>
        コンテンツ。
        ただしコンテンツ部分のheightを取るためにjavascriptで計算する必要があるんじゃね?
    </div>
    </section>

    勿論、こんな面倒臭い前時代的なことはやってられねぇ。

  4. CSSのみで実装。テクスチャを乗せた領域に ::after、::before 擬似要素で半透過色を乗せてやる

    <div class="texture-bg"><!-- 背景にテクスチャ画像を指定 -->
    コンテンツ
    </div>
    .texture-bg {
    width: 600px;
    height: 400px;
    position: relative;
    background: url(https://img17.shop-pro.jp/PA01270/216/product/99243864.jpg) center top;
    }
    .texture-bg::after {
      content: '';
      position: absolute;
      display: block;
      background-color: rgba( 145, 141, 64, .8);
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
    }
    .texture-bg > p {
      position: relative;
      z-index: 2;
    }

    お気づきであろうが、相当メンドくせぇ。擬似要素で乗せた背景色とコンテンツ部分の重なり順z-indexを調整してやらなきゃならないというおまけ付きですw

  5. あ、そういえば box-shadow ってinsetあったんじゃね??
    結論。はい、正解ww

box-shadowを使ってテクスチャに色を付ける

そうなんです、box-shadowは insetプロパティを取ることができますので、内側に影を落とすことができるのです。なので、スプレッドをマックスにしてぼかしをゼロにしたらいけるはずです。
また、X、Yそれぞれのオフセットをマックスにしてもいけるんじゃないかな、と。

See the Pen
Untitled
by yngdrsk (@yngdrsk)
on CodePen.

領域を最大に塗りつぶすために、length値に100%を指定したいのですが、%は取れないようなので100vw、100vhという単位を使います。

詳しくはドキュメントを参照してもらうとして、box-shadowのlength値は最大4つまで取ることができますが、

  • 値が 2 つだけ与えられた場合、 offset-x および offset-y として解釈されます。
  • 3 つ目の値が与えられた場合、 blur-radius として解釈されます。
  • 4 つ目の値が与えられた場合、 spread-radius として解釈されます。

ということです。
ですから、上記のサンプルコードのbox-shadowの部分の書き方は以下ふた通りができそうです。

/* オフセットで塗りつぶす場合 */
box-shadow: 100vw 100vh rgba( 145, 141, 24, .5) inset;

/* スプレッドで塗りつぶす場合 */
box-shadow: 0 0 0 100vw rgba( 145, 141, 24, .5) inset;

当然、前者の方が楽ですね。

これで解決!!!

コーディングcss

Posted by 大将