【CSS】filterの使い方:画像や背景の色変更・ぼかしと効かない時の対策

css-filter

CSSのfilterおよびbackdrop-filterは、Photoshop等の画像編集ソフトを使わずに、画像の色調変更、ぼかし、影付けなどをブラウザ上で動的に表現できるプロパティです。

本記事では、10種類のフィルター関数の使い方、「画像が白にならない」「Safariでぼかしが効かない」といった実務で直面する罠と解決策を解説します。

また、CSSに関するカテゴリーページから学びたい内容を決めたい人は、以下のCSSページをご確認ください。

目次

filterとは:画像の色・ぼかしを操る

Webサイトのデザインにおいて、画像や要素の色味を変えたり、ぼかしを入れたりする加工は頻繁に行われます。

かつてはPhotoshopなどの画像編集ソフトで加工済みの画像を複数用意する必要がありましたが、現在はCSSプロパティだけでエフェクトを瞬時に適用できます。

それがfilterプロパティです。

filterの使い方」や「filterの用法」をマスターすれば、1枚の元画像を用意するだけで動的にデザインを切り替えることが可能になります。

filterとは:画像の色・ぼかしを操る
  • filterプロパティの役割と10種類の関数
  • filterの複数指定ルール
  • transitionを使ったホバー時の滑らかなアニメーション

filterプロパティの役割と10種類の関数

filterプロパティは、画像だけでなく、テキストを含むブロック要素や中身に対してグラフィックエフェクトを適用する役割を持ちます。

利用できる主な関数は以下の10種類です。

  1. blur():ぼかし
  2. brightness():明るさ
  3. contrast():コントラスト
  4. drop-shadow():影
  5. grayscale():モノクロ化
  6. hue-rotate():色相回転
  7. invert():階調の反転
  8. opacity():不透明度
  9. saturate():彩度
  10. sepia():セピア調

背景だけを加工したい場合は、親要素にfilterをかけるのではなく、「疑似要素(::beforeなど)に背景画像を設定して、疑似要素に対してのみfilterをかける」か、「画像のimgタグとテキストを兄弟要素として配置し、imgにだけfilterをかける」のがよいです。

⭕️ 10種類のフィルター大集合!&親要素にかけてしまう初心者あるあるの罠

通常 (Normal)

通常

1. blur
(ぼかし)

ぼかし

2. brightness
(明るさ)

明るさ

3. contrast
(コントラスト)

コントラスト

4. drop-shadow
(影)

影

5. grayscale
(モノクロ化)

モノクロ

6. hue-rotate
(色相回転)

色相回転

7. invert
(階調反転)

階調反転

8. opacity
(不透明度)

不透明度

9. saturate
(彩度)

彩度

10. sepia
(セピア調)

セピア

❌ 親への適用罠
(文字までボケる)

テキストも
ボケる!
/* 💡 画像自体に直接フィルターをかける正しい例 */
.img-blur { filter: blur(5px); } /* px等で指定 */
.img-brightness { filter: brightness(1.5); } /* 1が基準。1.5は明るく、0.5は暗く */
.img-contrast { filter: contrast(200%); } /* %や小数で指定。メリハリをつける */
.img-shadow { filter: drop-shadow(4px 4px 6px rgba(0,0,0,0.5)); } /* 透過画像にも沿う影 */
.img-hue { filter: hue-rotate(90deg); } /* deg(角度)で色相を回す */
.img-saturate { filter: saturate(300%); } /* 色を鮮やかにする */
/* ※grayscale, invert, opacity, sepia は 0%〜100% などで指定します */

/* ❌ 親要素(箱)にフィルターをかけてしまう */
.parent-box {
  filter: blur(4px); /* 🚨 中に入っているテキストなど、子要素すべてが道連れでボケる! */
}
HTMLコード表示
<div class="filter-layout-wrapper">
  
  <p class="filter-caption">⭕️ 10種類のフィルター大集合!&親要素にかけてしまう初心者あるあるの罠</p>

  <!-- 💡 10種類+罠をGridで整列 -->
  <div class="filter-demo-area">
    
    <div class="filter-item">
      <p class="filter-label">通常 (Normal)</p>
      <!-- 💡 変化が分かりやすい風景写真を使用 -->
      <img class="filter-img" src="https://picsum.photos/id/29/120/120" alt="通常">
    </div>

    <div class="filter-item">
      <p class="filter-label">1. blur<br><small>(ぼかし)</small></p>
      <img class="filter-img is-blur" src="https://picsum.photos/id/29/120/120" alt="ぼかし">
    </div>

    <div class="filter-item">
      <p class="filter-label">2. brightness<br><small>(明るさ)</small></p>
      <img class="filter-img is-brightness" src="https://picsum.photos/id/29/120/120" alt="明るさ">
    </div>

    <div class="filter-item">
      <p class="filter-label">3. contrast<br><small>(コントラスト)</small></p>
      <img class="filter-img is-contrast" src="https://picsum.photos/id/29/120/120" alt="コントラスト">
    </div>

    <div class="filter-item">
      <p class="filter-label">4. drop-shadow<br><small>(影)</small></p>
      <img class="filter-img is-drop-shadow" src="https://picsum.photos/id/29/120/120" alt="影">
    </div>

    <div class="filter-item">
      <p class="filter-label">5. grayscale<br><small>(モノクロ化)</small></p>
      <img class="filter-img is-grayscale" src="https://picsum.photos/id/29/120/120" alt="モノクロ">
    </div>

    <div class="filter-item">
      <p class="filter-label">6. hue-rotate<br><small>(色相回転)</small></p>
      <img class="filter-img is-hue-rotate" src="https://picsum.photos/id/29/120/120" alt="色相回転">
    </div>

    <div class="filter-item">
      <p class="filter-label">7. invert<br><small>(階調反転)</small></p>
      <img class="filter-img is-invert" src="https://picsum.photos/id/29/120/120" alt="階調反転">
    </div>

    <div class="filter-item">
      <p class="filter-label">8. opacity<br><small>(不透明度)</small></p>
      <img class="filter-img is-opacity" src="https://picsum.photos/id/29/120/120" alt="不透明度">
    </div>

    <div class="filter-item">
      <p class="filter-label">9. saturate<br><small>(彩度)</small></p>
      <img class="filter-img is-saturate" src="https://picsum.photos/id/29/120/120" alt="彩度">
    </div>

    <div class="filter-item">
      <p class="filter-label">10. sepia<br><small>(セピア調)</small></p>
      <img class="filter-img is-sepia" src="https://picsum.photos/id/29/120/120" alt="セピア">
    </div>

    <div class="filter-item">
      <p class="filter-label" style="color:#dc3545;">❌ 親への適用罠<br><small>(文字までボケる)</small></p>
      <!-- 💡 背景画像の上に文字を乗せた状態の親要素をシミュレート -->
      <div class="filter-fail-box" style="background-image: url('https://picsum.photos/id/29/120/120');">
        <span>テキストも<br>ボケる!</span>
      </div>
    </div>

  </div>

  <!-- 💡 エディタ画面風の解説エリア -->
  <div class="filter-code-area">
    <span class="hl-comment">/* 💡 画像自体に直接フィルターをかける正しい例 */</span><br>
    <span class="hl-blue">.img-blur</span> { <span class="hl-green">filter:</span> <span class="hl-red">blur(5px);</span> } <span class="hl-comment">/* px等で指定 */</span><br>
    <span class="hl-blue">.img-brightness</span> { <span class="hl-green">filter:</span> <span class="hl-red">brightness(1.5);</span> } <span class="hl-comment">/* 1が基準。1.5は明るく、0.5は暗く */</span><br>
    <span class="hl-blue">.img-contrast</span> { <span class="hl-green">filter:</span> <span class="hl-red">contrast(200%);</span> } <span class="hl-comment">/* %や小数で指定。メリハリをつける */</span><br>
    <span class="hl-blue">.img-shadow</span> { <span class="hl-green">filter:</span> <span class="hl-red">drop-shadow(4px 4px 6px rgba(0,0,0,0.5));</span> } <span class="hl-comment">/* 透過画像にも沿う影 */</span><br>
    <span class="hl-blue">.img-hue</span> { <span class="hl-green">filter:</span> <span class="hl-red">hue-rotate(90deg);</span> } <span class="hl-comment">/* deg(角度)で色相を回す */</span><br>
    <span class="hl-blue">.img-saturate</span> { <span class="hl-green">filter:</span> <span class="hl-red">saturate(300%);</span> } <span class="hl-comment">/* 色を鮮やかにする */</span><br>
    <span class="hl-comment">/* ※grayscale, invert, opacity, sepia は 0%〜100% などで指定します */</span><br><br>

    <span class="hl-comment">/* ❌ 親要素(箱)にフィルターをかけてしまう */</span><br>
    <span class="hl-blue">.parent-box</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">blur(4px);</span> <span class="hl-comment">/* 🚨 中に入っているテキストなど、子要素すべてが道連れでボケる! */</span><br>
    }
  </div>

