Hình dạng phức tạp

Tính năng web: Mặt nạ SVG

Tổng quan

Để cắt các phần tử thành hình dạng phức tạp, biểu mẫu tuỳ ý như nét vẽ hoặc hoạ tiết tự nhiên, hãy sử dụng CSS Masking (mask-image). Mặc dù clip-path rất phù hợp với hình dạng hình học hoặc đường dẫn vectơ, nhưng mask-image cho phép bạn sử dụng hình ảnh (như PNG có độ trong suốt) hoặc SVG để xác định vùng hiển thị của một phần tử. Cách tiếp cận này có tính biểu đạt cao hơn vì hỗ trợ độ bán trong suốt, cho phép tạo các cạnh mềm và kết cấu phức tạp mà khó hoặc không thể đạt được bằng clip-path.

Triển khai

Cách triển khai các hình dạng phức tạp bằng mặt nạ CSS:

Sử dụng độ trong suốt của hình ảnh

Bạn có thể sử dụng độ trong suốt của hình ảnh làm mặt nạ, trong đó các phần mờ sẽ hiển thị và các phần trong suốt sẽ bị ẩn. Đây có thể là PNG, SVG hoặc hình ảnh khác có độ trong suốt hoặc hình ảnh tạo sinh, chẳng hạn như dải chuyển màu 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;
}

Sử dụng phần tử SVG trong HTML

Bạn cũng có thể tham chiếu một phần tử <mask> được xác định trong SVG cùng dòng trong HTML của trang. Sử dụng maskContentUnits="objectBoundingBox" để mặt nạ tự động điều chỉnh theo kích thước của phần tử. Điều này cho trình duyệt biết rằng tất cả toạ độ bên trong mặt nạ đều được diễn giải dưới dạng phân số từ 0 đến 1 (như 0.5 cho 50%) thay vì pixel tuyệt đối.

Mặt nạ độ sáng so với mặt nạ alpha: Theo mặc định, mặt nạ SVG sử dụng độ sáng để xác định độ mờ, trong đó màu trắng hiển thị, màu đen ẩn và màu xám tạo ra độ bán trong suốt. Nếu muốn mặt nạ sử dụng kênh alpha (độ trong suốt) của hình dạng SVG, bạn có thể chỉ định mask-type: alpha; trong CSS hoặc mask-type="alpha" trực tiếp trên phần tử <mask> của SVG.

<!-- 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>

Chiến lược dự phòng

Nếu trình duyệt không hỗ trợ mask-image hoặc phiên bản có tiền tố:

  • Phần tử sẽ không bị cắt và sẽ hiển thị dưới dạng hình chữ nhật bình thường.
  • Đảm bảo nội dung vẫn có thể đọc được và bố cục không bị hỏng nếu không có mặt nạ (cải tiến tăng dần).
  • Nếu muốn, bạn có thể sử dụng tính năng phát hiện tính năng để cung cấp hình dạng dự phòng đơn giản hơn bằng 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);
  }
}