LoginSignup
47
24
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

CSS だけで、かつ不要な div を使わずに、擬似 Progressive blur

Last updated at Posted at 2024-01-08

この記事の概要

あるときこちらの記事を見ました。

CSS でのストレートな実装はできないようで、なかなかパワー系の実装が紹介されていました。

この表現のためだけに 350 もの div を作成するのはなあ……と思い、もう少し現実的なやり方を考えてみました。

この記事ではコードの一部を載せていますが、全体はこちらのリポジトリに置いてあります。

Progressive blur の実現の方向性

usagimaru さんの記事にある通りですが、現状実現されている方向性は以下のどちらかです。

  1. フィルターを小刻みに並べる
  2. アルファマスクによる擬似 Progressive blur

1 の フィルターを小刻みに並べる は冒頭の codepen のようなやり方です。
2 の アルファマスクによる擬似 Progressive blur は、大きめのボケがかかった要素にマスクをかけるようなやりかたです。

この 2 つを組み合わせて、擬似的な再現の中では っぽい 見た目にしてみました。

完成形

グリッド状に画像を並べ、下部に Progressive blur をかけた要素を作りました。

HTML は次のようになっています。
装飾のためだけの div などはありません。

HTML
<body>
  <div>
    <img src="path/to/image" alt="" width="800" height="450">
    <img src="path/to/image" alt="" width="800" height="450">
    <img src="path/to/image" alt="" width="800" height="450">
    <!-- 以下画像が続く -->
  </div>
  <footer>Progressive blur</footer>
</body>

CSS は次のようになっています。1

CSS
footer {
  position: fixed;
  bottom: 0;
}

footer::before {
  position: absolute;
  z-index: -1;
  inset: 0;
  content: "";
  backdrop-filter: blur(1rem);
  mask-image: linear-gradient(
    to bottom,
    rgb(0 0 0 / 0%) 0%,
    rgb(0 0 0 / 4.9%) 7.75%,
    rgb(0 0 0 / 10.4%) 11.25%,
    rgb(0 0 0 / 45%) 23.55%,
    rgb(0 0 0 / 55%) 26.45%,
    rgb(0 0 0 / 89.6%) 38.75%,
    rgb(0 0 0 / 95.1%) 42.25%,
    rgb(0 0 0 / 100%) 50%
  );
}

footer::after {
  position: absolute;
  z-index: -1;
  inset: 0;
  top: 25%;
  content: "";
  backdrop-filter: blur(2rem);
  mask-image: linear-gradient(
    to bottom,
    rgb(0 0 0 / 0%) 0%,
    rgb(0 0 0 / 4.9%) 15.5%,
    rgb(0 0 0 / 10.4%) 22.5%,
    rgb(0 0 0 / 45%) 47.1%,
    rgb(0 0 0 / 55%) 52.9%,
    rgb(0 0 0 / 89.6%) 77.5%,
    rgb(0 0 0 / 95.1%) 91.9%,
    rgb(0 0 0 / 100%) 100%
  );
}

解説

不要な要素は使いたくありませんでしたが、さすがに単なる backdrop-filter などではどうしようもなく、擬似要素を使いました。

z-index には -1 を指定して、もともとの footer よりも後ろに表示されるようにしています。

また、それぞれに backdrop-filtermask-image をかけています。
ボケ感の違う 2 つのフィルターを、上から下に不透明度が上がるようにマスクをかけて重ねている、という状態です。

マスク ボケ量
before
after

mask-image がやたら細かいのは、単に 0 -> 1 で指定すると変化が急に見えるからです。
現状の CSS では変化を滑らかにすることはできないので、手動で間を補完しています。

参考: https://css-tricks.com/easing-linear-gradients/

最後に

よく見れば変化している箇所が分かってしまいますし、マスクをかけている関係で若干汚いボケ方になっています。

しかし、コードの管理のしやすさやパフォーマンス的なことを考えるとまあまあ良い塩梅で実現できたのではないかと思います。

  1. 今回の説明に必要なものだけを抜き出しています。

47
24
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
47
24