</div>
CSSコード表示
.filter-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.filter-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

/* 10種類を整列させるGridコンテナ */
.filter-demo-area {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 20px;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.filter-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.filter-label {
  font-size: 12px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.4;
  height: 34px; /* ラベルの高さを揃える */
}

/* 共通の画像サイズ */
.filter-img {
  width: 100px;
  height: 100px;
  border-radius: 8px;
  object-fit: cover;
}

/* =💡 10種類のフィルター指定= */
.is-blur { filter: blur(3px); }
.is-brightness { filter: brightness(1.5); }
.is-contrast { filter: contrast(200%); }
.is-drop-shadow { filter: drop-shadow(4px 4px 6px rgba(0,0,0,0.6)); }
.is-grayscale { filter: grayscale(100%); }
.is-hue-rotate { filter: hue-rotate(90deg); }
.is-invert { filter: invert(100%); }
.is-opacity { filter: opacity(40%); }
.is-saturate { filter: saturate(300%); }
.is-sepia { filter: sepia(100%); }

/* =❌ 罠:親要素への適用= */
.filter-fail-box {
  width: 100px;
  height: 100px;
  border-radius: 8px;
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 13px;
  line-height: 1.4;
  text-shadow: 1px 1px 2px rgba(0,0,0,0.8);
  /* 親要素にかけることで、中の白い文字まで無惨にボケてしまう */
  filter: blur(3px); 
}

/* =コード解説エリア(エディタ風)= */
.filter-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

画像に関するimgタグの使い方を詳しく知りたい人は「【HTML】imgタグの使い方:src・altの使い分けや画像リサイズ・中央寄せ」を一読ください。

filterの複数指定ルール

filterプロパティは、「モノクロにして、さらに少し暗くしたい」といったように、複数のエフェクトを同時に組み合わせることが可能です。

また、要素の形状に沿って複数の影を落とすといった表現も可能です。

filterプロパティを複数指定する際は、「半角スペースで区切ること」です。

また、「記述した順番に処理される」という点も重要です。

例えば、opacity(透明化)をしてからdrop-shadow(影)をかけるか、影をかけてから透明化するかで見た目の結果が変わる場合があります。

パフォーマンスへの影響も考慮し、多重掛けしすぎない設計を心がけましょう。

⭕️ 複数のフィルターを重ねる技と、カンマ(,)で区切って無効になる罠

通常 (Normal)

通常

単一(モノクロのみ)

単一

⭕️ 複数指定(スペース区切り)
モノクロ + 暗く + 影

複数成功

❌ 複数指定の罠(カンマ区切り)
エラーになり無効化される

複数失敗
/* 💡 1つだけフィルターをかける場合 */
.img-single {
  filter: grayscale(100%);
}

/* ⭕️ 複数かける場合は「半角スペース」で繋ぐ! */
.img-multiple {
  /* 💡 モノクロにして、少し暗くして、影を落とす */
  filter: grayscale(80%) brightness(0.6) drop-shadow(6px 6px 8px rgba(0,0,0,0.6));
}

/* ❌ カンマで区切ってしまう */
.img-fail {
  filter: grayscale(80%), brightness(0.6); /* 🚨 構文エラー!フィルターが一切効かなくなる */
}
HTMLコード表示
<div class="filter-multi-layout-wrapper">
  
  <p class="filter-multi-caption">⭕️ 複数のフィルターを重ねる技と、カンマ(,)で区切って無効になる罠</p>

  <div class="filter-multi-demo-area">
    
    <div class="filter-multi-item">
      <p class="filter-multi-label">通常 (Normal)</p>
      <!-- 💡 変化が分かりやすい風景写真を使用 -->
      <img class="filter-multi-img" src="https://picsum.photos/id/1015/150/150" alt="通常">
    </div>

    <div class="filter-multi-item">
      <p class="filter-multi-label">単一(モノクロのみ)</p>
      <img class="filter-multi-img is-single" src="https://picsum.photos/id/1015/150/150" alt="単一">
    </div>

    <div class="filter-multi-item">
      <p class="filter-multi-label" style="color:#0d6efd;">⭕️ 複数指定(スペース区切り)<br><small>モノクロ + 暗く + 影</small></p>
      <img class="filter-multi-img is-multiple-success" src="https://picsum.photos/id/1015/150/150" alt="複数成功">
    </div>

    <div class="filter-multi-item">
      <p class="filter-multi-label" style="color:#dc3545;">❌ 複数指定の罠(カンマ区切り)<br><small>エラーになり無効化される</small></p>
      <img class="filter-multi-img is-multiple-fail" src="https://picsum.photos/id/1015/150/150" alt="複数失敗">
    </div>

  </div>

  <!-- 💡 エディタ画面風の解説エリア -->
  <div class="filter-multi-code-area">
    <span class="hl-comment">/* 💡 1つだけフィルターをかける場合 */</span><br>
    <span class="hl-blue">.img-single</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">grayscale(100%);</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 複数かける場合は「半角スペース」で繋ぐ! */</span><br>
    <span class="hl-blue">.img-multiple</span> {<br>
      <span class="hl-comment">/* 💡 モノクロにして、少し暗くして、影を落とす */</span><br>
      <span class="hl-green">filter:</span> <span class="hl-red">grayscale(80%) brightness(0.6) drop-shadow(6px 6px 8px rgba(0,0,0,0.6));</span><br>
    }<br><br>

    <span class="hl-comment">/* ❌ カンマで区切ってしまう */</span><br>
    <span class="hl-blue">.img-fail</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">grayscale(80%), brightness(0.6);</span> <span class="hl-comment">/* 🚨 構文エラー!フィルターが一切効かなくなる */</span><br>
    }
  </div>

</div>
CSSコード表示
.filter-multi-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.filter-multi-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.filter-multi-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  justify-content: center;
  align-items: flex-end;
  background-color: #e9ecef;
  padding: 40px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.filter-multi-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 150px;
}

.filter-multi-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 12px;
  line-height: 1.5;
}

/* 共通の画像サイズ */
.filter-multi-img {
  width: 130px;
  height: 130px;
  border-radius: 8px;
  object-fit: cover;
  background-color: #fff; /* 影を分かりやすくするため */
}

/* =💡 単一の指定= */
.is-single {
  filter: grayscale(100%);
}

/* =⭕️ 正しい複数の指定(スペース区切り)= */
.is-multiple-success {
  /* モノクロ80% + 暗くする + 影をつける */
  filter: grayscale(80%) brightness(0.6) drop-shadow(6px 6px 8px rgba(0,0,0,0.6));
}

/* =❌ 罠:間違った複数の指定(カンマ区切り)= */
.is-multiple-fail {
  /* カンマを入れるとCSSが無効になり、ただの通常画像になる */
  filter: grayscale(80%), brightness(0.6);
}

/* =コード解説エリア(エディタ風)= */
.filter-multi-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

transitionを使ったホバー時の滑らかなアニメーション

Webサイトをリッチに見せるテクニックが、画像にマウスカーソルを乗せたときに、ふわっと色鮮やかになったり、明るくなったりする表現です。

これを実現するには、filterプロパティとtransitionプロパティを組み合わせて、滑らかなアニメーションを作ります。

ホバーアニメーションを実装する際は、「transitionプロパティは、ホバーされる前の『通常状態』のセレクタに記述すること」です。

