CSS clip-path 常見問題:陰影、插值、版面尺寸與 Safari 相容性
GDESIGN
設計發布: 7 分鐘閱讀

CSS clip-path 常見問題:陰影、插值、版面尺寸與 Safari 相容性

CSS clip-path 決定元素哪些部分可見。陰影消失、版面方框比想像中大,不一定是瀏覽器錯誤。本文將規格定義的陰影、插值與尺寸行為,和 WebKit 曾發生的 SVG 參照問題分開說明,幫助你逐項找出原因。

日文原文發布: 2026-04-17

先從基本形狀開始

clip-path 可以把元素裁成多邊形、圓形、橢圓形,或其他支援的路徑形狀。

.hexagon {
  clip-path: polygon(
    25% 0%, 75% 0%, 100% 50%,
    75% 100%, 25% 100%, 0% 50%
  );
}

目前主要瀏覽器普遍支援基本的裁切功能,但仍須依使用的語法確認相容性。較舊的 Safari 曾需要 -webkit-clip-path 前綴;若支援範圍包含這些版本,請先寫相容宣告,再寫標準宣告。實際需要支援的版本,應查閱相容性資料並在目標裝置測試。

.hexagon {
  -webkit-clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
          clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}

WebKit 的歷史問題:SVG 參照與堆疊情境

