阿卡不拉阿卡不拉
Vue3
阿卡的博客
Vue3
阿卡的博客
  • Vue3

    • 快速入门

      • 搭建工程 👌
      • 模板语法
      • 响应式基础
      • 响应式常用 API
      • 计算属性
      • 类与样式绑定
      • 条件和列表渲染
      • 事件处理
      • 表单处理
      • 生命周期
      • 侦听器
      • 组件介绍
      • Props
      • 自定义事件
      • 组件v-model
      • 插槽
      • 前端路由介绍
      • KeepAlive内置组件
      • 状态管理库
      • 组件库介绍
    • 深入本质

      • 虚拟DOM本质
      • 模板的本质
      • 组件树和虚拟DOM树
      • 数据拦截的本质
      • 响应式数据的本质
      • 响应式的本质
      • 响应式和组件渲染
      • 实现响应式系统 1
      • 实现响应式系统 2
      • 图解EFFECT
      • 实现响应式系统 3
      • 手写computed
      • 手写watch
      • 指令的本质
      • 插槽的本质
      • v-model的本质
      • setup 语法标签
      • 组件生命周期
      • keepalive 生命周期
      • keepalive的本质
      • key的本质
    • 细节补充

      • 【Vue】属性透传
      • 【Vue】依赖注入
      • 【Vue】组合式函数 👌
      • 【Vue】自定义指令
      • 【Vue】插件
      • 【Vue】Transition
      • 【Vue】TransitionGroup
      • 【Vue】Teleport
      • 【Vue】异步组件
      • 【Vue】Suspense
      • 【Router】路由模式
      • 【Router】路由零碎知识
      • 【Router】路由匹配语法
      • 【Router】路由组件传参
      • 【Router】内置组件和函数
      • 【Router】导航守卫
      • 【Router】过渡特效
      • 【Router】滚动行为
      • 【Router】动态路由
      • 【State】通信方式总结
      • 【State】Pinia 自定义插件
      • 【场景】封装树形组件
      • 【场景】自定义 ref 实现防抖
      • 【场景】懒加载
      • 【场景】虚拟列表
      • 【场景】虚拟列表优化
      • 【第三方库】VueUse
      • 【第三方库】vuedragable
      • 【第三方库】vue-drag-resize
      • 【第三方库】vue-chartjs
      • 【第三方库】vuelidate
      • 【第三方库】vue3-lazyload
      • 【场景】Websocket 聊天室
      • 【Vite】✨ 认识 Vite👌
      • 【Vite】配置文件 👌
      • 【Vite】✨ 依赖预构建 👌
      • 【Vite】构建生产版本 👌
      • 【Vite】环境变量与模式
      • 【Vite】CLI
      • 【Vite】Vite 插件
  • 笔面试

    • HTML

      • HTML 面试题汇总
      • 文档声明
      • 语义化
      • W3C 标准组织
      • SEO
      • iframe
      • 微格式
      • 替换元素
      • 页面可见性
    • CSS

      • CSS 面试题汇总
      • CSS 单位总结
      • 居中方式总结
      • 隐藏元素方式总结
      • 浮动
      • 定位总结
      • BFC
      • CSS 属性计算过程
      • CSS 层叠继承规则总结
      • @import 指令
      • CSS3 calc 函数
      • CSS3 媒体查询
      • 过渡和动画事件
      • 渐进增强和优雅降级
      • CSS3 变形
      • 渐进式渲染
      • CSS 渲染性能优化
      • 层叠上下文
      • CSS3 遮罩
    • JavaScript

      • JavaScript 面试题汇总
      • ✨ let、var、const 的区别
      • JS中的数据类型
      • 包装类型
      • 数据类型的转换
      • 运算符
      • ✨ 原型链
      • ✨ this 指向
      • ✨ 垃圾回收与内存泄漏
      • ✨ 执行栈和执行上下文
      • ✨ 作用域和作用域链
      • ✨ 闭包
      • DOM 事件的注册和移除
      • DOM 事件的传播机制
      • 阻止事件默认行为
      • 递归
      • ✨ 属性描述符
      • class 和构造函数区别
      • 浮点数精度问题
      • 严格模式
      • ✨ 函数防抖和节流
      • ✨ WeakSet 和 WeakMap
      • ✨ 深浅拷贝
      • 函数柯里化
      • Node 事件循环
      • 尺寸和位置
    • 浏览器

      • 浏览器面试题汇总
      • ✨ 浏览器的渲染流程
      • ✨ 资源提示关键词
      • 浏览器的组成部分
      • IndexedDB
      • ✨ File API
      • ✨ 浏览器缓存
      • ✨ 浏览器跨标签页通信
      • Web Worker
    • 网络

      • 网络面试题汇总
      • 五层网络模型 👌
      • 常见请求方法 👌
      • ✨cookie👌
      • 面试题
      • 加密
      • ✨JWT👌
      • ✨ 同源策略及跨域问题 👌
      • 文件上传
      • ✨ 输入 url 地址之后
      • 文件下载
      • ✨ session
      • ✨ TCP
      • ✨ CSRF 攻击
      • ✨XSS 攻击 👌
      • ✨ 网络性能优化
      • 断点续传
      • 域名和 DNS
      • SSL、TLS、HTTPS 的关系
      • ✨ HTTP 各版本差异 👌
      • HTTP 缓存协议
      • ✨ WebSocket
    • 工程化

      • CMJ 和 ESM
      • npx
      • ESLint
    • Vue2

      • Vue 面试题汇总相关
      • 组件通信方式总结
      • 虚拟 DOM
      • v-model
      • 数据响应式原理
      • diff
      • 生命周期详解
      • computed
      • 过滤器
      • 作用域插槽
      • 过度和动画
      • 优化
      • keep-alive
      • 长列表优化
      • 其他 API
      • 模式和环境变量
      • 更多配置
      • 更多命令
      • 嵌套路由
      • 路由切换动画
    • Vue3

      • ✨ Vue3 整体变化 👌
      • ✨ Vue3 响应式变化 👌
      • ✨ nextTick 实现原理 👌
      • 两道代码题 👌
      • Vue 运行机制
      • 渲染器核心功能
      • 事件绑定与更新