これにより、マウスを乗せた時も外した時も、両方向で滑らかなアニメーションが適用されます。

⭕️ ホバーアニメーションの鉄則!transitionを書く場所に注意せよ

❌ 罠(ホバー側に記述)
マウスを外すと「パッ」と戻って不自然

失敗ホバー

⭕️ 成功(ベース側に記述)
乗せても外しても「フワッ」と滑らか

成功ホバー
/* 💡 画像の初期状態(モノクロで少し暗い) */
.img-base {
  filter: grayscale(100%) brightness(0.8);
  /* ⭕️ transitionは「ベース(通常状態)」に書く! */
  transition: filter 0.5s ease; /* 💡 これで往復とも滑らかになる */
}

/* 💡 ホバー時の状態(カラーに戻して明るくする) */
.img-base:hover {
  filter: grayscale(0%) brightness(1.1);
}

/* ———————————————— */

/* ❌ ホバーされる側に transition を書いてしまう */
.img-fail:hover {
  filter: grayscale(0%) brightness(1.1);
  transition: filter 0.5s ease; /* 🚨 マウスを外した瞬間は適用されず、ガクッと戻る! */
}
HTMLコード表示
<div class="filter-hover-layout-wrapper">
  
  <p class="filter-hover-caption">⭕️ ホバーアニメーションの鉄則!transitionを書く場所に注意せよ</p>

  <div class="filter-hover-demo-area">
    
    <!-- ❌ 失敗:ホバー側にtransitionを書いた罠 -->
    <div class="filter-hover-item">
      <p class="filter-hover-label" style="color:#dc3545;">❌ 罠(ホバー側に記述)<br><small>マウスを外すと「パッ」と戻って不自然</small></p>
      
      <!-- 💡 変化が分かりやすい風景写真を使用 -->
      <img class="filter-hover-img is-hover-fail" src="https://picsum.photos/id/1018/200/200" alt="失敗ホバー">
    </div>

    <!-- ⭕️ 成功:ベース側にtransitionを書いた正しい実装 -->
    <div class="filter-hover-item">
      <p class="filter-hover-label" style="color:#0d6efd;">⭕️ 成功(ベース側に記述)<br><small>乗せても外しても「フワッ」と滑らか</small></p>
      
      <img class="filter-hover-img is-hover-success" src="https://picsum.photos/id/1018/200/200" alt="成功ホバー">
    </div>

  </div>

  <!-- 💡 エディタ画面風の解説エリア -->
  <div class="filter-hover-code-area">
    <span class="hl-comment">/* 💡 画像の初期状態(モノクロで少し暗い) */</span><br>
    <span class="hl-blue">.img-base</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">grayscale(100%) brightness(0.8);</span><br>
      <span class="hl-comment">/* ⭕️ transitionは「ベース(通常状態)」に書く! */</span><br>
      <span class="hl-green">transition:</span> <span class="hl-red">filter 0.5s ease;</span> <span class="hl-comment">/* 💡 これで往復とも滑らかになる */</span><br>
    }<br><br>

    <span class="hl-comment">/* 💡 ホバー時の状態(カラーに戻して明るくする) */</span><br>
    <span class="hl-blue">.img-base:hover</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">grayscale(0%) brightness(1.1);</span><br>
    }<br><br>

    <span class="hl-comment">/* ------------------------------------------------ */</span><br><br>

    <span class="hl-comment">/* ❌ ホバーされる側に transition を書いてしまう */</span><br>
    <span class="hl-blue">.img-fail:hover</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">grayscale(0%) brightness(1.1);</span><br>
      <span class="hl-green">transition:</span> <span class="hl-red">filter 0.5s ease;</span> <span class="hl-comment">/* 🚨 マウスを外した瞬間は適用されず、ガクッと戻る! */</span><br>
    }
  </div>

</div>
CSSコード表示
.filter-hover-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.filter-hover-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.filter-hover-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 40px;
  justify-content: center;
  align-items: flex-end;
  background-color: #e9ecef;
  padding: 40px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.filter-hover-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 220px;
}

.filter-hover-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  line-height: 1.5;
}

/* 共通の画像サイズ */
.filter-hover-img {
  width: 180px;
  height: 180px;
  border-radius: 50%;
  object-fit: cover;
  cursor: pointer;
  /* 初期状態はモノクロ&少し暗くしておく */
  filter: grayscale(100%) brightness(0.8);
}


/* =❌ 罠:ホバー側にtransitionを書いてしまった失敗例= */
/* ベースには何も書かない */
.is-hover-fail {
  /* transitionなし */
}

/* ホバー時にだけtransitionを適用してしまう */
.is-hover-fail:hover {
  filter: grayscale(0%) brightness(1.1) drop-shadow(0 8px 15px rgba(0,0,0,0.5));
  transition: all 0.5s ease; /* 🚨 ここに書くのがNG!外した時にガクッとなる */
}


/* =⭕️ 正しい実装:ベース側にtransitionを書く= */
.is-hover-success {
  transition: all 0.5s ease;
}

/* ホバー時は変化後のスタイルを指定するだけ */
.is-hover-success:hover {
  filter: grayscale(0%) brightness(1.1) drop-shadow(0 8px 15px rgba(0,0,0,0.5));
  /* 拡大のアニメーションなども追加するとリッチになります */
  transform: translateY(-5px);
}


/* =コード解説エリア(エディタ風)= */
.filter-hover-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

様々な要素のアニメーションの作り方やtransitionの使い方を詳しく知りたい人は以下から一読ください。

目的別:filter関数の種類と効果一覧

CSSのfilterプロパティには様々な関数が用意されており、目的によって使い分けることでデザインの幅が広がります。

最近では、ブラウザ上でフィルターの効果をリアルタイムに試せるツールも多数公開されていますが、実務でよく使われる実践的なパターンは限られています。

ここでは、実務で使用頻度の高いフィルター関数を「目的別」に分類し、それぞれの効果と仕様の違いを解説します。

目的別:filter関数の種類と効果一覧
  • 明るさとコントラスト
  • モノクロやセピア・色相反転
  • ぼかしとbox-shadowより便利なdrop-shadow

明るさとコントラスト

画像の明るさを調整するには、brightness()を使用します。

1(または100%)を基準とし、0.5にすれば暗く、1.5にすれば明るくなります。

また、画像の色味のメリハリを調整するには、contrast()を使用します。

こちらも1を基準とし、数値を上げるほどくっきりと、下げるとのっぺりとした色合いになります。

背景画像をシンプルに黒っぽく沈めて文字を目立たせたい場合は、opacityではなくfilter: brightness(0.5);を使うことです。

これにより、背景が透けることなく画像の明度だけを下げられます。

⭕️ 明るさ(brightness)とコントラスト(contrast)の比較

通常 (Normal)

通常

brightness(0.5)
暗くする

暗く

brightness(1.5)
明るくする

明るく

contrast(200%)
メリハリを強く

コントラスト強
/* 💡 画像を暗くする(背景を透かさずに黒く沈める) */
.img-darken {
  filter: brightness(0.5); /* 0.5 または 50% */
}

/* 💡 画像を明るくする */
.img-lighten {
  filter: brightness(1.5); /* 1.5 または 150% */
}