WebKit Bug 233553 曾回報:在 <img> 使用 clip-path: url(#shape),再加上會建立堆疊情境(stacking context)的屬性,例如 transform,可能讓圖片消失。該案例的 SVG 使用 clipPathUnits="objectBoundingBox"。

修正已於 2024 年 11 月 5 日併入 WebKit,問題狀態為 RESOLVED FIXED。不能只憑併入日期,推定哪個 Safari 正式版本最先包含修正。這是歷史案例,不能當成所有現行 Safari 都有問題的證據,也不能據此推論 polygon() 與 transform 的所有組合都不穩定。

/* 用於檢查歷史問題條件的 CSS 片段;另需圖片及 SVG 的 #shape 定義。 */
.masked-image {
  clip-path: url(#shape);
  transform: translate3d(0, 0, 0); 
}

請在目標 Safari 版本分別測試 SVG 參照、建立堆疊情境的宣告,以及兩者同時存在的情況。如果能重現問題,可先移除不必要的合成相關宣告;若能表達相同輪廓,也可考慮 polygon() 等基本形狀,再於目標裝置確認。不要一律加入促使合成的宣告,因為這可能重新形成歷史問題的觸發條件。

陰影放在外層,裁切放在子元素

超出裁切區域的 box-shadow 也會被裁掉。這是規格定義的行為,不是 Safari 特有的錯誤。對不透明的裁切元素加上一般外陰影,並不會得到沿著新輪廓延伸的外陰影。

/* 超出裁切區域的陰影會被裁掉。 */
.badge {
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
  box-shadow: 0 4px 12px rgba(0,0,0,.2);  
}

CSS Masking 的繪製順序是先套用濾鏡,再裁切。因此,把 filter: drop-shadow() 放在同一個元素上,陰影仍會受到裁切。解法是讓外層容器套用濾鏡,子元素負責裁切。以下範例的前半段是 HTML,從 .badge-shadow 開始的部分是 CSS。

<div class="badge-shadow">
  <div class="badge-shape">徽章</div>
</div>

.badge-shadow {
  display: inline-block;
  filter: drop-shadow(0 4px 12px rgba(0,0,0,.25));
}
.badge-shape {
  width: 160px;
  height: 100px;
  display: grid;
  place-items: center;
  background: #2563eb;
  color: white;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}

外層容器本身應保持透明背景,讓子元素的形狀成為陰影輪廓的來源。更外層的祖先元素若設定 overflow: hidden,仍可能裁掉陰影。濾鏡的繪製成本也與面積及元素數量有關,大量使用時應在目標裝置量測。

polygon() 插值需要相同的頂點數、填滿規則與參照框

兩個多邊形的頂點數不同時,座標無法連續插值。CSS 關鍵影格動畫與 Web Animations 可以採用離散切換;一般 CSS transition 在預設情況下,不會為離散變化啟動轉場。以兩個關鍵影格、線性進度為例,離散切換會發生在區間中點;預設 transition 則可能直接套用新值,並非一律到最後才跳轉。

/* 無法連續插值:4 個頂點變成 6 個。 */
.el { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
.el:hover { clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%); }

請讓起點與終點的頂點數相同。重複同一個座標,可以讓額外的頂點在起始時與另一個頂點重合。

/* 起點與終點都有 6 個頂點。 */
.el {
  clip-path: polygon(0 0, 100% 0, 100% 0, 100% 100%, 0 100%, 0 100%);
}
.el:hover {
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}

CSS Shapes 也要求這種多邊形插值使用相同的參照框(reference box)與填滿規則(fill-rule)。以上範例都使用預設的 border-box 與 nonzero。hover 規則只定義形狀,並未設定動畫時間;若要產生轉場,可另外加入 transition: clip-path 250ms linear,並配合使用者的減少動態效果偏好,例如停用該轉場。

分開檢查父元素的 overflow 與子元素的裁切

父元素的 overflow: hidden 與子元素的 clip-path 是不同的裁切限制。可見範圍同時受到兩者約束,只看子元素時,容易誤以為形狀壞掉了。

可暫時把父元素的 overflow 改為 visible,先確認子元素單獨裁切的結果,再恢復所需的父元素尺寸與 overflow 設定。沒有先找出裁切邊界,就任意加上 position 或 isolation,無法釐清原因。

.parent {
  position: relative;
  overflow: hidden;
}
.child {
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}

裁切不會縮小版面配置中的方框

clip-path 影響繪製結果,不會改變元素本身的幾何尺寸或固有尺寸(intrinsic size)計算。在 Grid 與 Flexbox 內也一樣:看不見的區域,仍屬於版面配置使用的方框。因此,視覺上很小的圖示,周圍可能仍保留空間。

請依需求設定方框的尺寸。當某一方向的尺寸為 auto 時,aspect-ratio 可協助推算該方向的尺寸,但比例本身並不指定大小。也要確認父元素的限制,例如 Flex 項目的縮小行為。

.icon {
  width: 32px;
  height: 32px;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}

實用的除錯順序

  1. 以 Safari 為目標時,直接在 Safari 檢查。Chrome 測試成功不能證明 Safari 的行為相同。
  2. 先停止動畫與轉場,再分別移除 transform。transform: none 不會停止 clip-path 的動畫。可在開發者工具暫停動態效果,再逐一排除宣告。
  3. 暫時停用裁切。使用 clip-path: none 看清原本的版面方框,再恢復形狀。
  4. 分別確認語法支援與繪製結果。polygon、path 與 SVG 參照不能當成相同的相容性測試。CSS.supports() 能確認宣告是否受支援,不能證明繪製完全沒有問題。

重點整理

  • 需要相容舊 Safari 時,前綴宣告放在標準宣告之前。
  • WebKit Bug 233553 是已修正的歷史問題;仍應在目標版本分別測試 SVG 參照與堆疊情境條件。
  • 要讓外陰影沿著形狀,請在外層套用濾鏡、子元素套用裁切。
  • 多邊形要連續插值,頂點數、填滿規則與參照框須一致。
  • 父元素的 overflow 與子元素的裁切區域應分開檢查。
  • 依需求設定版面方框的尺寸;裁切本身不會縮小它。

參考資料與來源

編輯說明

本文使用 AI 協助編輯,並於發布前由編輯確認。內容仍可能包含事實、解讀或時效上的錯誤;進行重要判斷前,請查閱所列的一手資料或官方文件。

相關文章