CSS3 变形

经典真题

  • 请简述一下 CSS3 中新增的变形如何使用?

CSS3 变形相关知识

变形介绍

CSS2.1 中的页面都是静态的,多年来,Web 设计师依赖于图片、Flash 或者 JavaScript 才能完成修改页面的外观。CSS3 改变了设计师这种思维,借助 CSS3 可以轻松的倾斜、缩放、移动以及翻转元素。

2012 年 9 月,W3C 组织发布了 CSS3 变形工作草案。允许 CSS 把元素变成 2D 或者 3D 空间,这其实就是 CSS3 的 2D 变形和 3D 变形。

CSS3 变形是一些效果的集合,比如平移、旋转、缩放和倾斜效果,每个效果通过变形函数(transform function)来实现。在此之前,要想实现这些效果,必须依赖图片、Flash 或者 JavaScript 才能完成,而现在仅仅使用纯 CSS 就能够实现,大大的提高了开发效率以及页面的执行效率。

变形效果要通过变形函数来实现,语法如下:

transform: none|transform-functions;

那么 CSS3 中为我们提供了哪些变形函数呢?

这里我们整体可以划分出 3 大类:

  • 具有 X/Y 的函数:translateX、translateY、sclaeX、scaleY、skewX、skewY
  • 2D 变形函数:translate、sclae、rotate、skew、matrix
  • 3D 变形函数:rotateX、rotateY、rotate3d、translateZ、translate3d、scaleZ、scale3d、matrix3d

此时,你可能已经做好了逐一击破每个变形函数的思想准备了。

别急,在介绍每个变形函数之前,我们先来了解一下变形相关的属性。

变形属性

transform 属性