/* 💡 画像の明暗差(コントラスト)を強める */
.img-contrast {
  filter: contrast(200%);
}
HTMLコード表示
<div class="filter-type-wrapper">
  
  <p class="filter-type-caption">⭕️ 明るさ(brightness)とコントラスト(contrast)の比較</p>

  <div class="filter-type-demo-area">
    
    <div class="filter-type-item">
      <p class="filter-type-label">通常 (Normal)</p>
      <img class="filter-type-img" src="https://picsum.photos/id/1016/150/150" alt="通常">
    </div>

    <!-- 💡 brightnessの比較 -->
    <div class="filter-type-item">
      <p class="filter-type-label">brightness(0.5)<br><small>暗くする</small></p>
      <img class="filter-type-img is-darken" src="https://picsum.photos/id/1016/150/150" alt="暗く">
    </div>

    <div class="filter-type-item">
      <p class="filter-type-label">brightness(1.5)<br><small>明るくする</small></p>
      <img class="filter-type-img is-lighten" src="https://picsum.photos/id/1016/150/150" alt="明るく">
    </div>

    <!-- 💡 contrastの比較 -->
    <div class="filter-type-item">
      <p class="filter-type-label">contrast(200%)<br><small>メリハリを強く</small></p>
      <img class="filter-type-img is-contrast-high" src="https://picsum.photos/id/1016/150/150" alt="コントラスト強">
    </div>

  </div>

  <div class="filter-type-code-area">
    <span class="hl-comment">/* 💡 画像を暗くする(背景を透かさずに黒く沈める) */</span><br>
    <span class="hl-blue">.img-darken</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">brightness(0.5);</span> <span class="hl-comment">/* 0.5 または 50% */</span><br>
    }<br><br>

    <span class="hl-comment">/* 💡 画像を明るくする */</span><br>
    <span class="hl-blue">.img-lighten</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">brightness(1.5);</span> <span class="hl-comment">/* 1.5 または 150% */</span><br>
    }<br><br>

    <span class="hl-comment">/* 💡 画像の明暗差(コントラスト)を強める */</span><br>
    <span class="hl-blue">.img-contrast</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">contrast(200%);</span><br>
    }
  </div>

</div>
CSSコード表示
.filter-type-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.filter-type-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.filter-type-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: center;
  align-items: flex-end;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.filter-type-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 140px;
}

.filter-type-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 12px;
  line-height: 1.5;
  height: 40px;
}

.filter-type-img {
  width: 130px;
  height: 130px;
  border-radius: 8px;
  object-fit: cover;
}

/* =💡 実践コード:明るさとコントラスト= */
.is-darken {
  filter: brightness(0.5);
}

.is-lighten {
  filter: brightness(1.5);
}

.is-contrast-high {
  filter: contrast(200%);
}

/* =コード解説エリア= */
.filter-type-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

モノクロやセピア・色相反転

画像の色を大きく変化させるフィルターも豊富です。

白黒写真にするgrayscale()、ノスタルジックなsepia()、写真のネガのように色を反転させるinvert()、色相環を回転させて色味をずらすhue-rotate()があります。

ダークモード対応などで「白背景用の黒いロゴ」を「黒背景用の白いロゴ」に変換したい場合、filter: invert(1);を使います。

画像を作り直すことなく、CSS1行で白黒を反転できるテクニックです。

⭕️ 画像の色を操るフィルターと、ロゴを白黒反転させる「invert」の魔法

通常 (Normal)

通常

grayscale(1)
モノクロ化

モノクロ

sepia(1)
セピア調

セピア

hue-rotate(90deg)
色相を回す

色相回転

invert(1)
黒い画像を白く反転

/* 💡 写真をモノクロにする */
.img-gray {
  filter: grayscale(100%);
}

/* ⭕️ 黒いロゴ画像(SVGやPNG)を、ダークモード用に白く反転させる */
.logo-invert {
  filter: invert(100%); /* 💡 黒が白になり、白が黒になる! */
}
HTMLコード表示
<div class="filter-color-layout-wrapper">
  
  <p class="filter-color-caption">⭕️ 画像の色を操るフィルターと、ロゴを白黒反転させる「invert」の魔法</p>

  <div class="filter-color-demo-area">
    
    <div class="filter-color-item">
      <p class="filter-color-label">通常 (Normal)</p>
      <img class="filter-color-img" src="https://picsum.photos/id/1025/120/120" alt="通常">
    </div>

    <div class="filter-color-item">
      <p class="filter-color-label">grayscale(1)<br><small>モノクロ化</small></p>
      <img class="filter-color-img is-grayscale" src="https://picsum.photos/id/1025/120/120" alt="モノクロ">
    </div>

    <div class="filter-color-item">
      <p class="filter-color-label">sepia(1)<br><small>セピア調</small></p>
      <img class="filter-color-img is-sepia" src="https://picsum.photos/id/1025/120/120" alt="セピア">
    </div>

    <div class="filter-color-item">
      <p class="filter-color-label">hue-rotate(90deg)<br><small>色相を回す</small></p>
      <img class="filter-color-img is-hue" src="https://picsum.photos/id/1025/120/120" alt="色相回転">
    </div>

    <!-- 💡 黒いアイコンを invert で白くするデモ -->
    <div class="filter-color-item" style="background-color: #333; padding: 10px; border-radius: 8px;">
      <p class="filter-color-label" style="color: #fff;">invert(1)<br><small>黒い画像を白く反転</small></p>
      <!-- 透過の黒いアイコン画像の代わり(テキストを含む要素) -->
      <div class="filter-color-icon is-invert-demo">★</div>
    </div>

  </div>

  <div class="filter-color-code-area">
    <span class="hl-comment">/* 💡 写真をモノクロにする */</span><br>
    <span class="hl-blue">.img-gray</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">grayscale(100%);</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 黒いロゴ画像(SVGやPNG)を、ダークモード用に白く反転させる */</span><br>
    <span class="hl-blue">.logo-invert</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">invert(100%);</span> <span class="hl-comment">/* 💡 黒が白になり、白が黒になる! */</span><br>
    }
  </div>

</div>
CSSコード表示
.filter-color-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.filter-color-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.filter-color-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: center;
  align-items: flex-end;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.filter-color-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 130px;
}

.filter-color-label {
  font-size: 12px;
  font-weight: bold;
  color: #333;
  margin-bottom: 12px;
  line-height: 1.5;
  height: 36px;
}

.filter-color-img {
  width: 100px;
  height: 100px;
  border-radius: 8px;
  object-fit: cover;
}

/* アイコン代わりの要素(黒色) */
.filter-color-icon {
  font-size: 60px;
  color: black; /* 元は真っ黒 */
  line-height: 100px;
}

/* =💡 実践コード:色の操作= */
.is-grayscale {
  filter: grayscale(100%);
}

.is-sepia {
  filter: sepia(100%);
}

.is-hue {
  filter: hue-rotate(90deg); /* 角度で指定 */
}

/* =⭕️ 白黒反転= */
.is-invert-demo {
  filter: invert(100%); /* 💡 ここで黒い星が「白い星」に反転する */
}

/* =コード解説エリア= */
.filter-color-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
}

ぼかしとbox-shadowより便利なdrop-shadow

画像をぼかすblur()と並んで実務で使われるのが、影をつけるdrop-shadow()です。

透過画像やSVG、複雑な形をした要素の「形そのもの」に沿って影を落としたい場合はfilter: drop-shadow()を使用するのがよいです。

また、影のぼかしを0にして、上下左右に複数のdrop-shadowを重ね掛けすることで画像の周囲を縁取るアウトライン効果を自作するテクニックも存在します。

⭕️ 透過画像に影をつけるなら、box-shadow ではなく drop-shadow を使え!

❌ box-shadow の罠
(画像の枠・四角に影がつく)

🍎

⭕️ drop-shadow 指定
(りんごの形に沿って影がつく)

🍎
/* ❌ 透過画像に対して box-shadow を使ってしまう */
.fail-shadow {
  box-shadow: 5px 5px 10px rgba(0,0,0,0.5); /* 🚨 画像を囲む四角い枠に影がついてしまう */
}

