mask-size缺失或设为auto会导致遮罩按原始尺寸渲染,无法适配容器,从而变形;必须用contain/cover配合center定位,并禁用repeat,才能实现响应式伸缩适配。

直接说结论:用 mask-size: contain 或 mask-size: cover 配合 mask-position: center,再确保遮罩源(如 SVG、渐变)本身无固有宽高限制,就能让遮罩图形随容器尺寸自动伸缩适配。硬编码像素值或漏设 mask-size 是最常见失效原因。
为什么 mask-size 不设就变形?
CSS mask-image 默认不缩放——它会按遮罩资源原始尺寸(比如一张 200×200px 的 PNG)直接平铺或拉伸填充,而不会感知容器大小。你看到的“拉伸”“错位”“只显示一角”,几乎全是 mask-size 缺失或设为 auto auto(即原始尺寸)导致的。
-
mask-size: auto:等同于用遮罩图原始宽高,容器变小后遮罩溢出,变大后留白 -
mask-size: 100% 100%:强制拉满容器,但会破坏宽高比,圆形变椭圆、SVG 路径扭曲 -
mask-size: contain:保持比例,完整显示整个遮罩图形,适合 logo、图标类遮罩 -
mask-size: cover:保持比例,完全覆盖容器,适合全屏渐变遮罩、背景型裁剪
响应式 SVG 遮罩怎么写才不崩?
用内联 SVG 做 mask-image 时,必须移除 width/height 属性,并在 <svg></svg> 上加 viewBox。否则浏览器会按默认 300×150 视口渲染,和容器尺寸脱钩。
正确写法示例:
立即学习“前端免费学习笔记(深入)”;
.responsive-mask {
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='40' fill='white'/%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='40' fill='white'/%3E%3C/svg%3E");
mask-size: contain;
mask-position: center;
mask-repeat: no-repeat;
}
-
viewBox="0 0 100 100"定义坐标系,让 SVG 内部路径可缩放 - URL 编码中不能出现空格或引号,
%3C是,<code>%3E是> - 别漏掉
mask-repeat: no-repeat,否则默认repeat会把单个圆形铺满整个元素
用渐变做响应式遮罩要注意什么?
径向/线性渐变本身无尺寸概念,mask-size 对它依然生效——它控制的是“渐变图案的单元尺寸”,不是图像像素。比如 radial-gradient(circle, white 50%, transparent 70%) 配 mask-size: 200px 200px,会让这个圆形渐变每次重复都以 200×200px 为单位;而配 mask-size: contain,则让整个渐变“撑满容器一次”,实现真正意义上的中心圆形遮罩。
- 响应式首选:
mask-size: contain+mask-position: center - 避免用
mask-size: 100vw 100vh:视口单位在滚动、地址栏收放时抖动,iOS Safari 尤其明显 - 如果要动画,改
mask-size比改mask-position更稳定,例如呼吸灯效果:@keyframes pulse { 0% { mask-size: 100%; } 100% { mask-size: 120%; } }
真正难的不是写对属性,而是意识到:遮罩不是“画一个形状盖上去”,而是“定义一个透明度场,由 mask-size 决定这个场如何映射到容器空间”。一旦理解这点,所有变形、错位、响应失败,基本都能归因到 mask-size 和 mask-position 的组合是否匹配你的遮罩源类型与预期缩放逻辑。


