第一个首当其冲的就是 transform 属性,该属性所对应的属性值就是一系列的变形函数,例如:

transform: scale(1.5);

上面的代码中,我们设置了 transform 属性,属性值为 scale 变形函数。

transform-origin 属性

接下来第二个是 transform-origin 属性,该属性用于设置元素的中心点位置。该属性语法如下:

transform-origin: x-axis y-axis z-axis;

为了演示此属性的作用,我们先透支一点后面的知识。

这里我们以 rotate 为例。rotate 是变形函数中的一个,作用是旋转元素,其语法如下:

rotate(angle)

定义 2D 旋转,在参数中规定角度。

来看一个例子:

<div></div>
div {
    width: 150px;
    height: 150px;
    background-color: red;
    margin: 200px;
    transition: all 1s;
}
div:hover {
    transform: rotate(45deg);
}

效果如下:

在上面的示例中,我们设置 div 鼠标 hover 的时候进行变形,旋转 45 度,为了更加平滑,我们加入了 transition 过渡效果。

我们观察整个元素的旋转中心点,是在元素的最中央。

接下来我们可以使用 transform-origin 来修改这个中心点的位置。例如:

div {
    width: 150px;
    height: 150px;
    background-color: red;
    margin: 200px;
    transition: all 1s;
    transform-origin: bottom left;
    /* 修改元素的中心点位置 */
}
div:hover {
    transform: rotate(45deg);
}

效果如下:

在上面的代码中,我们修改了元素的中心点位置为 bottom、left,也就是左下角。可以看到因为元素的中心点位置发生了变化,旋转的方式也随之发生了改变。

transform-origin 的属性值除了像上面一样设置关键词以外,也可以是百分比、em、px 等具体的值。

transform-origin 的第三个参数是定义 Z 轴的距离,这在后面介绍 3D 变形时再来介绍。

  1. transform-style 属性

transform-style 属性是 3D 空间一个重要属性,指定了嵌套元素如何在 3D 空间中呈现。语法如下:

transform-style: flat | preserve-3d;

其中 flat 为默认值。

需要注意的是该属性需要设置在父元素上面,使其变成一个真正的 3D 图形。

当然光看属性说明是非常模糊的,一点都不直观,我们直接来看一个例子。

<div class="box">
    <div class="up">上</div>
    <div class="down">下</div>
    <div class="left">左</div>
    <div class="right">右</div>
    <div class="forword">前</div>
    <div class="back">后</div>
</div>
.box {
    width: 250px;
    height: 250px;
    border: 1px dashed red;
    margin: 100px auto;
    position: relative;
    border-radius: 50%;
    transform-style: preserve-3d;
    animation: gun 8s linear infinite;
}

.box > div {
    width: 100%;
    height: 100%;
    position: absolute;
    text-align: center;
    line-height: 250px;
    font-size: 60px;
    color: #daa520;
}

.left {
    background-color: rgba(255, 0, 0, 0.3);
    transform-origin: left;
    transform: rotateY(90deg) translateX(-125px);
}

.right {
    background: rgba(0, 0, 255, 0.3);
    transform-origin: right;
    /* 变换*/
    transform: rotateY(90deg) translateX(125px);
}
.forward {
    background: rgba(255, 255, 0, 0.3);
    transform: translateZ(125px);
}
.back {
    background: rgba(0, 255, 255, 0.3);
    transform: translateZ(-125px);
}
.up {
    background: rgba(255, 0, 255, 0.3);
    transform: rotateX(90deg) translateZ(125px);
}
.down {
    background: rgba(99, 66, 33, 0.3);
    transform: rotateX(-90deg) translateZ(125px);
}
@keyframes gun {
    0% {
        transform: rotateX(0deg) rotateY(0deg);
    }

    100% {
        transform: rotateX(360deg) rotateY(360deg);
    }
}

效果如下:

上面的 CSS 代码不用具体去关心,我们只看在 box 元素上面添加了一句 transform-style: preserve-3d,表示 box 里面的子元素都以 3D 的形式呈现。如果我们把这行代码去除掉或者值修改为 flat,效果如下:

怎么样?是不是非常直观,一下子就知道 transform-style 属性的作用是什么了。该属性就是指定子元素是在 3D 空间还是 2D 平面中显示。

perspective 属性

perspective 属性用于设置查看者的位置,可以将可视内容映射到一个视锥上,继而投到一个 2D 视平面上。如果不指定该属性,则 Z 轴空间中所有点将平铺到同一个 2D 视平面中,并且在变换结果中将不存在景深概念。

简单理解,就是视距,用来设置用户和元素 3D 空间 Z 平面之间的距离。而其效应由他的值来决定,值越小,用户与 3D 空间 Z 平面距离越近,视觉效果更令人印象深刻;反之,值越大,用户与 3D 空间 Z 平面距离越远,视觉效果就很小。

注意当为元素定义 perspective 属性时,其子元素会获得透视效果,而不是元素本身。

我们还是来看一个直观的例子来了解这个属性的作用。例如:

<div class="container">
    <div class="item"></div>
</div>
.container {
    width: 500px;
    height: 500px;
    border: 1px solid;
    margin: 100px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.item {
    width: 150px;
    height: 150px;
    background-color: red;
    animation: rotateAnimation 5s infinite;
}
@keyframes rotateAnimation {
    0% {
        transform: rotateY(0deg);
    }
    100% {
        transform: rotateY(360deg);
    }
}

效果:

在上面的代码中,我们虽然设置了 div.item 沿着 Y 轴进行旋转,但是由于没有设置 perspective 视距,所以看上去就像是 div 盒子在宽度伸缩一样,3D 效果并不明显。

此时我们可以给父元素 div.container 设置 perspective 视距,例如:

.container{
  ...
  perspective: 1200px;
}

效果如下:

很明显,加入 perspective 视距后,3D 旋转效果更佳的真实。

关于 perspective 的取值,接受一个长度单位大于 0,其单位不能为百分比的值。大致能够分为如下 3 种情况:

  • none 或者不设置:没有 3D 空间。
  • 取值越小:3D 效果越明显,也就是眼睛越靠近真 3D。
  • 取值无穷大或者为 0:与取值为 none 的效果一样。

perspective-origin 属性

如果理解了上面的 perspective 属性,那么这个 perspective-origin 就非常好理解了,该属性用来决定 perspective 属性的源点角度。

其语法如下:

perspective-origin: x-axis y-axis;

举个例子:

.container{
  ...
  perspective: 600px;
  perspective-origin: top;
}

效果如下:

由于我们设置的 perspective-origin 的值为 top,所以会呈现一种俯视的效果。如果将其值修改为 bottom,则会是仰视的即视感,如下:

backface-visibility 属性

backface-visibility 属性决定元素旋转背面是否可见。对于未旋转的元素,该元素的正面面向观看者。当其旋转 180 度时会导致元素的背面面向观众。

该属性是设置在旋转的元素上面,语法如下:

backface-visibility: visible|hidden;

来看一个具体的例子:

.item{
  ...
  backface-visibility: hidden;
}

效果:

在上面的代码中,我们在子元素 div.item 上设置了 backface-visibility: hidden,当此元素旋转 180 度到背面时,我们可以发现此时是无法看到背面的。

2D 变形

介绍完 CSS3 中变形的相关属性后,接下来我们就该来看一下具体的变形函数了。

整个 CSS3 为我们提供了相当丰富的变形函数,有 2D 的,有 3D 的。这里我们先来看 2D 的变形函数。

2D 位移

2D 位移对应有 3 个变形函数,分别是 translate、translateX、translateY

用法也非常简单,translate 方法从其当前位置移动元素(根据为 X 轴和 Y 轴指定的参数)。

div {
    transform: translate(50px, 100px);
}

上面的例子把 div 元素从其当前位置向右移动 50 个像素,并向下移动 100 个像素:效果如下:

2D 缩放

2D 缩放对应的也有 3 个变形函数,分别是 sclae、sclaeX、sclaeY

该方法能够按照倍数放大或缩小元素的大小(根据给定的宽度和高度参数)。默认值为 1,小于这个值就是缩小,大于这个值就是放大。

div {
    transform: scale(2, 3);
}

上面的例子把 div 元素增大为其原始宽度的两倍和其原始高度的三倍,效果如下:

2D 旋转

2D 旋转对应的只有 1 个变形函数 rotate,这个我们在前面也已经用过了。

该变形函数只接受一个值代表旋转的角度值,取值可正可负,正值代表顺时针旋转,负值代表逆时针旋转。

div {
    transform: rotate(20deg);
}

上面的例子把 div 元素顺时针旋转 20 度,效果如下:

2D 倾斜

2D 倾斜对应的变形函数也是 3 个,分别是 skew、skewX、skewY

语法如下:

skew(ax, ay)
  • ax:指定元素水平方向(X 轴方向)倾斜角度
  • ay:指定元素垂直方向(Y 轴方向)倾斜角度
<div></div>
div {
    width: 150px;
    height: 150px;
    background-color: red;
    margin: 150px;
    transition: all 1s;
}
div:hover {
    transform: skew(20deg);
}

效果如下:

2D 矩阵

虽然 CSS3 为我们提供了上述的变形函数方便我们进行元素的变形操作,但是毕竟函数个数有限,有些效果是没有提供的,例如镜像翻转的效果。此时就轮到 2D 矩阵函数 matrix 登场了。

matrix 有六个参数:

matrix(a,b,c,d,e,f)

六个参数对应的矩阵:

这六个参数组成的矩阵与原坐标矩阵相乘计算坐标。计算方式如下:

什么意思呢 ?x 和 y 是元素中每一个像素的初始原点的坐标,而 x’ 和 y’ 是通过矩阵变化后得到的新原点坐标。通过中间 3 x 3 变换矩阵,对原先的坐标施加变换,从而得到新的坐标。

x’ = ax+cy+e,表示变换后的水平坐标

y’ = bx+dy+f,表示变换后的垂直位置

在 CSS3 中,上面我们所介绍的所有 2D 变形函数都能够通过这个 matrix 矩阵函数来替代。

矩阵实现偏移

我们首先来看通过矩阵实现偏移效果。

偏移效果前后 x、y 与 x’、y’ 所对应的坐标公式为:

x' = x + 偏移量
y' = y + 偏移量

套用上面的公式那么各个参数的取值就应该是:

a = 1; b = 0;
c = 0; d = 1;
e = x 偏移量; f = y 偏移量
x' = ax+cy+e = 1x + 0y + x 偏移量 = x + x 偏移量
y' = bx+dy+f = 0x + 1y + y 偏移量 = y + y 偏移量

所以换成 matrix 函数就应该是:

matrix(1, 0, 0, 1, x 偏移量, y 偏移量)

下面来做一个测试:

<div></div>
div {
    width: 150px;
    height: 150px;
    background-color: red;
    margin: 150px;
    transition: all 1s;
}
div:hover {
    /* transform: translate(100px, 200px); */
    transform: matrix(1, 0, 0, 1, 100, 200);
}

在上面的示例中,使用 translate 和 matrix 两个变形函数的效果一致。

矩阵实现缩放

缩放之后 x、y 与 x’、y’ 所对应的坐标公式为:

x' = x * x 缩放倍数
y’ = y * y 缩放倍数

套用上面的公式那就是:

a = x缩放倍数; b = 0;
c = 0; d = y 缩放倍数;
e = 0; f = 0;
x' = ax+cy+e = x缩放倍数 * x + 0y + 0 = x缩放倍数 * x
y' = bx+dy+f = 0x + y 缩放倍数 * y + 0 = y 缩放倍数 * y

所以换成 matrix 函数就应该是:

matrix(x 缩放倍数, 0, 0, y 缩放倍数, 0, 0);

例如:

<div></div>
div {
    width: 150px;
    height: 150px;
    background-color: red;
    margin: 150px;
    transition: all 1s;
}
div:hover {
    /* transform: scale(2, 2); */
    transform: matrix(2, 0, 0, 2, 0, 0);
}

上面的代码我们分别使用 scale 和矩阵实现了相同的缩放效果。

矩阵实现旋转

旋转需要实现

水平倾斜角度 =  - 垂直倾斜角度

旋转我们用到的变形函数是 rotate(θ),其中 θ 为旋转的角度。套用上面的公式:

x' = xcosθ - ysinθ + 0 = xcosθ - ysinθ;
y' = xsinθ + ycosθ + 0 = xsinθ + ycosθ

转换为 matrix 的代码为:

matrix(cos(θ), sin(θ), -sin(θ), cos(θ), 0, 0)

例如:

<div></div>
div {
    width: 150px;
    height: 150px;
    background-color: red;
    margin: 150px;
    transition: all 1s;
}
div:hover {
    /* transform: rotate(45deg); */
    transform: matrix(0.7, 0.7, -0.7, 0.7, 0, 0);
}

上面的代码使用了 rotate 和 matrix 来实现旋转 45 度的效果。其中 sin45 和 cos45 的值都为 0.7。

矩阵实现倾斜

skew(θx, θy) 将一个元素按指定的角度在 X 轴和 Y 轴上倾斜。

倾斜对应的公式为:

x' = x + ytan(θx) + 0 = x + ytan(θx)
y' = xtan(θy) + y + 0 = xtan(θy) + y

转换为 matrix 的代码为:

matrix(1,tan(θy),tan(θx),1,0,0)

例如:

<div></div>
div {
    width: 150px;
    height: 150px;
    background-color: red;
    margin: 150px;
    transition: all 1s;
}

div:hover {
    /* transform: skew(20deg); */
    transform: matrix(1, 0, 0.4, 1, 0, 0);
}

上面的示例中分别使用 skew 和矩阵 matrix 实现了一致的倾斜效果。

矩阵实现镜像变形

前面介绍的效果,CSS3 中都提供了对应的变形函数,但是矩阵真正发挥威力是在没有对应的变形函数时,例如这里要讲的镜像变形。

我们先来看一下各种镜像变化 x、y 与 x’、y’ 所对应的关系:

水平镜像,就是 y 坐标不变,x 坐标变负

x' = -x;
y' = y;

所以:

a = -1; b = 0;
c = 0; d = 1;
e = 0; f = 0;

具体示例如下:

<div></div>
div {
    width: 300px;
    height: 200px;
    margin: 150px;
    transition: all 1s;
    background: url("./ok.png") no-repeat;
    background-position: center;
    background-size: contain;
}

div:hover {
    transform: matrix(-1, 0, 0, 1, 0, 0);
}

效果:

垂直镜像,就是 x 坐标不变,y 坐标变负

x' = x;
y' = -y;

所以:

a = 1; b = 0;
c = 0; d = -1;
e = 0; f = 0;

例如:

... div:hover {
    transform: matrix(1, 0, 0, -1, 0, 0);
}

效果:

水平镜像 + 倒立就是 y 坐标变负,x 坐标变负

x' = -x;
y' = -y;

所以:

a = -1; b = 0;
c = 0; d = -1;
e = 0; f = 0;

例如:

... div:hover {
    transform: matrix(-1, 0, 0, -1, 0, 0);
}

效果:

90 度旋转 + 镜像就是:

x' = y;
y' = x;

所以:

a = 0; b = 1;
c = 1; d = 0;
e = 0; f = 0;

例如:

... div:hover {
    transform: matrix(0, 1, 1, 0, 0, 0);
}

效果:

  • 90 度旋转 + 镜像就是:
x' = -y;
y' = -x;

所以:

a = 0; b = -1;
c = -1; d = -0;
e = 0; f = 0;

例如:

... div:hover {
    transform: matrix(0, -1, -1, 0, 0, 0);
}

效果:

通过上面一系列的示例,我们可以发现,使用矩阵 matrix 函数确实更佳灵活,能够写出各种变形效果。

3D 变形

使用二维变形能够改变元素在水平和垂直轴线,然而还有一个轴沿着它,可以改变元素。使用三维变形,可以改变元素在 Z 轴位置。

三维变换使用基于二维变换的相同属性,如果熟悉二维变换就会发现,3D 变形的功能和 2D 变换的功能类似。CSS3 中的 3D 变换只要包含以下几类:

  • 3D 位移:包括 translateZ 和 translate3d 两个变形函数。
  • 3D 旋转:包括 rotateX、rotateY、rotateZ 和 rotate3d 这四个变形函数。
  • 3D 缩放:包括 scaleZ 和 sclae3d 两个变形函数。
  • 3D 矩阵:和 2D 变形一样,也有一个 3D 矩阵功能函数 matrix3d

3D 位移

我们直接来看合成变形函数 translate3d,其语法如下:

translate3d(tx, ty, tz)
  • tx:在 X 轴的位移距离。
  • ty:在 Y 轴的位移距离。
  • tz:在 Z 轴的位移距离。值越大,元素离观察者越近,值越小,元素离观察者越远

来看一个具体的示例:

<div class="container">
    <div class="item"></div>
</div>
.container {
    width: 400px;
    height: 400px;
    border: 1px solid;
    margin: 150px;
    display: flex;
    justify-content: center;
    align-items: center;
    perspective: 1000px;
}
.item {
    width: 300px;
    height: 200px;
    transition: all 1s;
    background: url("./ok.png") no-repeat;
    background-position: center;
    background-size: contain;
}

.item:hover {
    transform: translate3d(100px, 100px, -500px);
}

在上面的代码中,我们设置 div.item 被 hover 的时候进行 3D 位移,也就是 X、Y、Z 轴同时进行移动。注意这里要设置父元素的透视效果,也就是设置 perspective 值,否则看不出 Z 轴的移动效果。效果如下:

3D 旋转

在三维变形中,可以让元素在任何轴旋转,对应的变形函数有 rotateX、rotateY、rotateZ 以及 rotate3d。

其中 rotate3d 就是前面 3 个变形函数的复合函数。不过出了 x、y、z 这三条轴的参数以外,还接受第四个参数 a,表示旋转角度。

rotate3d(x, y, z, a)
  • x:可以是 0 到 1 之间的数值,表示旋转轴 X 坐标方向的矢量。
  • y:可以是 0 到 1 之间的数值,表示旋转轴 Y 坐标方向的矢量。
  • z:可以是 0 到 1 之间的数值,表示旋转轴 Z 坐标方向的矢量。
  • a:表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转。

下面我们以 rotateX 变形函数为例:

<div class="container">
    <div class="item"></div>
</div>
.container {
    width: 400px;
    height: 400px;
    border: 1px solid;
    margin: 150px;
    display: flex;
    justify-content: center;
    align-items: center;
    perspective: 1000px;
}
.item {
    width: 150px;
    height: 150px;
    background-color: red;
    transition: all 1s;
}

.item:hover {
    transform: rotateX(45deg);
}

效果如下:

3D 缩放

3D 缩放主要有 sclaeZ 和 scale3d,其中 scale3d 就是 scaleX、scaleY 以及 scaleZ 的复合变形函数。其语法如下:

scale(sx, sy, sz)
  • sx:X 轴上的缩放比例
  • sy:Y 轴上的缩放比例
  • sz:Z 轴上的缩放比例

但是 scaleX 和 scaleY 变形效果很明显,但是 scaleZ 却基本看不出有什么效果。原因很简单,scaleZ 是 Z 轴上面的缩放,也就是厚度上面的变化,所以如果不是立方体结构,基本上是看不出来 Z 轴上面的缩放效果的。

一般来讲,我们不会将 scaleZ 和 scale3d 单独使用,因为 scaleZ 和 scale3d 这两个变形函数在单独使用时没有任何效果,需要配合其他的变形函数一起使用时才会有效果。

这里我们以前面那个立方体为例,如下:

<div class="box">
    <div class="up">上</div>
    <div class="down">下</div>
    <div class="left">左</div>
    <div class="right">右</div>
    <div class="forword">前</div>
    <div class="back">后</div>
</div>
.box {
    width: 250px;
    height: 250px;
    border: 1px dashed red;
    margin: 100px auto;
    position: relative;
    border-radius: 50%;
    transform-style: preserve-3d;
    transition: all 1s;
    transform: rotateX(45deg) rotateY(45deg);
}

.box:hover {
    transform: rotateX(45deg) rotateY(45deg) scaleZ(0.5);
}

.box > div {
    width: 100%;
    height: 100%;
    position: absolute;
    text-align: center;
    line-height: 250px;
    font-size: 60px;
    color: #daa520;
}

.left {
    background-color: rgba(255, 0, 0, 0.3);
    transform-origin: left;
    transform: rotateY(90deg) translateX(-125px);
}

.right {
    background: rgba(0, 0, 255, 0.3);
    transform-origin: right;
    /* 变换*/
    transform: rotateY(90deg) translateX(125px);
}

.forward {
    background: rgba(255, 255, 0, 0.3);
    transform: translateZ(125px);
}

.back {
    background: rgba(0, 255, 255, 0.3);
    transform: translateZ(-125px);
}

.up {
    background: rgba(255, 0, 255, 0.3);
    transform: rotateX(90deg) translateZ(125px);
}

.down {
    background: rgba(99, 66, 33, 0.3);
    transform: rotateX(-90deg) translateZ(125px);
}

效果如下:

3D 矩阵

CSS3 中的 3D 矩阵比 2D 矩阵复杂,从二维到三维,在矩阵里 33 变成 4_4,即 _9 到 16。

对于 3D 矩阵而言,本质上很多东西与 2D 是一致的,只是复杂程度不一样而已。

对于 3D 缩放效果,其矩阵如下:

matrix3d(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1)

倾斜是二维变形,不能在三维空间变形。元素可能会在 X 轴和 Y 轴倾斜,然后转化为三维,但它们不能在 Z 轴倾斜。

这里举几个 3D 矩阵的例子:

translate3d(tx,ty,tz) 等价于 matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,tx,ty,tz,1)