/* ⭕️ 透過画像の「形」に沿って影を落とすなら drop-shadow! */
.success-shadow {
  filter: drop-shadow(5px 5px 10px rgba(0,0,0,0.5)); /* 💡 形にぴったり沿った美しい影になる */
}
HTMLコード表示
<div class="filter-shadow-layout-wrapper">
  
  <p class="filter-shadow-caption">⭕️ 透過画像に影をつけるなら、box-shadow ではなく drop-shadow を使え!</p>

  <div class="filter-shadow-demo-area">
    
    <!-- ❌ 失敗:box-shadow は四角い箱に影がつく -->
    <div class="filter-shadow-item">
      <p class="filter-shadow-label" style="color:#dc3545;">❌ box-shadow の罠<br><small>(画像の枠・四角に影がつく)</small></p>
      
      <!-- 💡 透過要素をシミュレート(絵文字) -->
      <div class="filter-shadow-emoji is-box-shadow">🍎</div>
    </div>

    <!-- ⭕️ 成功:drop-shadow は要素の形に沿って影がつく -->
    <div class="filter-shadow-item">
      <p class="filter-shadow-label" style="color:#0d6efd;">⭕️ drop-shadow 指定<br><small>(りんごの形に沿って影がつく)</small></p>
      
      <div class="filter-shadow-emoji is-drop-shadow">🍎</div>
    </div>

  </div>

  <div class="filter-shadow-code-area">
    <span class="hl-comment">/* ❌ 透過画像に対して box-shadow を使ってしまう */</span><br>
    <span class="hl-blue">.fail-shadow</span> {<br>
      <span class="hl-green">box-shadow:</span> <span class="hl-red">5px 5px 10px rgba(0,0,0,0.5);</span> <span class="hl-comment">/* 🚨 画像を囲む四角い枠に影がついてしまう */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 透過画像の「形」に沿って影を落とすなら drop-shadow! */</span><br>
    <span class="hl-blue">.success-shadow</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">drop-shadow(5px 5px 10px rgba(0,0,0,0.5));</span> <span class="hl-comment">/* 💡 形にぴったり沿った美しい影になる */</span><br>
    }
  </div>

</div>
CSSコード表示
.filter-shadow-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.filter-shadow-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.filter-shadow-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 50px;
  justify-content: center;
  align-items: flex-end;
  background-color: #e9ecef;
  padding: 40px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.filter-shadow-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 200px;
}

.filter-shadow-label {
  font-size: 13px;
  font-weight: bold;
  margin-bottom: 20px;
  line-height: 1.5;
  height: 40px;
}

/* 透過画像を想定した絵文字コンテナ */
.filter-shadow-emoji {
  font-size: 80px;
  line-height: 1;
}

/* =❌ 罠:box-shadowを使用= */
.is-box-shadow {
  box-shadow: 10px 10px 15px rgba(0, 0, 0, 0.4);
  /* 絵文字という「四角いブロック」に対して影がついてしまう */
}

/* =⭕️ 正解:drop-shadowを使用= */
.is-drop-shadow {
  filter: drop-shadow(10px 10px 15px rgba(0, 0, 0, 0.4));
  /* 絵文字(りんご)の形に沿って影がつく */
}

/* =コード解説エリア= */
.filter-shadow-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
}

特定要素全体に影を落とすbox-shadowプロパティの使い方を詳しく知りたい人は「【CSS】box-shadowの使い方:おしゃれな影のコピペ集と浮遊感の作り方」を一読ください。

SVGや画像を特定の色に変える

Webサイトの制作現場でよくある要望が「ボタンにホバーした時に、中にあるアイコンの色を変えたい」というものです。

画像やSVGのピクセルカラーを直接変える方法を覚えれば、画像ファイルの読み込みを減らしてサイトのパフォーマンスを向上させられます。

特に<img>タグで読み込んだSVGの色変更において、フィルターの知識は欠かせません。

SVGや画像を特定の色に変える
  • 黒いアイコンを白にする:invertbrightnessの活用

黒いアイコンを白にする:invertとbrightnessの活用

アイコンの色変更で頻出するのが「黒や暗い色のアイコンを真っ白にする」という処理です。

ダークモードの対応やホバー時にボタンの背景色が濃い色に変わる際など、実務で直面します。

画像を白くするには、階調を反転させるinvert()関数が活躍します。

元の画像が「真っ黒(#000000)」であれば、invert(100%)を指定するだけで白に反転します。

逆に、白いアイコンを黒くする場合も、同じくinvert(100%)で対応可能です。

どんな色の画像でも「白」にするには、filter: brightness(0) invert(100%);を使うことです。

まずbrightness(0)で画像の明るさをゼロにして「黒(#000000)」にし、直後にinvert(100%)で反転させることで、元の色が何色であろうと「白」を作り出せます。

⭕️ 元が何色でも確実!「brightness(0)」+「invert(100%)」の最強コンボ

元画像
(青っぽい色)

元画像

❌ 失敗
(invertだけ)

失敗

⭕️ 成功
(最強コンボ)

成功
/* ❌ 色がついている画像に invert だけをかける */
.img-fail {
  filter: invert(100%); /* 🚨 黒以外の画像だと真っ白にならず、変な色になる! */
}

/* ⭕️ 強制的に黒くしてから白に反転させる */
.img-success {
  filter: brightness(0) invert(100%); /* 💡 これでどんな画像も確実に純白になる! */
}
HTMLコード表示
<div class="filter-white-layout-wrapper">
  
  <p class="filter-white-caption">⭕️ 元が何色でも確実!「brightness(0)」+「invert(100%)」の最強コンボ</p>

  <div class="filter-white-demo-area">
    
    <div class="filter-white-item">
      <p class="filter-white-label">元画像<br><small>(青っぽい色)</small></p>
      <!-- 💡 安全にエンコードされた青色の星アイコン -->
      <img class="filter-white-img" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23336699'%3E%3Cpath d='M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/%3E%3C/svg%3E" alt="元画像">
    </div>

    <div class="filter-white-item">
      <p class="filter-white-label" style="color:#dc3545;">❌ 失敗<br><small>(invertだけ)</small></p>
      <!-- 💡 反転しただけなので、黄色っぽくなってしまう -->
      <img class="filter-white-img is-invert-fail" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23336699'%3E%3Cpath d='M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/%3E%3C/svg%3E" alt="失敗">
    </div>

    <div class="filter-white-item">
      <p class="filter-white-label" style="color:#0d6efd;">⭕️ 成功<br><small>(最強コンボ)</small></p>
      <!-- 💡 確実に真っ白になる! -->
      <img class="filter-white-img is-white-success" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23336699'%3E%3Cpath d='M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/%3E%3C/svg%3E" alt="成功">
    </div>

  </div>

  <!-- 💡 エディタ画面風の解説エリア -->
  <div class="filter-white-code-area">
    <span class="hl-comment">/* ❌ 色がついている画像に invert だけをかける */</span><br>
    <span class="hl-blue">.img-fail</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">invert(100%);</span> <span class="hl-comment">/* 🚨 黒以外の画像だと真っ白にならず、変な色になる! */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 強制的に黒くしてから白に反転させる */</span><br>
    <span class="hl-blue">.img-success</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">brightness(0) invert(100%);</span> <span class="hl-comment">/* 💡 これでどんな画像も確実に純白になる! */</span><br>
    }
  </div>

</div>
CSSコード表示
.filter-white-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.filter-white-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.filter-white-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  justify-content: center;
  align-items: flex-end;
  /* 白いアイコンが見えるように背景を少し暗く設定 */
  background-color: #343a40; 
  padding: 40px 20px;
  border-radius: 8px;
  margin-bottom: 20px;
}

.filter-white-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 140px;
}

.filter-white-label {
  font-size: 13px;
  font-weight: bold;
  color: #f8f9fa; /* 背景が暗いので文字を明るく */
  margin-bottom: 15px;
  line-height: 1.5;
  height: 40px;
}

.filter-white-img {
  width: 80px;
  height: 80px;
}

/* =❌ 罠:invertだけ(変な色になる)= */
.is-invert-fail {
  filter: invert(100%);
}

/* =⭕️ 正解:確実に真っ白にする最強コンボ= */
.is-white-success {
  filter: brightness(0) invert(100%);
}

/* =コード解説エリア(エディタ風)= */
.filter-white-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

背景だけぼかす:backdrop-filterの使い方と違い

Webデザインで人気の高い「すりガラス(グラスモーフィズム)」のような表現があります。

背景の画像はぼかしつつ、手前のテキストはくっきりと読ませたい場面は多々あります。

ここでは、要素の「後ろ側」にだけフィルター効果を適用できるbackdrop-filterの使い方と実務で直面するSafari特有の罠について解説します。

背景だけぼかす:backdrop-filterの使い方と違い
  • 要素の後ろだけを加工するガラス風デザイン
  • Safariで効かない!ベンダープレフィックスと解決策

要素の後ろだけを加工するガラス風デザイン

要素自体に加工を施すのがfilterなら、要素の「背後」にだけ加工を施すのがbackdrop-filterです。

