背景色にじんわりと色が染み出るYouTubeのあのUIをCSSで実装する。

sawaですよろしくおねがいします😺
# はじめに

去年の10月にYouTubeのUIがアップデートされるとの情報が発表され、ニュース記事でもチェックされた方は多いのではないでしょうか。

https://blog.youtube/news-and-events/an-updated-look-and-feel-for-youtube/

その中で自分が興味を抱いたものが「アンビエントモード」です。
動画内の色を背景色に反映させたものです。


わかりやすい例として下の図を作成しました。
画面下の黒い背景色に、画面上の写真の色がじわっと反映されています。
![スクリーンショット 2023-03-14 153738 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752085/2da99ec8-c070-d7ed-8cd5-7aecdf8f68cd.png)



なんだかお洒落でいい感じの雰囲気になるので、これをブラウザでも実装していきたいと思います。

ちなみにYouTubeアプリでは動画内の色を動的に反映させているようなのですが、CSSのみではおそらく実現不可能なので静止画を用いて実装します。
今回はサンプルとして汎用的なカード型コンポーネントを実装していきたいと思います。

また、こちらは近年流行っている「グラスモーフィズム」とは別物なので、この記事の後半に違いをご説明します。

# コード例

今回は下記の図のように要素を重ねていきます。
![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752085/77345908-744a-9f32-6a38-352050e68f12.png)


## HTML

``` html:index.html
<div class="card">
  <div class="card-img"></div>
  <dl class="card-text">
    <dt>Title</dt>
    <dd>
      Lorem ipsum, dolor sit amet consectetur adipisicing elit. Hic
      voluptatibus autem itaque aperiam eos, ducimus, non provident quidem
      neque fugit corrupti nam aliquid libero voluptates laudantium,
      blanditiis rerum harum culpa.
    </dd>
  </dl>
</div>
```
HTMLはこのような感じです。

画像の表示に`<img>`タグを使っていない点に着目してください。
`<img>`タグの代わりに`<div>`タグを挿入し、CSSの`background-image`プロパティでパスを設定します。

理由としては、今回はCSSの疑似要素で画像を複製する必要があるからです。その場合`background-image`プロパティの方が画像を扱いやすいため、`<div>`タグを使った実装にしています。（この点については[丁寧に紹介されている記事](https://kouhekikyozou.com/css_content_image)があったので参考にしてみてください）

## CSS
``` css:style.css
.card {
  position: relative;
  overflow: hidden;
  width: 360px;
  height: 500px;
  border-radius: 10px;
  background-color: #000;
  z-index: -10;
}
.card-img {
  height: 300px;
  width: 360px;
  background-image: url("https://images.unsplash.com/photo-1498940757830-82f7813bf178?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1074&q=80");
  background-size: cover;
}
.card-img::after {
  content: "";
  display: block;
  position: relative;
  z-index: -1;
  height: 100%;
  width: 100%;

  /*参照先の画像を複製
  Duplicate referenced image*/
  background-image: url("https://images.unsplash.com/photo-1498940757830-82f7813bf178?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1074&q=80");
  background-size: cover;

  /*画像をぼかして下にずらす
  Blur and shift the image down*/
  filter: blur(20px);
  transform: translateY(20px);


  /*ブレンドモードの設定
  Blend mode settings*/
  mix-blend-mode: difference;
}
.card-text {
  position: relative;
  color: #fff;
  padding: 16px;
  line-height: 24px;
}
```
CSSは上記で全てです。


疑似要素を設定する上での注意点があるので後述します。

### z-indexについて

疑似要素は何も指定していないと親要素の上に重なるため、ぼかした疑似要素が写真の下に来るように`z-index`でマイナスの値を指定します。
このとき、親要素に`z-index`を指定すると疑似要素の上に重なってしまうため、親要素には`z-index`を設定しないでください。
それに伴い、背景色を指定している要素の`z-index`が疑似要素よりも下に重なるようにマイナス値を設定してください。


### 画像をぼかしてずらす
``` 
  filter: blur(20px);
  transform: translateY(20px);
```
疑似要素で親と同じ画像を複製し、それを`filter: blur()`でぼかします。
今回は画像下部の背景色にぼかしたものを重ねたいので、`transform: translateY()`を設定して疑似要素を下にずらすようにしています。

また、画像をぼかした分は親要素からはみでてしまうので、親要素に`overflow: hidden`を設定し、はみ出ている部分をカットしてください。
↓`overflow: hidden`を設定せずぼかしが親要素からはみ出している例
![スクリーンショット 2023-03-14 174844.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752085/e5fbc342-8265-c1e8-45af-de58dd3c7c78.png)

# グラスモーフィズムとの違い
（グラスモーフィズムについては[弊社の過去記事](https://qiita.com/alpaca1231/items/6c980848a783660aef8d)を参考にしてね）


図で比較してみました。
![Frame 155.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752085/1645a1c1-0c39-81ce-cd18-e93c8373b2da.png)
今回の実装方法だと、大きな画像を用意しなくて済みます。
また、テキスト部分の背景色も透けないので可読性が保てます。


さらに、疑似要素の`mix-blend-mode`プロパティでぼかし部分の色の表現を変えることができます。
下図にいくつか例を挙げます。
![Frame 156.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752085/3d08c25b-b0f1-70f9-0be1-e50f900de2ca.png)

`mix-blend-mode`で与える印象が変わってくるので、いくつか試してみることをお勧めします。

# おわりに

今回はカード型で例を挙げましたが、いろんな箇所に適用していただけるかと思います。
疑似要素でちょっとひと手間加えて、ガンガンいい感じの雰囲気にしていきましょう！

最後にcodepenのリンクを貼っておきますので、こちらで触って色々試してみてください。

<p class="codepen" data-height="650" data-default-tab="html,result" data-slug-hash="KKxoMrp" data-user="SawadaMoemi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/SawadaMoemi/pen/KKxoMrp">
  Color seeping UI</a> by sawa (<a href="https://codepen.io/SawadaMoemi">@SawadaMoemi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>