1. 为什么我建议前端小白学CSS 3D变形
先讲个真实场景。我有一次在招聘现场看候选人做自我介绍,对方说自己是“两年前端经验”,简历上写满了Vue、React、小程序。我随手点开他带来的个人主页作品,平面卡片堆叠,没有任何空间层次,整个页面像一张纸贴在屏幕上。于是我问了一个很基础的问题:transform-style: preserve-3d和perspective分别控制什么?他愣了几秒,然后开始背面试题。这个画面我印象很深。
CSS 3D变形从来不是“炫技专用”,它是前端开发里性价比极高的技能模块。你不需要懂WebGL,不需要引入Three.js,不需要写一行JavaScript,只要把几个CSS属性吃透,就能让卡片翻转、图片轮播、产品展示、页面转场拥有真正的三维空间感。更重要的是,它在面试中的出现频率远比大多数人想象的高——尤其是“有没有做过复杂交互动效”“页面如何有层次感”“移动端3D性能怎么优化”这类问题,背后全是CSS 3D变形的基础。
这篇内容我按7天节奏来组织:前3天搞定坐标系、透视、位移旋转缩放的核心逻辑,第4到5天做3个能写进简历的动手案例,第6到7天讲组合动画、性能优化和面试应答。整篇文章提到的所有代码,你都可以直接复制到本地跑一遍。我自己写前端这些年,凡是能在纯CSS层面解决的交互动效,从来不给项目引入额外依赖——不是不喜欢工具库,而是CSS 3D本身就够用,而且更轻、更快、更好维护。
先明确一个认知:CSS 3D变形不是“让元素飘起来”的魔法,它有清晰的数学逻辑 —— 坐标系、矩阵变换、透视投影。但你不需要啃线性代数,只需要理解几个关键属性和它们之间的配合关系,就能应对绝大多数开发场景。
2. Day 1~2:先搞懂“空间感”从哪来
2.1 坐标系:页面里的三维空间到底是什么
CSS里的常规布局是二维的:X轴向右,Y轴向下,原点在元素左上角(严格来说是元素的transform-origin位置)。添加3D变形后,多了Z轴——方向是“指向用户”。Z轴正值越大,元素离你越近;Z轴负值越大,元素离你越远。
我用一个生活化类比帮助理解:你坐在电脑前盯着屏幕,屏幕表面就是XY平面,从屏幕朝你的方向延伸出来的是Z轴。如果某个按钮的Z值是50px,它就像从屏幕表面凸出来50像素;如果Z值是-100px,它就像嵌进屏幕后方100像素。
这个坐标系的起点由transform-origin控制,默认是元素中心点。很多人做3D效果时发现旋转中心不对,大概率就是没调这个属性。常用写法:
.box { transform-origin: center center; /* 默认值:中心点 */ transform-origin: left top; /* 左上角 */ transform-origin: 20% 80%; /* 百分比 */ transform-origin: center bottom -50px; /* 3D:z轴偏移 */ }transform-origin还有第三个参数,控制Z轴方向的旋转中心,这个在实现“立体翻页”类效果时非常有用。初学阶段先掌握前两个参数就够了,第三个参数可以等理解了坐标系后回头再试。
2.2 perspective透视:没有它就没有“近大远小”
透视是整个CSS 3D的灵魂。没有透视,你让元素绕Y轴旋转45度,看到的只是一条被压扁的线,毫无立体感;加了透视,旋转时才会有近大远小的空间感。perspective属性就是模拟人眼距离屏幕的远近。
它有两种写法,很多人分不清:
/* 写法一:写在父容器上,所有子元素共享同一个透视关系 */ .parent { perspective: 800px; } /* 写法二:写在当前元素自身的transform里 */ .box { transform: perspective(800px) rotateY(45deg); }写法一的效果是“站在一个固定位置看整个场景”,所有子元素共用同一个消失点,适合做卡片墙、轮播图这类整体3D场景。写法二的效果是“每个元素各自拥有独立视角”,适合单个元素做翻转效果。
数值怎么定?经验值如下:perspective值越小,透视效果越强烈,元素变形越夸张;值越大,透视效果越平缓,越接近肉眼正常视角。
- 300px ~ 500px:非常强烈的透视,适合做“从屏幕里冲出来”的效果
- 600px ~ 1000px:常见区间,适合大多数卡片和轮播场景
- 1200px以上:接近真实视角,用于大场景、大屏可视化
我踩过的一个坑:把perspective加在需要变形的元素本身,又给它设置了transform: rotateY(...),结果透视和旋转写到同一个transform里,顺序还放错了。perspective()函数必须放在最前面,否则效果完全不一样:
/* 正确:先透视,再旋转 */ .box { transform: perspective(800px) rotateY(45deg); } /* 错误:先旋转再透视,透视作用就被扭曲了 */ .box { transform: rotateY(45deg) perspective(800px); }另一个高频问题是只写了perspective,但没写perspective-origin。它决定你“从哪个方向看”场景,默认值center center是正对屏幕中心看。改成left center,视角会偏向左侧,整个场景看起来像从侧面看过去;改成center top,视角偏高,适合展示向下展开的卡片。
2.3 preserve-3d:让子元素真正待在三维空间里
这个属性是CSS 3D里最容易忽略、但最关键的一个开关。它的作用是告诉浏览器:“我的子元素不只是平面投影,而是真实分布在三维空间里。”
理解它的关键在对比。默认情况下,父元素即使设置了transform-style: preserve-3d,子元素的3D效果也会被压平——因为CSS默认的transform-style值是flat。只有显式设置为preserve-3d,子元素的Z轴位移和旋转才会在三维空间里“立”起来。
看一个最典型的例子,实现两个卡片前后堆叠:
<div class="scene"> <div class="card front">正面</div> <div class="card back">反面</div> </div>.scene { width: 200px; height: 300px; perspective: 800px; } .scene .card { position: absolute; inset: 0; backface-visibility: hidden; } .scene .front { transform: rotateY(0deg); } .scene .back { transform: rotateY(180deg); } /* 问题来了:.front和.back确实是立体的,但它们的父容器没有开启3D空间 */如果.scene没有transform-style: preserve-3d,下面这张卡片即使在Z轴上有位移,也会被拍到同一个平面上,翻转效果就是平的;加上之后,前后两张卡片才真正分居“屏幕前”和“屏幕后”。
实际写项目时还有一处容易踩坑:在.scene上设置了overflow: hidden,结果子元素的3D效果又被压扁了。原因在于overflow会强制创建新的渲染上下文,间接把preserve-3d的效果抵消。如果你想裁剪场景,又不想丢失3D效果,建议把裁剪放到一个额外的外层容器,而不是加在.scene本身。
到这里,7天计划的前两天核心就是这三件事:坐标系、perspective、preserve-3d。第一天的成果应该是不看文档能写出一个“两卡片前后堆叠并可翻转”的小示例;第二天的成果是能理解transform-origin对旋转中心的影响,并能手动推算出某个元素旋转90度后的视觉位置。
3. Day 3:掌握位移、旋转、缩放的3D形态
3.1 translate3d和rotate3d:不只是加个“3d”后缀
很多人以为translate3d(x, y, z)就是比translate(x, y)多一个参数,其实不是这样,多出来的Z轴才是立体布局的关键能力。
Z轴位移最常见的场景是“层叠卡片”和“弹窗层级”。比如微信朋友圈的图片预览,点开大图后,图片从当前缩略图位置“浮起来”,背后其他内容暗下去——这就是把大图Z轴位移拉高,配合背景遮罩完成空间层级。CSS里实现就几行:
.photo-open { transform: translate3d(0, 0, 200px); transition: transform 0.3s ease; position: relative; z-index: 10; /* 虽然Z轴变化了,但z-index仍然决定DOM层叠顺序 */ }这里补充一个容易混淆的知识:CSS 3D的Z轴和z-index是两套体系。z-index控制的是DOM层的垂直堆叠顺序,跟是否3D无关;translate3d的Z值改变的是元素在三维空间里的深度位置,最终是否看起来变大变小、遮挡关系如何,由透视和渲染顺序共同决定。实战中两者经常配合使用,但心里要清楚是两回事。
rotate3d和rotateX/Y/Z的关系也很微妙。rotateX(45deg)是绕X轴旋转,rotateY(45deg)是绕Y轴旋转,rotate3d(x, y, z, angle)则可以绕空间中的任意向量旋转。比如rotate3d(1, 1, 0, 45deg)是绕“X轴和Y轴夹角的对角线”旋转,效果类似先绕X转再绕Y转的复合结果,但顺序和视觉并不完全相同。
旋转方向的正负值也容易搞反。记住“左手定则”的Web版本:当坐标轴正方向朝向自己时,旋转正值为顺时针,负值为逆时针。举个例子,rotateY(45deg),右手坐标系下Y轴向下,正方向指向屏幕下方,所以是绕竖轴顺时针旋转,视觉效果是元素右侧朝屏幕外翻出。
3.2 scale3d:Z轴缩放的真实用途是“呼吸感”
scale3d的X和Y轴就是普通缩放,很多菜鸟忽略了Z轴。实际上,Z轴缩放影响的是元素的厚度“拉伸”效果。如果把一个纯平面的卡片做scale3d(1, 1, 2),在透视下它看起来像从单薄纸片变成了有厚度的玻璃板。
不过说实话,Z轴缩放日常用得不算多,真正的实战价值是配合动画做“呼吸感”。例如3D卡片上的按钮悬停时,不只是放大,而是向Z轴方向“拉回来”一点:
.card { transition: transform 0.25s ease; } .card:hover { transform: scale3d(1.05, 1.05, 1.1) translateZ(40px); }这样鼠标悬停时,卡片先向用户方向推近40px,再整体放大1.05倍,比单纯的scale(1.05)有质感得多。
缩放和缩放的顺序同样是细节。transform: scale3d(1.2, 1.2, 1) translateZ(100px)和transform: translateZ(100px) scale3d(1.2, 1.2, 1)的最终视觉位置完全不同。原因在于变换函数按从右到左的顺序叠加,先执行后面的变换。看起来有点绕,但记住一个原则:想让元素“先移动再缩放”,就要先写缩放后写位移;想让元素“先缩放再移动”,就先写位移后写缩放。
到了第三天的检验标准:你能不看资料,写出一张图片在透视下绕Y轴旋转180度后自然消失、然后又出现的动画,并解释清楚backface-visibility: hidden的作用与局限。
4. Day 4~5:三个实战案例,做完你就入门了
4.1 案例一:产品卡片的3D翻转效果
这个案例是面试和项目中最常见的需求:鼠标悬停或点击时,卡片正面翻转消失,背面展示详细信息。
<div class="flip-card"> <div class="flip-inner"> <div class="flip-front">正面内容</div> <div class="flip-back">背面内容</div> </div> </div>.flip-card { width: 300px; height: 400px; perspective: 1000px; } .flip-inner { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; transition: transform 0.6s; } .flip-card:hover .flip-inner { transform: rotateY(180deg); } .flip-front, .flip-back { position: absolute; inset: 0; backface-visibility: hidden; display: flex; align-items: center; justify-content: center; } .flip-back { transform: rotateY(180deg); }几个关键点拆解一下:
.flip-card上只加perspective,把透视和翻转动画的容器区分开。.flip-inner上必须有preserve-3d,否则正反面会贴在同一平面,翻转效果变成闪烁。.flip-back先预设rotateY(180deg),这样初始时它是背对用户的,backface-visibility: hidden让它不可见;悬停时父容器整体旋转180度,背面正好转向用户。- 翻转动画时长设0.6秒比较自然,太短显得生硬,太长拖节奏。
- 移动端触屏没有
:hover,需要绑定点击事件切换class。如果你不想写JavaScript,可以用:focus-within配合tabindex让卡片可聚焦后翻转,但兼容性和可访问性都不如JS方案靠谱。
4.2 案例二:3D旋转木马图片展示
旋转木马是CSS 3D案例里的“经典款”。核心思路是把若干张图片均匀分布在圆周上,每张旋转相应角度,再沿Z轴推出去一段半径距离。
以8张图为例,每张应该旋转 360° ÷ 8 = 45°。半径按需求选取,想要图片间距大一些就加大半径值。这里先定义8个位置:
.carousel { position: relative; width: 300px; height: 200px; transform-style: preserve-3d; animation: rotateCarousel 20s infinite linear; } .carousel .item { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 24px; color: #fff; } .carousel .item:nth-child(1) { transform: rotateY(0deg) translateZ(300px); } .carousel .item:nth-child(2) { transform: rotateY(45deg) translateZ(300px); } .carousel .item:nth-child(3) { transform: rotateY(90deg) translateZ(300px); } .carousel .item:nth-child(4) { transform: rotateY(135deg) translateZ(300px); } .carousel .item:nth-child(5) { transform: rotateY(180deg) translateZ(300px); } .carousel .item:nth-child(6) { transform: rotateY(225deg) translateZ(300px); } .carousel .item:nth-child(7) { transform: rotateY(270deg) translateZ(300px); } .carousel .item:nth-child(8) { transform: rotateY(315deg) translateZ(300px); }为什么每个item的translateZ都写300px?因为这里translateZ是相对于“旋转后的自身坐标系”执行的。第2张图先绕Y轴旋转45度,它的Z轴方向也随之旋转,再沿这个新Z轴推出去300px。最终8张图均匀分布在圆周上。
动画部分用关键帧旋转整个容器:
@keyframes rotateCarousel { from { transform: rotateY(0deg); } to { transform: rotateY(360deg); } }实际项目里你会发现一个问题:8张图虽然位置对了,但面向屏幕的图会很难看清,因为图片法线方向指向圆心,而不是指向观众。解决办法是对每张图额外做一次反向旋转,把图片“掰”正:
.carousel .item:nth-child(1) { transform: rotateY(0deg) translateZ(300px) rotateY(0deg); } .carousel .item:nth-child(2) { transform: rotateY(45deg) translateZ(300px) rotateY(-45deg); } .carousel .item:nth-child(3) { transform: rotateY(90deg) translateZ(300px) rotateY(-90deg); }这样图片朝观众方向显示,文字和图片内容才是正的。
4.3 案例三:层叠视差卡片墙
视差效果其实也是3D变形发挥价值的重点,尤其适合大屏展示页和品牌介绍页。核心原理是让不同深度的卡片在滚动时移动速度不同——离用户近的动得快,离用户远的动得慢,形成空间层次。
CSS层面有一种纯3D实现方式:给容器设置perspective,给不同卡片设置不同translateZ值,再让容器沿Z轴整体位移。
.scroll-stage { perspective: 800px; height: 80vh; overflow-y: auto; } .card-layer { transform-style: preserve-3d; } .card-1 { transform: translateZ(80px); } .card-2 { transform: translateZ(0px); } .card-3 { transform: translateZ(-80px); }容器内部滚动时,Z值大的卡片视觉上移动更快,Z值小的移动更慢,于是产生了视差。当然这种方案要在较大型的滚动容器里调参数才有明显效果,参数值取决于卡片的尺寸和内容密度,没有固定模板。我常用的调试方法是:先设定三个层级——近景、中景、远景,分别给translateZ(100px)、translateZ(0px)、translateZ(-100px),看效果再微调。之所以用100px起步,是因为太小的Z值在800px透视下几乎感知不到深度变化。
这里有个重要的性能提示:滚动容器里元素很多时,3D变形会有额外开销。建议只对参与视差的容器开启preserve-3d,不做视差的区域保持默认flat,否则浏览器要额外合成长层级,低端手机容易掉帧。
5. Day 6:组合动画与性能优化
5.1 动画时序和缓动函数的选择
做3D交互动画,很多人一开始把注意力全放在transform属性上,忽略了动画的“节奏感”。transition和animation里的ease、ease-in-out看似区别不大,在3D翻转这种大位移场景下,缓动函数的差异会被放大得很明显。
以卡片翻转为例,ease-in会让翻转刚开始很快、结尾突然停住,视觉上像是有个突然的顿挫;ease-out则开始快、结束慢,适合“物体飞入”这类效果;ease-in-out比较均衡,但用在180度翻转上容易显得拖沓。我个人建议3D翻转类动画优先用自定义贝塞尔曲线:
.flip-inner { transition: transform 0.6s cubic-bezier(0.23, 1, 0.32, 1); }cubic-bezier(0.23, 1, 0.32, 1)又被叫做“easeOutQuint”类曲线,前段快、后段缓,非常适合功能按钮点击、卡片翻转这类“需要快速响应、最终稳定停住”的场景。另一个实用的曲线是cubic-bezier(0.68, -0.55, 0.265, 1.55),自带回弹,适合做“卡片弹起”效果,但注意不要在严肃内容页面用得太多,回弹太多次会影响用户阅读。
动画时长也值得研究。0.3秒适合微交互,0.5秒是常规小型3D变换,0.6到0.8秒适合大型场景或整体页面转场。超过1秒除非是做展示型动画,否则回调过多用户会焦躁。
5.2 性能排查:为什么3D动画卡顿
CSS 3D动画在桌面端一般很流畅,但移动端经常掉帧,核心原因是“层合成”和“GPU内存”压力。常见优化手段如下:
第一,把will-change加到需要动画的元素上,提示浏览器提前为它创建合成层:
.flip-inner { will-change: transform; }注意,will-change不可滥用。每一个开了will-change的元素都可能消耗一块独立的GPU内存,页面里几十个元素都开,内存直接爆掉。只在真正持续动画的元素上使用,动画结束后通过JS移除,或者设置will-change: auto。
第二,动画过程中避免同时改变width、height、top、left这些触发重排的属性,只动transform和opacity。布局属性和绘制属性每次变化都需要重新计算布局和绘制,非常昂贵;而transform和opacity走合成线程,基本不影响主线程。
第三,减少不必要的3D层级嵌套。浏览器渲染3D场景时,多层preserve-3d嵌套会指数级增加复杂度。能用一层解决的,不要套三层。
第四,设置translateZ(0)这个经典的“骗GPU”技巧。在不需要真正Z轴位移但需要合成层加速的场景,给元素加上translateZ(0)强制触发GPU合成,可以改善动画流畅度。但同样,用得多了也吃内存,适合动画元素数量较少时使用。
5.3 兼容性适配:把这些属性当心用
CSS 3D变形的基础属性目前在现代浏览器里都很稳定,真正容易出问题的是这几个:transform-style: preserve-3d在Safari上默认只对“直接子元素”生效,嵌套更深时可能需要加前缀或做降级;backface-visibility在部分安卓浏览器上有闪烁bug;perspective作用于inline元素时无效,需要先改成block或inline-block;will-change对低版本浏览器的支持不完整,但对不支持的浏览器只是一个普通声明,不会报错,你的动画还是会走默认逻辑。
项目里如果必须兼容IE11,我只能提醒做好心理准备。IE11对transform-style: preserve-3d支持有严重缺陷,常见的方案是:用Modernizr检测能力,不支持3D的场景降级成“平面翻转”或纯透明度切换,保证功能可用但不追求立体效果。我在一个政府类项目中就是这样处理的,当时产品经理坚持要3D翻转按钮,但用户浏览器有相当比例老旧的Windows内嵌浏览器,最后采取“能力检测+降级为Fade”方案,上线后没有收到功能异常投诉。
6. Day 7:面试场景怎么用CSS 3D加分
6.1 面试官问CSS 3D时到底想考察什么
前端面试题里出现CSS 3D,很少是单纯让你背属性,而是通过它考察三个层面的能力:CSS基础是否扎实、是否做过真实交互动效、遇到性能问题有没有自己的排查思路。
最常见的几个问题:
- “说说
perspective和transform: perspective()的区别” —— 考你对透视作用域的理解。 - “
preserve-3d和flat有什么区别,什么场景下要开启preserve-3d?”—— 考渲染上下文。 - “实现一个3D翻转卡片,需要注意哪些性能问题?” —— 考实践经验和优化意识。
- “如何实现一个3D轮播图?旋转角度怎么计算?” —— 考数学逻辑和transform组合能力。
回答这些问题的思路不是背答案,而是先讲“是什么”,再讲“怎么做”,最后讲“坑在哪”。比如问perspective的区别,你可以从两段代码的实际效果开始解释,再补充“当多个元素需要共享同一个消失点时用父容器perspective,单独控制单个元素时用函数”,最后提一句“perspective()必须写在transform最前面,写错顺序效果会变”,面试官基本就确认你是真做过而不是纸上谈兵。
6.2 简历和作品集里怎么展示CSS 3D能力
作品集里有一两个纯CSS 3D交互就足够给简历加分。注意,不是堆数量,而是展示技术选型的思考过程。与其把10个花哨轮播图塞进页面,不如做两个有业务意义的场景。比如一个3D商品展示组件,正反两面展示商品图片和参数,比所有卡片都是平面更有说服力;比如一个3D数据大屏的门户页,视觉层级通过Z轴深度拉开,一眼就能看出这不是普通后台模板。
简历上的描述也不要只写“熟悉CSS3动画”,要具体化。例如:“基于CSS 3D变形(perspective、preserve-3d、backface-visibility)实现商品卡片3D翻转与旋转木马展示,纯CSS实现,无额外依赖,移动端通过will-change优化,帧率稳定在60fps。” 这种写法比“熟练使用CSS3”有信息量得多,面试官至少能从中问出三四个考点,也说明你有量化意识。
6.3 大屏适配与3D变形的联动
热词里出现了“vue3+element plus 前端项目自适应大屏方案”,在这个场景下CSS 3D也能发挥作用。大屏展示页的可视区域通常宽度超过1600像素,甚至做到整墙拼接屏,传统平面布局到了超大屏上容易显得空洞。用3D变形给标题区、数据卡片、地图容器加一点深度感,页面会有“空间导视”的效果。
大屏上做3D要注意两点:一是perspective要适当加大,因为观看距离比桌面屏幕远,透视值太小会导致元素变形夸张;二是谨慎使用自动旋转动画,大屏可能长时间无交互,一直转动的视觉元素干扰数据读取。我的做法是给3D容器增加一个“仅第一次展示时轮播、之后静止”的逻辑,或者把旋转绑定到鼠标交互上。
7. 常见问题与排查技巧
CSS 3D变形在开发中报错的情况很少,但“效果不对”的情况特别多。下面这些是我自己真正踩过的坑,按频率排序。
7.1 转了半天还是平的,问题多半出在父容器
现象:子元素设置了rotateY(180deg)、translateZ(80px),但页面毫无立体感。
排查顺序:
- 父容器有没有写
perspective?没有写就没有透视。 - 父容器有没有写
transform-style: preserve-3d?没有写就压平了。 - 父容器有没有
overflow: hidden?有的话可能把3D上下文破坏。 - 子元素是不是
inline类型?是的话需要改成block或inline-block。
7.2 翻转卡片背后出现“镜子里的文字”
这是backface-visibility没有生效。先检查是否拼写错误(这个属性没有前缀,就是标准写法),再检查是否被display: flex或某些属性间接影响到。还有一类情况是反面元素没有预设rotateY(180deg),所以在正面也能看到内容。正确逻辑是:正反两面的初始状态相差180度,双面都隐藏背面可见性。
.flip-front { transform: rotateY(0deg); } .flip-back { transform: rotateY(180deg); }7.3 Z轴位移没有效果
先确认透视是否真的存在。如果父容器有perspective,子元素Z轴位移应该有效果;如果无效,检查是否在位移后又做了缩放或旋转导致视觉位置变化不明显。另一个原因是Z轴位移的数值太小,在1000px以上的透视下,translateZ(10px)几乎看不出来,至少用50px起步。
7.4 3D动画在手机上好卡
绝大多数情况是动画元素过多或层嵌套太深。先把will-change开起来,再把所有重叠的透明遮罩层数量减到最少。如果还卡,检查动画期间有没有同时修改border-radius、box-shadow,这两个属性的重绘开销非常大,尤其配合3D transform时会雪上加霜。
7.5 图片背面显示时被压扁
这个现象通常和rotateX有关。如果卡片绕X轴翻转(上下翻转),backface-visibility: hidden配合rotateX(180deg)可以正常工作,但图片内容从背面看时左右方向会翻转,视觉上像“从反面看一张纸的反面”。解决方案是在反面内容上再包一层,做一次rotateY(180deg),把内容转回正向。这个细节在面试问答里也经常考。
8. 写在最后,一些零碎但实用的建议
CSS 3D变形学到这个程度,你已经能应付绝大多数日常页面动效需求了。最后分享几个我自己的使用习惯,供参考。
第一,能纯CSS解决的3D效果,不引入3D库。Three.js和WebGL很强大,但它们的强项是复杂3D场景、模型渲染、粒子系统,一个按钮翻转、一个卡片轮播就引入它们,学习成本和打包体积都不划算。我的判断标准是:如果场景中只有几个几何平面,并且不需要实时交互反馈,纯CSS就是最优解。
第二,3D效果要有边界感。做页面不是做游戏,用户的核心目标是获取信息或完成操作。一个元素跳出来、转个头、翻个身,会抓眼球;但如果每一个卡片都翻转、每段文字都有Z轴位移,用户反而会迷失重点。我给自己定的原则是:单个页面里3D动效不超过三处,并且每一处都要有明确的业务目的。
第三,多调试参数,别急着抄代码。perspective: 800px不是唯一正确的答案,同一段HTML在不同的布局宽度、不同的卡片尺寸下,视觉效果差异很大。我习惯的做法是:先用浏览器开发者工具实时修改perspective和translateZ,观察不同数值下的视觉变化,找到当前项目最舒服的区间,再固化到代码里。这样调出来的是贴合场景的方案,而不是“网上都这么写”。
如果你按这套7天计划走完,建议把三个案例整理成一个单独的demo页面,加上简单的导航,当作自己的CSS动效作品。这个作品不仅能在面试时展示,也能在以后做新项目时作为组件库反复复用。我自己最早的一套3D卡片组件就是从一个小demo开始的,后来在不同项目里拆拆改改,直到今天还在用。