概览
CSS 遮罩可让您将元素剪裁为自定义形状,例如为卡片添加凹口或创建形状边框。在为复杂布局组合形状时,请根据元素包含的内容类型选择遮罩策略:
| 遮盖策略 | 适用场景 | 文字影响 |
|---|---|---|
| 直接元素 SVG 遮罩 | 图片、图标、装饰性形状、复杂形状 | 不推荐(可能会剪裁文字) |
| 相邻元素 SVG 遮罩 | 包含文本和重要内容的卡片 | 文字仍完全可读 |
| 纯 CSS 渐变 | 简单几何形状 | 不推荐(可能会剪裁文字) |
实现
如需实现异形刘海屏,请执行以下操作:
使用 SVG 遮罩
SVG 遮罩可让您使用白色(显示)和黑色(隐藏)填充来定义从可见区域中减去或添加到可见区域的形状。
亮度遮罩与 Alpha 遮罩:SVG 遮罩默认为亮度模式,因此我们使用
fill="white"来显示区域,使用fill="black"来剪切区域。如果您希望使用 SVG 的透明度(Alpha 通道)而不是颜色,可以在 CSS 中设置mask-type: alpha;,或在 SVG<mask>元素上设置mask-type="alpha"。
直接元素 SVG 遮罩
如果元素内没有需要考虑的文本(例如个人资料头像、产品图片或插图),您可以直接将 SVG 遮罩应用于该元素。
在 SVG 遮罩中使用 maskContentUnits="objectBoundingBox" 可确保遮罩自动缩放到其所应用到的任何元素的宽度和高度。
<!-- 1. Define the mask in SVG (hidden from view) -->
<svg width="0" height="0" style="position: absolute;" aria-hidden="true">
<defs>
<!-- objectBoundingBox makes the mask scale from 0 to 1 along the element's borders -->
<mask id="splat-mask" maskContentUnits="objectBoundingBox">
<!-- Organic Bezier path defining an artistic paint splat shape -->
<path d="M 0.5 0.05 C 0.58 0.05, 0.58 0.21, 0.67 0.18 C 0.76 0.15, 0.79 0.08, 0.85 0.15 C 0.91 0.22, 0.83 0.32, 0.89 0.38 C 0.95 0.44, 1.03 0.45, 0.99 0.55 C 0.95 0.65, 0.82 0.62, 0.8 0.72 C 0.78 0.82, 0.89 0.92, 0.8 0.97 C 0.71 1.02, 0.64 0.88, 0.55 0.93 C 0.46 0.98, 0.44 1.06, 0.35 1.01 C 0.26 0.96, 0.31 0.81, 0.22 0.79 C 0.13 0.77, 0.01 0.88, 0.01 0.77 C 0.01 0.66, 0.16 0.62, 0.14 0.52 C 0.12 0.42, -0.02 0.39, 0.03 0.29 C 0.08 0.19, 0.23 0.27, 0.29 0.19 C 0.35 0.11, 0.3 0.01, 0.4 0.01 C 0.5 0.01, 0.42 0.05, 0.5 0.05 Z" fill="white" />
</mask>
</defs>
</svg>
<!-- 2. Apply the mask to the image element -->
<img src="avatar.jpg" alt="User Profile" class="shaped-avatar">
<style>
.shaped-avatar {
width: 200px;
height: 200px;
object-fit: cover;
/* Apply the SVG mask ID with standard and webkit-prefixed properties */
-webkit-mask-image: url(#splat-mask);
mask-image: url(#splat-mask);
}
</style>
相邻元素 SVG 遮罩
将遮罩应用于相邻元素,而不是包含文本的父元素。这样可以确保文本不会被剪裁,并且保持可读性。
为解决此问题,请将组件设计为两部分布局:
- 一个安全的、未遮盖的文本容器 (
.card-body),用于存放所有可读内容。 - 一个空的装饰性
div(.card-accent) 放置在它旁边,用于接收自定义 SVG 遮罩。
通过为这两个部分分配相同的背景颜色,它们在视觉上会合并为一个自定义形状的组件。
<!-- 1. Define the SVG mask (hidden from view) -->
<svg width="0" height="0" style="position: absolute;" aria-hidden="true">
<defs>
<!-- Use objectBoundingBox to make the mask scale with the element -->
<mask id="accent-stencil" maskContentUnits="objectBoundingBox">
<!-- Fill the entire area with white (fully visible) -->
<rect width="1" height="1" fill="white" />
<!-- Draw a black shape to cut out a concave curve. Extending the path to x=1.1 guarantees it fully clears the right edge, preventing subpixel lines -->
<path d="M 1.1,0 C 0.4,0.1 0.4,0.9 1.1,1 L 1.1,0 Z" fill="black" />
</mask>
</defs>
</svg>
<!-- 2. Create the unified card layout -->
<div class="unified-card">
<!-- The text-bearing element remains unmasked and perfectly rectangular -->
<div class="card-body">
<h3>Premium Membership</h3>
<p>Get exclusive weekly updates on modern web standards and premium UI designs.</p>
</div>
<!-- The empty accent element next to it is masked to form the custom shape -->
<div class="card-accent"></div>
</div>
<style>
.unified-card {
display: flex;
width: 400px;
}
.card-body {
flex: 1;
background-color: #1e293b; /* Elegant slate color */
color: #f8fafc;
padding: 24px;
border-top-left-radius: 16px;
border-bottom-left-radius: 16px;
}
.card-accent {
width: 60px;
background-color: #1e293b; /* Same background color so they merge visually without seams */
border-top-right-radius: 16px;
border-bottom-right-radius: 16px;
/* Reference the SVG mask */
-webkit-mask-image: url(#card-accent-mask);
mask-image: url(#card-accent-mask);
}
</style>
使用单个 CSS 渐变实现简单刘海屏
如果您只需要简单的几何切口(例如半圆形顶部凹口、侧面凹口或直线对角线切口),则无需编写或引用外部 SVG。不过,您可以直接在 mask-image 属性中定义 CSS 径向或线性渐变。
<div class="gradient-masked-card">
<h3>Notched Coupon Card</h3>
<p>This card uses a pure CSS radial gradient to cut out a semi-circular notch along its top edge.</p>
</div>
<style>
.gradient-masked-card {
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
color: white;
padding: 40px 24px 24px 24px; /* Extra top padding ensures content clears the notch */
border-radius: 16px;
text-align: center;
/* radial-gradient places a circle at 50% (horizontal center) and 0% (top edge), cutting out a 20px transparent notch */
-webkit-mask-image: radial-gradient(circle at 50% 0%, transparent 20px, black 21px);
mask-image: radial-gradient(circle at 50% 0%, transparent 20px, black 21px);
}
</style>
后备策略
如果浏览器不支持 mask-image 或带前缀的版本:
- 对于异形图片:元素会优雅降级,显示为具有默认后备样式的普通矩形元素。
- 对于异形卡:相邻的装饰性
.card-accent元素将保持为实心、未遮盖的矩形。由于它与文本容器具有相同的背景颜色,因此整个卡片将呈现为标准的、干净的矩形容器。 - 渐进增强:通过将文本图层完全置于遮罩之外,可确保内容在旧版浏览器中完全可读、结构清晰且易于访问。