scale3d(sx,sy,sz) 等价于 matrix3d(sx,0,0,0,0,sy,0,0,0,0,sz,0,0,0,0,1)

rotate3d(x,y,z,a) 真是得搬出高中数学书好好复习一下了,第四个参数 alpha 用于 sc 和 sq 中

等价于…你自己从上到下,从左到右依次将参数搬入 matrix3d 中吧。

当然除非是库函数需要,否则我严重怀疑是否会有人放着 rotate3d 不用,偏要去挑战用 matrix3d 模拟 rotate3d。

真题解答

  • 请简述一下 CSS3 中新增的变形如何使用?

参考答案:

在 CSS3 中的变形分为 2D 变形和 3D 变形。

整体可以划分出 3 大类:

  • 具有 X/Y 的函数:translateX、translateY、sclaeX、scaleY、skewX、skewY
  • 2D 变形函数:translate、sclae、rotate、skew、matrix
  • 3D 变形函数:rotateX、rotateY、rotate3d、translateZ、translate3d、scaleZ、scale3d、matrix3d

另外,还有一些重要的变形属性,例如:

  • transform 属性
  • transform-origin 属性
  • transform-style 属性
  • perspective 属性
  • perspective-origin 属性
  • backface-visibility 属性
  • EOF
最近更新:: 2025/7/11 12:49
Contributors: AK
Prev
渐进增强和优雅降级
Next
渐进式渲染