Smashing Animations Part 2: How CSS Masking Can Add An Extra Dimension
Andy Clarke
May 14, 2025 · 15 min read
CSS, Animation, Design
能否让CSS动画超越简单的淡入淡出和滑动效果,增添立体感和复古动画魔力?本文中,先驱作者兼网页设计师Andy Clarke将展示遮罩技术如何为CSS动画解锁新的创意可能性,使其更流畅、分层且具有电影感。
尽管有关键帧和滚动驱动事件,CSS动画仍相对基础。正如我在第一部分所述,它们让我想起1960年代在电视上观看的Hanna-Barbera动画系列,如《Dastardly and Muttley in Their Flying Machines》《Scooby-Doo》《The Perils of Penelope Pitstop》《Wacky Races》以及《Yogi Bear》。
Mike喜爱90年代动画——尤其是迪士尼的《Duck Tales》。因此,整个设计都采用了这一美学风格。
我全程使用动画,并最近通过遮罩为其增添了额外维度。为解释这一动画时代如何与CSS遮罩相关,我选择了1961年5月首播的《The Yogi Bear Show》中的一集“Disguise and Gals”。在这个故事中,两名银行劫匪伪装成老妇人,将赃物藏在Yogi和Boo-Boo洞穴中的“野餐”篮里!
可能会出什么错呢?
什么是遮罩?
一个简单的遮罩示例出现在“Disguise and Gals”及无数其他卡通片的结尾。这里,一个动画渐晕逐渐隐藏Yogi的更多面部。遮罩后面的内容并未被擦除,而是被隐藏。
在CSS中,遮罩使用位图、矢量或渐变遮罩图像控制可见性。当遮罩的填充像素覆盖元素时,其内容将可见;当它们透明时,内容将被隐藏,这很合理。填充像素可以是任何颜色,但我总是使用亮粉色,以便清楚哪些区域将可见。
clip-path
的功能类似遮罩,但使用路径创建硬边裁剪区域。严格来说,遮罩和裁剪路径在技术上是不同的,但使用它们的目标通常相同。因此,在本文中,我将它们视为同一洞穴的两个入口,并统称为“遮罩”。
在“Disguise and Gals”的这一序列中,一名劫匪将装有赃物的野餐篮匆忙带入Yogi的洞穴。遮罩定义了可见区域,营造出劫匪进入洞穴的错觉。
我如何选择使用clip-path
还是mask
?我将在每个示例中解释原因。
当Mike Worth和我讨论合作时,我们知道既没有预算也没有时间为其网站创作短动画。然而,我们热衷于探索动画如何将静态图像变为生动。
使用裁剪路径进行遮罩
在Mike的传记页面,他的角色也进入了一个洞穴。我创建的SVG插图包含两组,一组用于背景,另一组用于前景的猩猩:
|
|
我定义了一个关键帧动画,通过改变其平移值,将角色从右侧2000px移动到帧中心的自然位置:
|
|
然后将该动画应用于前景组:
|
|
尽管50px的弹跳为其移动增添了一丝真实感,但我不满意角色从视口边缘开始进入的方式。
我希望他在插图边缘变得可见。由于洞穴墙壁的边缘是硬的,我选择了clip-path
。
在CSS中定义clip-path
有几种方式。我可以使用原始形状如矩形,其中前四个值指定其角位置。round
关键字和后续值定义任何圆角:
|
|
或使用更易读的xywh(x, y, width, height)值:
|
|
我可以使用圆形:
|
|
或椭圆:
|
|
我可以使用多边形形状:
|
|
甚至使用在Sketch等图形应用中创建的路径点:
|
|
最后——也是本例中的选择——我可能使用在SVG文件中定义的路径遮罩:
|
|
为使角色从插图边缘可见,我添加了第二个SVG。为防止浏览器显示它,将其尺寸设置为零:
|
|
这包含一个单独的SVG clipPath
。通过将其放在defs
元素中,此路径不会被渲染,但可用于创建CSS clip-path
:
|
|
我将clipPath
URL应用于我的插图,现在Mike的吉祥物只在进入洞穴时变得可见:
|
|
提示:实现该代码后,你会注意到调整浏览器窗口大小时存在问题。虽然我的洞穴插图是灵活的,但clipPath
保持固定宽度。
为使clipPath
响应,在 opening tag 中添加clipPathUnits="objectBoundingBox"
,然后对transform
属性应用两个缩放值。要计算这些值,首先将1除以SVG的宽度,然后除以高度。我的SVG宽度为1400px,产生第一个缩放值0.0007142857143。
|
|
裁剪不规则形状
我经常需要更改或修改插图——可能通过叠加颜色或应用混合模式——但希望保留其整体形状。
虽然clipPath
会给我想要的结果,但这些路径的复杂性和大小有时会对性能产生负面影响。这时我选择CSS遮罩,因为其属性自2023年以来已成为基线且高度可用。
mask
属性是一个简写,可以包括mask-clip
、mask-mode
、mask-origin
、mask-position
、mask-repeat
、mask-size
和mask-type
的值。我发现最好单独学习这些属性,以更轻松地掌握遮罩概念。
遮罩使用位图、矢量或渐变遮罩图像控制可见性。同样,当遮罩的填充像素覆盖元素时,其内容将可见;当它们透明时,内容将被隐藏;当遮罩部分半透明时,部分内容将透出。我可以使用包含alpha通道的位图格式,如PNG或WebP:
|
|
我可以应用使用矢量图形的遮罩:
|
|
或使用圆锥、线性或径向渐变生成图像:
|
|
或:
|
|
我可能对元素应用多个遮罩,并使用应熟悉的语法混合几种图像类型:
|
|
mask
与CSS背景共享相同的语法,这使得记住其属性更容易。要应用background-image
,添加其URL值:
|
|
要应用遮罩,将background-image
属性替换为mask-image
:
|
|
mask
属性也与CSS背景共享相同的浏览器样式,因此默认情况下,遮罩将水平和垂直重复,除非我另有指定:
|
|
它将放在左上角,除非我改变其位置:
|
|
另外,我可以以与background-size
相同的方式指定mask-size
:
|
|
最后,我可以定义遮罩的开始位置:
|
|
使用遮罩图像
Mike的FAQ页面包括其英雄站在十字路口的动画插图。我的目标是将形状与其内容分离,允许我在英雄的旅程中更改插图。因此,我创建了一个可缩放的mask-image
,定义了可见区域,并将其应用于figure
元素:
|
|
为确保遮罩匹配插图的尺寸,我还将mask-size
设置为始终覆盖其内容:
|
|
尽管“X”从未标记地点,Mike Worth的评论页面插图显示其猩猩吉祥物正在研究藏宝图。我想通过使用椭圆形状将某人的注意力集中在图像的中心部分。
|
|
然而,clip-path
的硬边没有产生我旨在实现的效果。
我尝试通过将高斯模糊过滤器与SVG中定义的遮罩结合,首先创建过滤器,然后将其应用于遮罩的椭圆:
|
|
虽然这实现了我要找的结果,但实现感觉过于复杂,毕竟只是一个简单效果。最有效、优雅和响应式的实现使用radial-gradient
,无需位图或矢量图像,仅用单个CSS属性就实现了我希望的效果:
|
|
这种方法使我能够微调mask-image
大小,甚至在有人与其内容交互时动画其颜色停止点、位置和大小。
分层多个遮罩
照明在Mike Worth的评论页面上尤其重要,其猩猩英雄需要它来研究藏宝图。像背景图像一样,我可以应用多个遮罩图像来创建所需的照明。
我可以组合两个遮罩图像:一个圆形、半透明的radial-gradient
提供环境光,加上一个45度角的linear-gradient
用于光线。我将它们都应用于figure
元素:
|
|
我单独定位遮罩,将radial-gradient
大小设置为80%,linear-gradient
光线覆盖整个图像:
|
|
但我需要更精确地控制光线位置,以创建它们来自台灯的效果。因此,我用软边位图图像替换了linear-gradient
:
|
|
最后,为增添一丝真实感,我添加了一个关键帧动画——改变mask-size
并创建灯光明灭的效果——并将其应用于figure
:
|
|
动画遮罩
动画CSS遮罩创建令人兴奋的揭示和场景之间的过渡,帮助某人关注关键内容。它还可以将故事变为生动,使个人体验更具吸引力和沉浸感。
在我为其网站设计的删除场景中,为Mike Worth创建的猩猩冒险者吉祥物可以看到驾驶穿越景观。为帮助讲述他被宿敌从远处监视的故事,我想添加一个双筒望远镜形状的遮罩。
我首先创建了双筒望远镜形状,包括一些取景器标记。
然后,我将该图像应用为遮罩,设置其位置、重复和大小值,将其放在figure
元素的中心:
|
|
然而,尽管背景无限滚动和英雄颠簸行驶的运动,动画仍感觉静态。因此我添加了一个微妙的动画,移动mask-position
,首先创建关键帧:
|
|
然后,我将其与滚动背景动画一起应用于figure
元素:
|
|
看到这些结果后,我想知道是否可以通过将mask-position
链接到某人光标的移动来将其与故事连接。我添加了一个脚本,选择figure
元素,获取光标相对于视口的位置,并动态改变mask-position
:
|
|
至此,只剩下一个挑战来完成效果。用双筒望远镜聚焦远处目标很少容易,当英雄的宿敌拥有银背大猩猩般大小的手时,任务更加困难。我扩展了我的脚本,模糊通过双筒望远镜形状遮罩看到的可见内容,然后在某人按下键盘空格键或鼠标按钮时移除过滤器:
|
|
更多遮罩动画
当使用Mike Worth网站的人走错路或转错弯时,他最终会沉入热熔岩中。
为让某人知道他们可能已到达冒险的终点,我想模仿本文开始的缩放效果:
|
|
我创建了一个圆形clip-path
,并将其默认大小设置为75%。然后,我定义了动画关键帧,将圆从75%调整到15%,然后以一秒持续时间和三秒延迟将其附加到我的figure
:
|
|
动画现在将某人的注意力集中在不幸的英雄身上,然后他越来越低地沉入沸腾的热熔岩中。
将所有变为生动
遮罩为网页动画增添了额外维度,使故事更具吸引力,某人的体验更引人入胜——同时保持动画高效轻量。无论你是揭示内容、引导焦点还是为设计增添更多深度,遮罩提供了无尽的创意可能性。那么