紀錄工作經驗、相關知識,解決技術相關問題。

CSS, HTML

CSS backdrop-filter 毛玻璃效果教學:blur 背景模糊語法與無效原因排查

CSS backdrop-filter 毛玻璃效果教學:blur 背景模糊語法與無效原因排查 特色圖片

在現代網頁設計中,像 iOS / macOS 導覽列與浮動卡片那樣「背景呈現半透明霧化模糊,但卡片上面的文字依然清晰銳利」的毛玻璃效果(Glassmorphism),核心就是透過 CSS 的 backdrop-filter 屬性來實現。

本文提供可直接複製的 CSS backdrop-filter: blur() 毛玻璃標準程式碼範本,圖解它與一般 filter: blur() 的差別,並逐一排查開發者最常遇到「寫了 backdrop-filter 卻完全沒效果」的 5 大無效原因。

快速複製與章節跳轉:


1. CSS 毛玻璃(Glassmorphism)標準程式碼範本

要做出具有立體質感的毛玻璃區塊,單靠一行 backdrop-filter: blur(12px) 是不夠的——必須同時搭配「半透明的 rgba() 背景色」與「微光細邊框」,才能透出底下的模糊景深:

.glass-card {
  /* 1. 關鍵:背景必須是半透明(透明度建議 0.15 ~ 0.65),絕不能填純白 #fff */
  background-color: rgba(255, 255, 255, 0.28);

  /* 2. 核心背景模糊濾鏡(Safari 18 起支援無前綴寫法,同時加上 -webkit- 前綴以相容 Safari 17 以前版本) */
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);

  /* 3. 加上半透明白邊與柔和陰影,強化玻璃邊緣折射質感 */
  border: 1.5px solid rgba(255, 255, 255, 0.55);
  border-radius: 18px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, 0.25);
  padding: 28px 32px;
  color: #0f172a;
}

毛玻璃(backdrop-filter: blur(12px))實際渲染效果示意圖

CSS backdrop-filter blur(12px) 半透明毛玻璃卡片效果示意圖

圖:套用 backdrop-filter: blur(12px) 搭配半透明 rgba() 背景後,底層幾何色塊被柔化,而卡片內文字維持清晰。


2. backdrop-filter: blur() 與 filter: blur() 差在哪?

初學者最常犯的錯誤,就是在卡片上寫了 filter: blur(4px),結果發現連卡片裡面的文字跟按鈕也全部糊成一團:

比較項目filter: blur(4px)backdrop-filter: blur(12px)
作用對象元素本身 + 內部所有子元素(含文字)僅針對「壓在該元素正後方」的背景畫面
內部文字清晰度文字與按鈕會一起變模糊,無法閱讀內部文字與圖示保持完全清晰
常見用途圖片霧化、未解鎖內容遮蔽(詳見 CSS Filter 濾鏡效果教學)懸浮導覽列(Sticky Navbar)、彈跳視窗遮罩、毛玻璃卡片

視覺差異對照圖(filter: blur vs backdrop-filter: blur)

CSS filter blur 與 backdrop-filter blur 視覺效果差異對照圖

圖:左側誤用 filter: blur(4px) 會將卡片內文字一併模糊;右側使用 backdrop-filter: blur(12px) 則僅模糊背景圖層。


3. 為什麼 backdrop-filter 沒效果?5 大無效原因與排查解法

如果你在 CSS 寫了 backdrop-filter: blur(10px); 卻發現畫面完全沒有毛玻璃效果,請依序檢查以下 5 個最常見的踩坑原因:

原因一:背景色設成了「完全不透明」(如 background: #fff)

  • 問題原因:backdrop-filter 是在元素「背後」的圖層進行模糊,需要透過元素本身的半透明背景才能看見。如果你寫了 background-color: #ffffff;(100% 不透明純白),這塊白底就會像水泥牆一樣把背後的模糊效果完全擋死。
  • 解法:將背景色改為帶有 Alpha 透明度的 rgba(255, 255, 255, 0.3) 或 hsla()。

原因二:背後根本沒有任何交疊的圖片或內容

  • 問題原因:如果毛玻璃卡片放在純白色的 body 上,且卡片正下方沒有壓著任何圖片、漸層或文字,對「純白背景」做高斯模糊看起來當然還是純白色。
  • 解法:確保毛玻璃元素正後方有圖片、漸層或其他內容,例如父層設定 background-image,或透過 position: fixed、sticky、absolute 讓毛玻璃元素疊在有色彩/圖片的內容上方(關於定位層級設定,可參考 CSS position 定位教學:relative、absolute、fixed 與 sticky 差別與用法)。

原因三:漏寫 -webkit-backdrop-filter 導致 Safari 失效

  • 問題原因:Chrome 76、Edge 79、Firefox 103 起支援無前綴的 backdrop-filter;Safari 與 iOS Safari 則到 18 版才支援無前綴寫法,Safari 9~17 只認得 -webkit-backdrop-filter,只寫無前綴版本時,舊版 Safari 會直接忽略。
  • 解法:一律成對宣告 -webkit-backdrop-filter 與 backdrop-filter。

原因四:父層容器已經用了 backdrop-filter(巢狀毛玻璃失效限制)

  • 問題原因:這是最隱蔽的瀏覽器渲染限制!當父層容器(例如整個 Header 導覽列)已經設定了 backdrop-filter: blur(10px),此時它裡面的子元素(例如從 Header 展開的下拉選單 Dropdown)如果也寫 backdrop-filter: blur(10px),內層子元素的毛玻璃會失效,只剩半透明底色、背後的網頁內容不會被模糊(依 Filter Effects Level 2 規格,設了 backdrop-filter 的父層會形成 Backdrop Root,子元素的 backdrop-filter 只能讀到這個父層範圍內的內容)。
  • 解法:不要把下拉選單放在已經有 backdrop-filter 的標籤內部;而是改用偽元素 ::before 來繪製 Header 自己的毛玻璃背景,讓子選單與 ::before 處於平級關係(關於偽元素用法,可參考 CSS ::before 與 ::after 偽元素用法:content 屬性、圖片大小與無效原因):
/* 解法:當導覽列內還有子選單也需要毛玻璃時,將導覽列的毛玻璃改寫在 ::before 上 */
.navbar {
  position: sticky;
  top: 0;
  z-index: 100;
}

.navbar::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.7);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  z-index: -1; /* 放在導覽列文字下方,且不影響內部 .dropdown 子選單的 backdrop-filter */
}

原因五:父元素同時設定了 opacity < 1 或 filter

  • 問題原因:若毛玻璃元素的父容器被設為 opacity: 0.9 或 filter: brightness(...),同樣會形成 Backdrop Root(mask、clip-path、mix-blend-mode 不為預設值時也會),截斷 backdrop-filter 向下讀取網頁底圖的能力。
  • 解法:避免在毛玻璃元素的父層直接設定小於 1 的 opacity,改用 rgba() 控制背景透明度。

參考資料與延伸閱讀

發佈留言