はじめに
Webサイトのヘッダーなどで、「背景色に合わせて文字色を反転させつつ(mix-blend-mode: difference)、背景にはすりガラスのようなぼかし(backdrop-filter: blur)を入れたい」と思ったことはありませんか?
弊社コーポレートサイトのヘッダーを実装する際、まさにこの両方を適用しようとしたのですが、ある問題に直面しました。
今回は、この2つのプロパティを共存させるための解決策をご紹介します。

気づいた点:2つを同じ要素につけると効かない?
実装を進める中で、「mix-blend-modeとbackdrop-filterを同じ要素に適用すると、mix-blend-modeが効かなくなってしまう」という仕様の壁にぶつかりました。
これはCSSの重ね合わせの順序の仕様によるものです。
backdrop-filterを適用した要素は、その要素自身が独立したレイヤーを作ってしまいます。そのため、その要素にmix-blend-modeをかけても、背後にあるページ全体のコンテンツと色がブレンドされなくなってしまうのです。
解決策:要素を2つに分けて「重ねる」
この問題を解決するために「blur(ぼかし)を担当する要素」と「mix-blend-mode(色反転)を担当する要素」をHTML上で完全に分離させ、それらを重ね合わせて表示するという方法をとります。
HTML
ヘッダーを2つのレイヤーに分けます。
1つは背面に配置する「ブラー(ぼかし)専用のダミーヘッダー」、もう1つは前面に配置する「色反転専用のメインヘッダー」です。
<!-- ① 背面:ブラー(ぼかし)を担当するレイヤー -->
<div class="header__blur" aria-hidden="true">
<span class="header__logo__link"></span>
<div class="header__arrow header__blur__arrow">
<div class="header__arrow__text">
<p>About</p>
<span></span>
<p>Recruit</p>
</div>
<img src="/img/arrow-down.svg" alt="">
</div>
</div>
<!-- ② 前面:色反転(difference)を担当するレイヤー -->
<header class="header header--blend">
<a href="/" class="header__logo__link">
<img src="/img/logo_icon_white.svg" alt="">
</a>
<div class="header__arrow --about js-open">
<div class="header__arrow__text --about">
<p>About</p>
<span></span>
<p>Recruit</p>
</div>
<img src="/img/arrow-down.svg" alt="">
</div>
</header>
SCSS
ポイントは、背面のダミー要素(.header__blur)のテキストや画像は visibility: hidden; で隠しつつ、幅や高さの空間だけを確保することです。
前面の要素(.header–blend)には mix-blend-mode: difference; をかけ、背景は透明にします。
/* 共通のヘッダーレイアウト */
.header, .header__blur {
height: pxToRem(56px);
position: fixed;
display: flex;
padding: pxToRem(14px) pxToRem(16px);
gap: pxToRem(16px);
align-items: center;
@include mq(lg) {
height: pxToRem(80px);
padding: pxToRem(21px) pxToRem(24px);
gap: pxToRem(24px);
}
}
/* =========================================
前面レイヤー:色反転(mix-blend-mode)担当
========================================= */
.header {
z-index: 1000; /* 前面に配置 */
}
.header--blend {
/* 背景に応じて全体を反転させる */
mix-blend-mode: difference;
.header__arrow {
/* blurは持たせず、背面を透過させる */
background: transparent;
backdrop-filter: none;
}
}
/* =========================================
背面レイヤー:ぼかし(blur)担当
========================================= */
.header__blur {
z-index: 999; /* 背面に配置 */
pointer-events: none; /* クリック判定を無効化 */
.header__blur__arrow {
/* フロスト(すりガラス)背景だけを描画 */
background: rgba(234, 232, 231, 0.02);
backdrop-filter: blur(20px);
border-color: transparent;
}
/* 中身は幅を合わせるために配置するが、描画はしない */
.header__arrow__text,
img {
visibility: hidden;
}
}
/* 各種パーツのスタイリング */
.header__arrow {
padding: pxToRem(4px) pxToRem(16px);
border-radius: 50px;
border: 1px solid #fff;
display: flex;
align-items: center;
box-shadow: 0 0 12px 0 transparent;
cursor: pointer;
transition: box-shadow 0.3s ease;
img {
display: block;
}
&:hover {
box-shadow: 0 0 12px 0 rgba(77, 77, 77, 0.50);
}
}
// ※以降、.header__arrow__text などのスタイル定義が続く...
おわりに
要素を2つに分けて重ねることで2つのプロパティを見事に共存させることができます。
同じ問題でつまずいた方の参考になれば幸いです!
こちらのCSSの記事も良ければ合わせてご確認ください。