このプロパティを使えば、中のテキストには影響を与えず、要素の背景だけをぼかしたり、色調を変えたりすることができます。

最近では、直感的にすりガラス風のCSSを生成してくれるツールも豊富に存在し、UIデザインにおいて欠かせないテクニックとなっています。

backdrop-filterを効かせるには、「要素のbackground-colorには、rgba()transparentなどの半透明な色を指定すること」です。

背景の透明度(アルファ値)を0.30.7程度に設定することですりガラス効果を表現できます。

⭕️ 要素の中身ごとぼかす「filter」と、背景だけぼかす「backdrop-filter」

❌ filter の罠

テキストも
ボケて読めない!

⭕️ backdrop-filter

背景だけボケて
文字はくっきり!

/* ❌ 通常の filter で背景をぼかそうとする */
.box-fail {
  background-color: rgba(255, 255, 255, 0.4);
  filter: blur(5px); /* 🚨 中の文字まで全部ボケる! */
}

/* ⭕️ 半透明の背景色 + backdrop-filter */
.box-success {
  background-color: rgba(255, 255, 255, 0.4); /* 💡 必須:半透明にして後ろを透かす */
  backdrop-filter: blur(5px); /* 💡 要素の後ろ側だけにフィルターをかける! */
}
HTMLコード表示
<div class="backdrop-layout-wrapper">
  
  <p class="backdrop-caption">⭕️ 要素の中身ごとぼかす「filter」と、背景だけぼかす「backdrop-filter」</p>

  <div class="backdrop-demo-area">
    
    <!-- ❌ 失敗:通常のfilterを使うと文字までボケる -->
    <div class="backdrop-item">
      <p class="backdrop-label" style="color:#dc3545; background: rgba(255,255,255,0.8); padding: 5px; border-radius: 4px;">❌ filter の罠</p>
      
      <div class="backdrop-box is-bad-filter">
        <p>テキストも<br>ボケて読めない!</p>
      </div>
    </div>

    <!-- ⭕️ 成功:backdrop-filterで美しいすりガラス -->
    <div class="backdrop-item">
      <p class="backdrop-label" style="color:#0d6efd; background: rgba(255,255,255,0.8); padding: 5px; border-radius: 4px;">⭕️ backdrop-filter</p>
      
      <div class="backdrop-box is-good-backdrop">
        <p>背景だけボケて<br>文字はくっきり!</p>
      </div>
    </div>

  </div>

  <!-- 💡 エディタ画面風の解説エリア -->
  <div class="backdrop-code-area">
    <span class="hl-comment">/* ❌ 通常の filter で背景をぼかそうとする */</span><br>
    <span class="hl-blue">.box-fail</span> {<br>
      <span class="hl-green">background-color:</span> <span class="hl-red">rgba(255, 255, 255, 0.4);</span><br>
      <span class="hl-green">filter:</span> <span class="hl-red">blur(5px);</span> <span class="hl-comment">/* 🚨 中の文字まで全部ボケる! */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 半透明の背景色 + backdrop-filter */</span><br>
    <span class="hl-blue">.box-success</span> {<br>
      <span class="hl-green">background-color:</span> <span class="hl-red">rgba(255, 255, 255, 0.4);</span> <span class="hl-comment">/* 💡 必須:半透明にして後ろを透かす */</span><br>
      <span class="hl-green">backdrop-filter:</span> <span class="hl-red">blur(5px);</span> <span class="hl-comment">/* 💡 要素の後ろ側だけにフィルターをかける! */</span><br>
    }
  </div>

</div>
CSSコード表示
.backdrop-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.backdrop-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

/* 変化が分かりやすいように、背景にカラフルな画像を設定 */
.backdrop-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 40px;
  justify-content: center;
  align-items: center;
  background-image: url('https://picsum.photos/id/1043/800/400');
  background-size: cover;
  background-position: center;
  padding: 50px 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  box-shadow: inset 0 0 0 2000px rgba(0,0,0,0.2); /* 少しだけ背景を暗く */
}

.backdrop-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 200px;
}

.backdrop-label {
  font-size: 13px;
  font-weight: bold;
  margin-bottom: 15px;
  line-height: 1.5;
}

/* 共通のボックス形状 */
.backdrop-box {
  width: 100%;
  height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.5); /* ガラスのフチを表現 */
  color: #333;
  font-weight: bold;
  font-size: 14px;
  line-height: 1.5;
}

/* =❌ 罠:通常のfilterを使用(文字もボケる)= */
.is-bad-filter {
  background-color: rgba(255, 255, 255, 0.5);
  filter: blur(4px);
}

/* =⭕️ 正解:backdrop-filterを使用(背景だけボケる)= */
.is-good-backdrop {
  background-color: rgba(255, 255, 255, 0.5); /* 💡 半透明にするのが鉄則 */
  backdrop-filter: blur(8px); /* 💡 後ろの風景だけがボケる */
  -webkit-backdrop-filter: blur(8px); /* Safari対応(次項で解説) */
  color: #000;
  text-shadow: 1px 1px 2px rgba(255,255,255,0.8); /* 文字をさらに読みやすく */
}

/* =コード解説エリア(エディタ風)= */
.backdrop-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

Safariで効かない!ベンダープレフィックスと解決策

「半透明の背景色も設定したし、文法も間違っていないのにスマホで確認したら効いていない!」とパニックになることがあります。

実はbackdrop-filterは、iOSのSafariや古いバージョンのmacOS Safariにおいて、記述しただけではブラウザに認識されず、半透明の箱になるという落とし穴があります。

Safariでbackdrop-filterを動作させるには、「-webkit-backdrop-filterというベンダープレフィックス(Safari専用の接頭辞)を標準のプロパティの【前】に記述すること」です。

Autoprefixerなどの自動付与ツールを使っている場合は問題ありませんが、手書きでCSSを書く場合はこの1行を忘れるとiPhoneでデザインが破綻するため、セットで記述する癖をつけましょう。

⭕️ Safari対策は必須!「-webkit-」を忘れずにつけて、綺麗なヘッダーを作ろう

下にスクロールする風景を想定

My Portfolio (Safari対応済)
/* ⭕️ iPhone(Safari)対策として、必ず -webkit- を併記する! */
.glass-header {
  background-color: rgba(255, 255, 255, 0.6);
  /* 💡 標準プロパティの【前】に、-webkit- 版を書くのがルール */
  -webkit-backdrop-filter: blur(10px); /* 🚨 Safari・iOS用 */
  backdrop-filter: blur(10px); /* 💡 Chrome・Edge・標準用 */
}
HTMLコード表示
<div class="backdrop-layout-wrapper">
  
  <p class="backdrop-caption">⭕️ Safari対策は必須!「-webkit-」を忘れずにつけて、綺麗なヘッダーを作ろう</p>

  <div class="backdrop-safari-demo-area">
    
    <!-- 💡 スクロールされる背景のダミーコンテンツ -->
    <div class="backdrop-safari-content">
      <div class="backdrop-safari-circle" style="top: 20px; left: 20px; background: #dc3545;"></div>
      <div class="backdrop-safari-circle" style="top: 60px; right: 30px; background: #0d6efd;"></div>
      <div class="backdrop-safari-circle" style="top: 100px; left: 50%; background: #198754;"></div>
      <p style="padding-top: 100px; color: #fff; font-weight: bold; text-align: center;">下にスクロールする風景を想定</p>
    </div>

    <!-- ⭕️ 成功:ベンダープレフィックスをつけた固定ヘッダー -->
    <div class="backdrop-header is-safari-safe">
      <span>My Portfolio</span>
      <span style="font-size: 11px;">(Safari対応済)</span>
    </div>

  </div>

  <!-- 💡 エディタ画面風の解説エリア -->
  <div class="backdrop-code-area">
    <span class="hl-comment">/* ⭕️ iPhone(Safari)対策として、必ず -webkit- を併記する! */</span><br>
    <span class="hl-blue">.glass-header</span> {<br>
      <span class="hl-green">background-color:</span> <span class="hl-red">rgba(255, 255, 255, 0.6);</span><br>
      <span class="hl-comment">/* 💡 標準プロパティの【前】に、-webkit- 版を書くのがルール */</span><br>
      <span class="hl-green">-webkit-backdrop-filter:</span> <span class="hl-red">blur(10px);</span> <span class="hl-comment">/* 🚨 Safari・iOS用 */</span><br>
      <span class="hl-green">backdrop-filter:</span> <span class="hl-red">blur(10px);</span>       <span class="hl-comment">/* 💡 Chrome・Edge・標準用 */</span><br>
    }
  </div>

