perspective 属性本身不支持 CSS 变量,因它是布局级不可变量化属性,解析阶段即锁定为固定长度;必须将 perspective() 拆入 transform 函数并配合 transform-style: preserve-3d 才能生效。

直接用 perspective: var(--depth) 无效——浏览器会静默忽略该声明。真正能用变量驱动透视距离的方式只有一种:把 perspective() 拆进 transform 函数里。
为什么 perspective 属性本身不支持 CSS 变量
perspective 是一个布局级、非继承、不可变量化属性,它的值在解析阶段就被锁定为固定长度,CSS 自定义属性无法穿透到其计算逻辑中。你改了 --depth,但 perspective: var(--depth) 始终不生效,不是写法错,是规范就不允许。
- 浏览器 DevTools 里能看到该声明被划掉(invalid),但不会报错
- 即使加了单位(如
--depth: 800px),也照样无效 - 这个限制和
z-index、line-height等类似,属于“语法合法但语义禁用”
正确写法:用 transform: perspective(...) + transform-style: preserve-3d
变量必须落在 transform 的函数参数中,且父容器(或自身)必须显式启用 3D 渲染上下文。
- 写法示例:
transform: perspective(var(--depth)) rotateY(45deg); -
--depth必须带单位(px、rem等),写800或800em都会失败 -
transform-style: preserve-3d必须设在该元素自身(若它是变换主体)或其直接父容器(若它有参与 3D 的子元素) - 漏掉
transform-style: preserve-3d,rotateY、translateZ全部退化为 2D 效果,Z 轴位移消失
变量联动景深:不只是改视距,还要调 Z 轴位移
单纯改 perspective 只改变“观察距离”,要让元素视觉上真正“靠近”或“远离”,得同步控制 translateZ()。
立即学习“前端免费学习笔记(深入)”;
- 推荐组合:
transform: perspective(var(--depth)) translateZ(var(--z-offset)) rotateY(45deg); -
--z-offset和--depth可绑定同一滑块或媒体查询,模拟镜头推拉 - 注意单位一致性:如果
--depth是600px,--z-offset也建议用px,避免混用rem导致比例失真 -
perspective-origin也支持变量(如perspective-origin: var(--ox) var(--oy);),但只接受长度值或top/center等关键词,不能写var(--ox) 50%这种混合单位
最容易被忽略的点:Vue/React 中动态插入的容器,transform-style: preserve-3d 如果写在子组件样式里,而父节点是运行时挂载的,很可能没生效——必须确保它落在真实 DOM 的直接父级上,且在 3D 变换发生前已存在。


















