如何实现mask-image的平滑过渡效果(初始显示完整内容后渐入右侧遮罩)
如何实现mask-image的平滑过渡效果(初始显示完整内容后渐入右侧遮罩)
嘿,这个需求我之前做横向滚动卡片列表时刚好折腾过!要让页面加载时先完整展示内容,再让右侧的遮罩平滑渐入,核心是靠CSS过渡配合状态切换来实现——直接给mask-image加过渡有时候不太好触发动画,得给它明确的起始和结束状态才行。
我给你整理了一套落地的方案,一步步来:
- 先让容器初始状态完全无遮罩,确保页面加载时内容是完整显示的;
- 单独定义一个类,用来承载带渐变的遮罩样式;
- 给容器加上过渡属性,让遮罩的变化过程平滑过渡;
- 最后用JS在页面加载完成后,给容器添加上这个遮罩类,触发动画效果。
下面是完整的可运行代码示例:
<div class="container"> <ul class="list"> <li class="list-item">Content</li> <li class="list-item">Content</li> </ul> </div>
.container { background-color: black; /* 初始状态:用全实色渐变模拟无遮罩,和目标渐变结构统一,过渡更顺畅 */ mask-image: linear-gradient(-90deg, #000, #000); /* 给mask属性加过渡,兼容更广的浏览器 */ transition: mask 0.6s ease; } /* 触发遮罩的状态类 */ .container--right-fade { mask-image: linear-gradient(-90deg, transparent, #000 32px); } .list { display: grid; grid-auto-flow: column; margin: 0; padding: 0; list-style: none; } .list-item { display: flex; align-items: center; justify-content: center; height: 250px; width: 250px; background-color: rgb(153, 51, 0); }
// 页面DOM渲染完成后触发遮罩渐入 document.addEventListener('DOMContentLoaded', () => { const container = document.querySelector('.container'); // 加个小延迟让用户先看清完整内容,时间可以按需调整,也可以直接去掉setTimeout setTimeout(() => { container.classList.add('container--right-fade'); }, 300); });
几个关键细节要注意:
- 初始mask的设置:我用了全实色的线性渐变而不是
none,是因为这样和目标渐变的结构完全一致,浏览器能更稳定地触发过渡动画——如果从none直接切换到渐变,部分浏览器可能会跳过动画直接显示最终状态。 - 过渡属性的选择:用
mask这个简写属性比单独写mask-image兼容性更好,能覆盖更多现代浏览器的过渡支持。 - JS触发时机:用
DOMContentLoaded确保DOM已经完全渲染,避免还没找到容器就执行代码;加小延迟是为了强化“先完整显示再渐入遮罩”的感知,你可以根据需求调整或者直接去掉。
要是你用的是比较新的浏览器,也可以试试用CSS关键帧动画实现,但类切换的方式灵活性更高——比如后续想改成“用户滚动到某个位置再触发遮罩”,直接改JS的触发逻辑就行,不用动CSS。
内容来源于stack exchange