</div>
CSSコード表示
.backdrop-safari-demo-area {
  position: relative;
  width: 100%;
  max-width: 400px;
  height: 200px;
  margin: 0 auto 20px auto;
  background-color: #212529;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #adb5bd;
}

/* ダミーの背景要素(これらがヘッダーの後ろを透けて通る) */
.backdrop-safari-content {
  position: absolute;
  width: 100%;
  height: 100%;
}

.backdrop-safari-circle {
  position: absolute;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  opacity: 0.8;
}

/* =⭕️ 正解:Safari対応済みのすりガラスヘッダー= */
.backdrop-header {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  box-sizing: border-box;
  font-weight: bold;
  color: #333;
  border-bottom: 1px solid rgba(255,255,255,0.3);
}

.is-safari-safe {
  background-color: rgba(255, 255, 255, 0.7); /* 💡 半透明の背景 */
  
  /* 💡 ここが超重要!Safari用のベンダープレフィックス */
  -webkit-backdrop-filter: blur(15px); 
  /* 💡 モダンブラウザ用の標準プロパティ */
  backdrop-filter: blur(15px); 
}

filterのトラブル解決!効かない原因と重なり問題

CSSのfilterプロパティは便利な反面、ブラウザのレンダリングの仕組みに深く関わるため、予期せぬ副作用を引き起こすことがあります。

「コードは合っているはずなのにfilterが効かない」と悩む場合、文法ミスだけでなく、ブラウザの仕様である「重なり」や「ぼかしのレンダリング仕様」の罠にハマっている可能性が高いです。

ここでは、filter特有のトラブルと解決策・パフォーマンス対策を解説します。

filterのトラブル解決!効かない原因と重なり問題
  • z-indexがおかしくなる仕様
  • ぼかしの端が白くなる問題とパフォーマンス低下への対策

z-indexがおかしくなる仕様

filterプロパティを使用する際、知っておかなければならないブラウザの仕様があります。

それは、要素にfilterを適用すると、要素に新しいスタッキングコンテキストが生成されるという点です。

これにより、内部の要素のz-indexが狂ってしまうという現象が起きます。

レイアウト崩れを防ぐには、filterは大枠の親要素にはかけず、影響を与えたい画像や背景用の疑似要素だけにピンポイントでかけることです。

スタッキングコンテキストの罠を避けるため、複雑な子要素を持つラッパー要素にはfilterを使用してはいけません。

⭕️ 親に filter をかけると z-index: 9999 でも下に潜る悲劇!

❌ 罠(親にfilter指定)
青い箱が下敷きになる

親要素 (filterあり)
z-index: 9999
後続の要素

⭕️ 成功(親はそのまま)
青い箱が正しく上にくる

親要素 (filterなし)
z-index: 9999
後続の要素
/* ❌ 親要素に直接 filter をかけてしまう */
.parent-fail {
  filter: brightness(0.9); /* 🚨 ここでスタッキングコンテキストが発生! */
}

/* 💡 子要素でいくら z-index を高くしても無駄になる */
.parent-fail .child {
  z-index: 9999; /* 🚨 親の「箱」の中で一番上になるだけで、外の要素には負ける */
}
HTMLコード表示
<div class="filter-zindex-layout-wrapper">
  
  <p class="filter-zindex-caption">⭕️ 親に filter をかけると z-index: 9999 でも下に潜る悲劇!</p>

  <div class="filter-zindex-demo-area">
    
    <!-- ❌ 失敗:親要素にfilterがかかっているため、子要素のz-indexが機能しない -->
    <div class="filter-zindex-item">
      <p class="filter-zindex-label" style="color:#dc3545;">❌ 罠(親にfilter指定)<br><small>青い箱が下敷きになる</small></p>
      
      <div class="zindex-parent is-filtered-parent">
        親要素 (filterあり)
        <div class="zindex-child is-high-z">
          z-index: 9999
        </div>
      </div>
      
      <!-- 比較用の後続要素 -->
      <div class="zindex-sibling">
        後続の要素
      </div>
    </div>

    <!-- ⭕️ 成功:親にはfilterをかけず、影響がないようにする -->
    <div class="filter-zindex-item">
      <p class="filter-zindex-label" style="color:#0d6efd;">⭕️ 成功(親はそのまま)<br><small>青い箱が正しく上にくる</small></p>
      
      <div class="zindex-parent">
        親要素 (filterなし)
        <div class="zindex-child is-high-z">
          z-index: 9999
        </div>
      </div>
      
      <!-- 比較用の後続要素 -->
      <div class="zindex-sibling">
        後続の要素
      </div>
    </div>

  </div>

  <div class="filter-zindex-code-area">
    <span class="hl-comment">/* ❌ 親要素に直接 filter をかけてしまう */</span><br>
    <span class="hl-blue">.parent-fail</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">brightness(0.9);</span> <span class="hl-comment">/* 🚨 ここでスタッキングコンテキストが発生! */</span><br>
    }<br><br>

    <span class="hl-comment">/* 💡 子要素でいくら z-index を高くしても無駄になる */</span><br>
    <span class="hl-blue">.parent-fail .child</span> {<br>
      <span class="hl-green">z-index:</span> <span class="hl-red">9999;</span> <span class="hl-comment">/* 🚨 親の「箱」の中で一番上になるだけで、外の要素には負ける */</span><br>
    }
  </div>

</div>
CSSコード表示
.filter-zindex-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.filter-zindex-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.filter-zindex-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 40px;
  justify-content: center;
  align-items: flex-start;
  background-color: #e9ecef;
  padding: 40px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.filter-zindex-item {
  display: flex;
  flex-direction: column;
  width: 200px;
  position: relative;
}

.filter-zindex-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  text-align: center;
  line-height: 1.5;
}

/* 親要素のベース */
.zindex-parent {
  background-color: #adb5bd;
  padding: 20px;
  border-radius: 6px;
  position: relative;
  text-align: center;
  font-size: 12px;
  font-weight: bold;
  color: white;
}

/* 子要素(高いz-indexを持つ) */
.zindex-child {
  position: absolute;
  top: 40px;
  left: 20px;
  width: 160px;
  height: 50px;
  background-color: #0d6efd;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  box-shadow: 0 4px 6px rgba(0,0,0,0.3);
}

/* 後続の兄弟要素 */
.zindex-sibling {
  position: relative;
  margin-top: -10px; /* あえて重ねる */
  background-color: #ffc107;
  padding: 30px 20px;
  border-radius: 6px;
  text-align: center;
  font-size: 12px;
  font-weight: bold;
  color: #333;
  z-index: 10; /* 通常のz-index */
}

/* =❌ 罠:親にfilterがかかっている= */
.is-filtered-parent {
  filter: brightness(0.9); /* 🚨 ここが元凶! */
}

/* 子要素のz-index */
.is-high-z {
  z-index: 9999;
}

/* =コード解説エリア(エディタ風)= */
.filter-zindex-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

ぼかしの端が白くなる問題とパフォーマンス低下への対策

filterの中でも使用頻度が高いblur()ですが、画像をぼかした際に「画像の端が白く透けてしまう」という特有の問題が発生します。

これは、画像の外側の「透明な領域」まで計算に巻き込んでぼかし処理を行ってしまうブラウザの仕様です。

さらに、大きなぼかしや複雑なdrop-shadowは、ブラウザの描画負荷を極端に高めます。

特にスマホ端末において、スクロール時に画面がカクついたり、アニメーションがコマ落ちしたりする原因のトップがfilterの乱用です。

  1. 白いフチを消す
    親要素にoverflow: hidden;を指定した上で、ぼかした画像自体をtransform: scale(1.05);で少しだけ拡大して、白く透けた端の部分を枠外に追い出してトリミングします。
  2. パフォーマンス対策
    filterプロパティをtransitionanimationで動かすのは最終手段です。
    ぼかした画像と通常の画像を2枚重ねておき、上の画像のopacityをアニメーションさせて切り替えるのがブラウザに負担をかけない手法です。

