複雜形狀

網頁功能: 遮罩 SVG

總覽

如要將元素裁剪成複雜、任意形式的形狀 (例如筆觸或有機紋理),請使用 CSS 遮罩 (mask-image)。雖然 clip-path 非常適合幾何形狀或向量路徑,但 mask-image 可讓您使用圖片 (例如具有透明度的 PNG) 或 SVG 定義元素的可見區域。這種方法更具表現力,因為支援半透明效果,可呈現柔和邊緣和複雜紋理,而 clip-path 難以或無法達到這種效果。

導入作業

如要使用 CSS 遮罩實作複雜形狀,請按照下列步驟操作:

使用圖片的透明度

您可以將圖片的透明度做為遮罩,顯示不透明部分,隱藏透明部分。這可以是 PNG、SVG 或其他具有透明度的圖片,也可以是生成圖像,例如 CSS 漸層。

.shaped-element {
  /* MANDATORY: Use vendor prefix for wider support in older browsers */
  -webkit-mask-image: url('mask.svg');
  -webkit-mask-size: cover; /* Scale mask to cover element */
  -webkit-mask-repeat: no-repeat; /* Do not tile the mask */

  /* Standard property for modern browsers */
  mask-image: url('mask.svg');
  mask-size: cover;
  mask-repeat: no-repeat;
}

在 HTML 中使用 SVG 元素

您也可以在網頁 HTML 的內嵌 SVG 中,參照定義的 <mask> 元素。使用 maskContentUnits="objectBoundingBox",遮罩就會隨著元素大小自動縮放。這會指示瀏覽器將遮罩內的所有座標解讀為 0 到 1 的分數 (例如 0.5 代表 50%),而非絕對像素。

亮度與 Alpha 遮罩:根據預設,SVG 遮罩會使用「亮度」來決定不透明度,其中白色會顯示、黑色會隱藏,灰色則會建立半透明效果。如果想讓遮罩改用 SVG 形狀的 Alpha 色版 (透明度),可以在 CSS 中指定 mask-type: alpha;,或直接在 SVG <mask> 元素上指定 mask-type="alpha"。

<!-- White areas reveal content, gray creates semi-transparency, black or transparent hides it -->
<svg width="0" height="0">
  <defs>
    <!-- objectBoundingBox scales mask coordinates (0 to 1) with the element's size -->
    <mask id="custom-shape" maskContentUnits="objectBoundingBox">
      <!-- Use white shapes to define fully opaque areas -->
      <circle cx="0.5" cy="0.5" r="0.5" fill="white" />
      <!-- Use gray shapes to define semi-transparent/faded areas -->
      <circle cx="0.5" cy="0.5" r="0.25" fill="gray" />
    </mask>
  </defs>
</svg>

<div class="masked-content">
  <!-- Content to be masked -->
</div>

<style>
.masked-content {
  /* Reference the SVG mask ID */
  -webkit-mask-image: url(#custom-shape);
  mask-image: url(#custom-shape);
}
</style>

備用策略

如果瀏覽器不支援 mask-image 或前置版本:

  • 系統不會裁剪元素,而是顯示為一般矩形。
  • 請確保內容仍可閱讀,且版面配置不會因沒有遮罩而中斷 (漸進增強)。
  • 您也可以使用功能偵測,透過 clip-path 提供更簡單的備用形狀。
/* Fallback for browsers that do not support masking */
@supports (not (mask-image: url(x))) and (not (-webkit-mask-image: url(x))) {
  .shaped-element {
    /* Use a simple rounded rectangle as fallback */
    clip-path: inset(5% round 15px);
  }
}