⭕️ ぼかしの「端が白くなる問題」は、拡大(scale)と切り抜きで解決!

❌ 罠(そのまま blur)
画像の端が白くフェードする

失敗ぼかし

⭕️ 成功(scale + overflow)
端の白ボケが隠れて美しい

成功ぼかし
/* ❌ そのまま blur() をかけるとフチが透ける */
.img-fail {
  filter: blur(10px);
}

/* ⭕️ 親枠で隠し、画像を少し拡大して白ボケ部分を追い出す! */
.img-wrapper {
  overflow: hidden; /* 💡 はみ出た部分をカットする */
}
.img-success {
  filter: blur(10px);
  transform: scale(1.1); /* 💡 画像を1.1倍に拡大して、白い端を枠外へ捨てる */
}
HTMLコード表示
<div class="filter-blur-layout-wrapper">
  
  <p class="filter-blur-caption">⭕️ ぼかしの「端が白くなる問題」は、拡大(scale)と切り抜きで解決!</p>

  <div class="filter-blur-demo-area">
    
    <!-- ❌ 失敗:ただ blur をかけただけだと端が透ける -->
    <div class="filter-blur-item">
      <p class="filter-blur-label" style="color:#dc3545;">❌ 罠(そのまま blur)<br><small>画像の端が白くフェードする</small></p>
      
      <!-- 親要素に背景色(黒)を入れて透けを分かりやすくする -->
      <div class="blur-container" style="background-color: #000;">
        <img class="blur-img is-bad-blur" src="https://picsum.photos/id/1018/200/200" alt="失敗ぼかし">
      </div>
    </div>

    <!-- ⭕️ 成功:scale で拡大してはみ出させる -->
    <div class="filter-blur-item">
      <p class="filter-blur-label" style="color:#0d6efd;">⭕️ 成功(scale + overflow)<br><small>端の白ボケが隠れて美しい</small></p>
      
      <div class="blur-container is-overflow-hidden">
        <img class="blur-img is-good-blur" src="https://picsum.photos/id/1018/200/200" alt="成功ぼかし">
      </div>
    </div>

  </div>

  <div class="filter-blur-code-area">
    <span class="hl-comment">/* ❌ そのまま blur() をかけるとフチが透ける */</span><br>
    <span class="hl-blue">.img-fail</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">blur(10px);</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 親枠で隠し、画像を少し拡大して白ボケ部分を追い出す! */</span><br>
    <span class="hl-blue">.img-wrapper</span> {<br>
      <span class="hl-green">overflow:</span> <span class="hl-red">hidden;</span> <span class="hl-comment">/* 💡 はみ出た部分をカットする */</span><br>
    }<br>
    <span class="hl-blue">.img-success</span> {<br>
      <span class="hl-green">filter:</span> <span class="hl-red">blur(10px);</span><br>
      <span class="hl-green">transform:</span> <span class="hl-red">scale(1.1);</span> <span class="hl-comment">/* 💡 画像を1.1倍に拡大して、白い端を枠外へ捨てる */</span><br>
    }
  </div>

</div>
CSSコード表示
.filter-blur-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.filter-blur-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.filter-blur-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 40px;
  justify-content: center;
  align-items: flex-start;
  background-color: #e9ecef;
  padding: 40px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.filter-blur-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 200px;
}

.filter-blur-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  line-height: 1.5;
}

/* 共通の画像コンテナ */
.blur-container {
  width: 150px;
  height: 150px;
  border-radius: 8px;
  /* 枠が分かりやすいように黒い背景を敷く */
  background-color: #111; 
}

/* 共通の画像設定 */
.blur-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
}

/* =❌ 罠:そのままぼかす(フチが黒い背景と混ざって黒く/白く透ける)= */
.is-bad-blur {
  filter: blur(8px);
}

/* =⭕️ 正解:親要素ではみ出しを隠し、子要素を拡大する= */
.is-overflow-hidden {
  overflow: hidden; /* 💡 親要素にはみ出し禁止を指定 */
}

.is-good-blur {
  filter: blur(8px);
  transform: scale(1.15); /* 💡 少し拡大して、透けた端っこの部分を切り落とす */
}

/* =コード解説エリア(エディタ風)= */
.filter-blur-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
}

overflowtransformの使い方を詳しく知りたい人は以下から一読ください。

まとめ

分かりやすいようにまとめを記載します。

本記事のまとめ
  • filterプロパティは、要素自体にぼかしや色調変化などのエフェクトを適用する。
  • 主要な関数にはblur() (ぼかし),brightness() (明るさ),contrast() (コントラスト),drop-shadow() (影),grayscale() (モノクロ化),invert() (階調反転) など10種類がある。
  • 複数のフィルターを組み合わせる場合は、カンマ(,)ではなく半角スペースで区切る。
  • ホバー時のアニメーション(transition)は、:hover側ではなくベース側に記述するのがよい。
  • 背景色を透かさずに画像を暗くするにはopacityではなくfilter: brightness()を使用する。
  • 透過画像やSVGの形に沿って影をつけるにはbox-shadowではなくfilter: drop-shadow()を使用する。
  • 黒などの画像を白に変えるには、filter: brightness(0) invert(100%);を使用する。
  • 要素の中身はそのままに、背景だけをぼかすにはbackdrop-filterを使用し、背景色を半透明にする。
  • Safariでbackdrop-filterを効かせるには、-webkit-backdrop-filterを併記する。
  • 親要素にfilterをかけると新しいスタッキングコンテキストが生成され、子要素のz-indexが効かなくなるため注意が必要である。
  • blur()で画像の端が白く透ける場合は、親要素にoverflow: hidden;を指定し、画像を少し拡大(transform: scale())して隠す。

よくある質問(FAQ)

CSSのfilterプロパティとは何ですか?

画像や要素に対して、Photoshopなどの画像編集ソフトを使わずに、ブラウザ上で直接グラフィックエフェクトを適用できるCSSプロパティです。

主にimgタグで読み込んだ写真やSVGアイコンの色味を調整したり、要素に影を落としたりする際に使用されます。

複数のfilter効果を同時にかけるにはどうすればいいですか?

複数のフィルターを適用する場合は、カンマ(,)ではなく半角スペースで区切って記述します。

例:filter: grayscale(100%) blur(5px);

カンマで区切ってしまうと構文エラーとなり、すべてのフィルターが無効になってしまうため注意が必要です。

また、記述した順番に効果が適用されるため、順番によって見た目が変わることがあります。

中のテキストはそのままにして、背景の画像だけをぼかすにはどうすればいいですか?

filterの代わりにbackdrop-filterプロパティを使用します。

filterは指定した要素全体に効果がかかりますが、backdrop-filterは「要素の後ろ側」にだけ効果を適用します。

この際、要素自身の背景色(background-color)をrgba(255, 255, 255, 0.5)のように半透明にしておかないと、後ろが透けないため効果が見えません。

filter: drop-shadow()とbox-shadowの違いは何ですか?

box-shadowは、要素の「四角い箱」に対して影をつけます。

一方drop-shadow()は、透過PNGやSVG画像、複雑な形をした要素の「実際の輪郭」に沿って影を落とします。

切り抜き画像やアイコンに影をつけたい場合は、drop-shadow()を使用してください。

CSSのfilterを使って、黒いアイコン画像を白にするにはどうすればいいですか?

filter: brightness(0) invert(100%);を指定するのが確実な方法です。

元の画像に少しでも色がついている場合、invert(100%)(階調反転)だけでは白にはなりません。

そのため、brightness(0)で強制的に黒にしてから、invert(100%)で白に反転させるというテクニックが実務で使われます。

この記事を書いた人

sugiのアバター sugi Site operator

【経歴】玉川大学工学部卒業→新卒SIer企業入社→2年半後に独立→プログラミングスクール運営/受託案件→フリーランスエンジニア&SEOコンサル→Python特化のコンテンツサイトJob Code&UIコピペサイトCode Stock運営中

目次