CSS transform 属性中文翻译过来是 变换,始终觉得翻译差那么一点意思。它可以用来改变元素形状,比如旋转、缩放、移动、倾斜等,就是它可以把元素各种拿捏~

transform 特性是在不改变自身尺寸的情况下,对元素进行各种变形,元素自身的文档流位置还是会保留,语言有些空洞,下面看例子。

笛卡尔坐标

学习变换之前,先了解一下笛卡尔坐标系,:

在笛卡尔坐标系中,每个 欧氏空间 里的点都由横坐标和纵坐标这两个值来确定。在 CSS(和大部分的计算机图形学)中,原点 (0, 0) 在元素的左上角。每个点都使用数学上的向量符号 (x,y) 来描述。



-- 摘自 MDN

意思就是 CSS 的坐标系都是从元素左上角开始的,与数学的坐标系稍有不同,Y 轴的箭头是相反的!!

transform 的属性值

截至到文章编写时,CSS3 transform 属性值有如下 21 种:

translate() 设置 2D 位移。

translate3d() 设置 3D 位移。

translateX() 设置 X 轴位移。

translateY() 设置 Y 轴位移。

translateZ() 设置 Z 轴位移。

skew() 设置 2D 倾斜。

skewX() 设置水平方向倾斜。

skewY() 设置垂直方向倾斜。

scale() 设置 2D 缩放。

scale3d() 设置 3D 缩放。

scaleX() 设置 3D X 轴缩放。

scaleY() 设置 3D Y 轴缩放。

scaleZ() 设置 3D Z 轴缩放。

rotate() 设置 2D 旋转角度。

rotate3d() 设置 3D 旋转角度。

rotateX() 设置 3D X 轴旋转角度。

rotateY() 设置 3D Y 轴旋转角度。

rotateZ() 设置 3D Z 轴旋转角度。

perspective() 设置 3D 透视,值越大会感觉越远。


matrix() 2D 矩阵变换。

matrix3d() 3D 矩阵变换,最底层的矩阵操作方法。

transform 的所有属性值都不会改变元素的自身的文档流位置!

意思就是给元素施加的 transform 仅仅是元素形态上的变化,而不会改变元素自身的位置和大小!!!

3D 立方体

为了看出每种变换的效果,先用 CSS 绘制一个立方体。代码如下:

里面也用到了 transform 属性,可以先不管代码意思,只需要知道我们的目的就是绘制一个立方体出来就行。

<div class="box">
<section class="cube">
<div class="face">1</div>
<div class="face">2</div>
<div class="face">3</div>
<div class="face">4</div>
<div class="face">5</div>
<div class="face">6</div>
</section>
</div>
<style>
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
padding: 20px;
width: 100px;
perspective: 800px; /* 透视点距离 */
}
.cube {
width: 100px;
height: 100px;
transform-style: preserve-3d; /* 子元素位于 3D 空间中 */
position: relative;
}
.face {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
position: absolute;
backface-visibility: visible;
font-size: 60px;
color: #fff;
}
.face:nth-of-type(1) {
background: rgba(90, 90, 90, 0.6);
transform: translateZ(50px);
}
.face:nth-of-type(2) {
background: rgba(0, 161, 210, 0.6);
transform: rotateY(180deg) translateZ(50px);
}
.face:nth-of-type(3) {
background: rgba(210, 207, 0, 0.6);
transform: rotateY(90deg) translateZ(50px);
}
.face:nth-of-type(4) {
background: rgba(116, 0, 210, 0.6);
transform: rotateY(-90deg) translateZ(50px);
}
.face:nth-of-type(5) {
background: rgba(210, 95, 0, 0.6);
transform: rotateX(90deg) translateZ(50px);
}
.face:nth-of-type(6) {
background: rgba(210, 0, 70, 0.6);
transform: rotateX(-90deg) translateZ(50px);
}
</style>

呈现效果:

translate 位移

translate 位移变换,使用 长度单位 设置移动距离。虽然名称叫位移,但元素的自身占用的位置还是存在的,变换后的位置也不会占用文档流。

语法:

transform: translate(tx, ty); /* 设置 2D 位移 */
transform: translate3d(tx, ty, tz); /* 设置 3D 位移 */
transform: translateX(tx); /* 设置 X 轴位移 */
transform: translateY(ty); /* 设置 Y 轴位移 */
transform: translateZ(tz); /* 设置 Z 轴位移 */

使用方式:

注意了本示例给一个盒子添加了多个 transform,仅为了演示使用方式,实际开发中只会生效一个 transform 属性:

.box {
transform: translate(20px, 20px);
transform: translate3d(20px, -20px, 200px);
transform: translateX(20px);
transform: translateY(20px);
transform: translateZ(200px);
}

呈现效果:

CSS 的 3D 坐标系 Z 轴都是垂直于屏幕,所以 X 轴上的位移,会呈现近大远小的效果。

skew 倾斜

skew 可以让元素扭成一个平行四边形一样,使用 角度值 设置倾斜角度。

语法:

transform: skew(ax, ay); /* 设置 2D 倾斜*/
transform: skewX(ax); /* 设置水平方向倾斜*/
transform: skewY(ay); /* 设置垂直方向倾斜*/

使用方式:

.box {
transform: skew(20deg, -20deg);
transform: skewX(20deg);
transform: skewY(-20deg);
transform: skew(20deg);
}

呈现效果:

scale 缩放

元素的默认缩放倍率是 1,就是不进行任何缩放,小于 1 表所缩小倍数,大于 1 表示放大倍数,使用 倍率值 设置缩放倍率。

语法:

transform: scale(sx, sy);  /* 设置 2D 缩放 */
transform: scale3d(sx, sy, sz); /* 设置 3D 缩放 */
transform: scaleX(sx); /* 设置 3D X 轴缩放 */
transform: scaleY(sy); /* 设置 3D Y 轴缩放 */
transform: scaleZ(sz); /* 设置 3D Z 轴缩放 */

使用方式:

.box {
transform: scale(1.1, 1.1);
transform: scale3d(1.2, 1.2, 1.2);
transform: scaleX(0.8);
transform: scaleY(0.8);
transform: scaleZ(2);
}

呈现效果:

rotate 旋转

rotate 可以让元素旋转起来,使用 角度值 设置旋转角度,角度单位支持:

  • deg 度数
  • rad 弧度
  • grad 梯度
  • turn 圈数

一般就 deg 和 turn 比较常用。

语法:

transform: rotate(a);  /* 设置 2D 旋转角度 */
transform: rotate3d(x, y, z, a); /* 设置 3D 旋转角度 */
transform: rotateX(a); /* 设置 3D X 轴旋转角度 */
transform: rotateY(a); /* 设置 3D Y 轴旋转角度 */
transform: rotateZ(a); /* 设置 3D Z 轴旋转角度 */

使用方式:

.box {
transform: rotate(45deg);
transform: rotate3d(1, 1, 1, -45deg);
transform: rotateX(0.15turn);
transform: rotateY(0.5rad);
transform: rotateZ(28grad);
}

呈现效果:

perspective 透视距离

perspective 设置 Z 轴的坐标原点(0)离观察者的距离,值越大会感觉越远,使用 距离单位。设置为 0 表示 Z 轴贴在了屏幕上,看起来就像无限大一样!!

语法:

transform: perspective(d);  /* 设置 3D 透视,值越大会感觉越远 */

使用方式:

.box {
transform: perspective(0);
transform: perspective(1000px);
transform: perspective(300px);
transform: perspective(143rem);
transform: perspective(6.5cm);
}

呈现效果:

matrix 矩阵变换

矩阵变换是底层实现,旋转、缩放、移动、倾斜这些效果都是上层封装后的语法糖。

矩阵变换语法:

transform: matrix(a, b, c, d, tx, ty);  /* 2D 矩阵变换*/
transform: matrix3d( /* 3D 矩阵变换,最底层的矩阵操作方法 */
a1, b1, c1, d1, /* X轴的缩放和倾斜 */
a2, b2, c2, d2, /* Y轴的缩放和倾斜 */
a3, b3, c3, d3, /* Z轴的缩放和倾斜 */
a4, b4, c4, d4 /* X、Y、Z轴位移,d4 常量是 1*/
); /*
matrix(a, b, c, d, tx, ty)

matrix3d(
a, b, 0, 0,
c, d, 0, 0,
0, 0, 1, 0,
tx, ty, 0, 1
)
的简写。
*/

2D 矩阵变换

矩阵算法梦回大学,具体原理就不详解了,有兴趣可以看看线性代数相关书籍,具体算法:

至于后面的 0 0 1 是什么,这个又跟 齐次坐标系 拉上关系了,有兴趣可参阅维基百科:https://zh.wikipedia.org/wiki/齐次坐标

其中的 x,y 表示的元素中的每个像素点的 x,y 坐标,计算的结果则是变化后的 x,y 坐标。

使用方式:

.box {
transform: matrix(1.2, 0, 0, 1.2, 0, 0);
/* 与 transform: scaleX(1.2) scaleY(1.2); 相同 */ transform: matrix(1, 0, 0.176327, 1, 0, 0);
/* 与 transform: skewX(10deg); 相同 */ transform: matrix(0.866025, 0.500000, -0.500000, 0.866025, 0, 0);
/* 与 transform: rotate(30deg); 相同 */ transform: matrix(1, 0, 0, 1, 10, 10);
/* 与 transform: translateX(10px) translateY(10px); 相同 */ }

呈现效果:

语法糖的换算规则:

变换类型 变换方法 matrix 写法
平移 translate(translateX, translateY) matrix(1, 0, 0, 1, translateX, translateY)
缩放 scale(scaleX, scaleY) matrix(scaleX, 0, 0, scaleY, 0, 0)
斜拉 skew(angleX, angleY) matrix(1, tan(angleY), tan(angleX), 1, 0, 0)
旋转 rotate(angle) matrix(cos(angle), sin(angle), -sin(angle), cos(angle), 0, 0)

3D 矩阵变换

2D 变换是 3*3 的矩阵,3D 则是 4*4 的矩阵,3D 比 2D 多出一个维度的空间,算法复杂度可不是 1+1 那么简单了。

3D 矩阵变换算法:

最终三维空间坐标:(x'/w', y'/w', z'/w')

3D 平移使用矩阵表示方法:

transform: matrix3d(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
translateX, translateY, translateZ, 1
);

3D 缩放使用矩阵表示方法:

transform: matrix3d(
scaleX, 0, 0, 0,
0, scaleY, 0, 0,
0, 0, scaleZ, 0,
0, 0, 0, 1
);

3D 倾斜使用矩阵表示方法:

transform: matrix3d(
1, tan(θ_yx), tan(θ_zx), 0,
tan(θ_xy), 1, tan(θ_zy), 0,
tan(θ_xz), tan(θ_yz), 1, 0,
0, 0, 0, 1
);

每个 tanθ 对应不同平面的倾斜角度。

旋转使用矩阵表示方法:

/* 绕 Z 轴旋转( */
transform: matrix3d(
cos(angle), sin(angle), 0, 0,
−sin(angle), cos(angle), 0, 0,
0, 0, 1, -1/d,
0, 0, 0, 1
);
/* 绕 X 轴旋转( */
transform: matrix3d(
1, 0, 0, 0,
0, cos(angle), sin(angle), 0,
0, −sin(angle), cos(angle), 0,
0, 0, 0, 1
);
/* 绕 Y 轴旋转( */
transform: matrix3d(
cos(angle), 0, −sin(angle), 0,
0, 1, 0, 0,
sin(angle), 0, cos(angle), 0,
0, 0, 0, 1
);

透视使用矩阵表示方法:

transform: matrix3d(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, -1/d,
0, 0, 0, 1
);

呈现效果:

与 transform 相关的属性

属性 作用 典型值
transform 应用变换 rotate(45deg) translateX(20px)
transform-origin 设置变换原点 left top, 50% 100%
transform-style 保留子元素 3D 空间 preserve-3d
perspective 定义 3D 观察深度 1000px
perspective-origin 设置观察者视角位置 20% 80%
backface-visibility 控制背面可见性 hidden

这些属性用于设置与 transform 相关的效果,比如设置变换原点,是否应用 3D 空间,设置透视视角等,这里就不再一一演示,有兴趣可自行写一下例子看看效果。

总结

transform 提供的基础变换已足以满足日常需求,一些特殊的变化有可能会用上矩阵,不过这么多年的前端经验来看,能用上矩阵的场景几乎不可见。

由于 transform 不改变文档流的特性,所以在 CSS 动画中,此属性应用非常广泛。

参考资料

https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform-function/matrix

https://www.zhangxinxu.com/wordpress/2012/06/css3-transform-matrix-矩阵/

https://www.cnblogs.com/cjc-0313/p/16472278.html

Web前端入门第 41 问:神奇的 transform 改变元素形状,matrix3d 矩阵变换算法演示的更多相关文章

  1. web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

    秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...

  2. Android零基础入门第41节:使用SimpleAdapter

    原文:Android零基础入门第41节:使用SimpleAdapter 通过ArrayAdapter实现Adapter虽然简单.易用,但ArrayAdapter的功能比较有限,它的每个列表项只能给一个 ...

  3. web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】

    http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...

  4. Web前端面试指导(十四):如何居中一个元素(正常、绝对定位、浮动元素)?

    题目点评 这道题目的提问比较多,连续问了三个问题,正常元素.绝对定位元素.互动元素如何居中,而且居中没有说清楚是垂直居中还是水平居中,要回答清楚这个问题,必须得有深厚的功底,而且要分类的来回答,条理要 ...

  5. [Web 前端] 023 js 的流程控制、循环和元素的获取、操作

    1. Javascript 流程控制 用于"基于不同条件执行不同的动作"的场合 1.1 if 语句 三种形式 // 第一种 if... // 第二种 if... else ... ...

  6. Android零基础入门第88节:Fragment显示和隐藏、绑定和解绑

    在上一期我们学习了FragmentManager和FragmentTransaction的作用,并用案例学习了Fragment的添加.移除和替换,本期一起来学习Fragment显示和隐藏.绑定和解绑. ...

  7. Android零基础入门第76节:Activity数据保存和横竖屏切换

    在前面几期学习了Activity的创建.配置.启动和停止,还学了Activity的生命周期,本期一起来学习Activity有关的更多事儿. 一.数据保存 通过上一期 LogCat 窗口打印的日志可以看 ...

  8. Android零基础入门第75节:Activity状态和生命周期方法

    前面两期我们学习了Activity的创建和注册.以及启动和关闭,也学会了重写onCraete方法,这些知识在实际开发中远远不够,还需要学习了解更多. 生命周期就是一个对象从创建到销毁的过程,每一个对象 ...

  9. 吐槽一下--最近多次在腾讯以及万科的面试经历---Web前端与PHP后端开发

    前端时间,由于职业发展等,想要换一份工作,于是投递了一些国内还算知名的公司,列如: 腾讯.万科之类的: (1)首先说一下这两家公司的反馈情况: 腾讯:投递到反馈,(初次人事打电话沟通)大约1周,三次不 ...

  10. Web前端3.0时代,“程序猿”如何“渡劫升仙”

    Web前端入行门槛低,很多人在成为前端工程师后很容易进入工作的舒适区,认为该熟悉的业务已熟悉了,然后就是重复用轮子,这样很容易让自己的成长处于原地打转以及低水平重复的状态. 想要不被行业抛弃,就要努力 ...

随机推荐

  1. axios请求拦截器和响应拦截器

    axios里面可以设置拦截器 ,在请求发送之前做一些事情: 拦截器分[请求拦截器]和[响应拦截器] 参考地址:https://www.jb51.net/article/150014.htm 参考的地址 ...

  2. 【译】轻松评估 AI 应用程序的质量

    原文 | Wendy Breiding 翻译 | 郑子铭 在构建利用 AI 的应用程序时,能够有效地评估 SLM(小型语言模型)或 LLM(大型语言模型)的响应从未如此重要. 评估是指评估 AI 模型 ...

  3. Java虚拟线程探索

    在Java 21中,引入了虚拟线程,这是一个非常非常重要的特性,之前一直苦苦寻找的Java协程,终于问世了.在高并发以及IO密集型的应用中,虚拟线程能极大的提高应用的性能和吞吐量. ## 什么是虚拟线 ...

  4. linux mint安装eclipse

    安装eclipse之前需要先安装配置jdk,参考上面, 一.Eclipse的下载与安装 1.首先,在Eclipse的官网中下载最新版的Luna SR2http://www.eclipse.org/do ...

  5. Net跨平台硬件信息查询库 Hardware.Info:全面获取系统硬件详情

    Hardware.Info 是一个基于 .NET Standard 2.0 的跨平台库,提供了硬件信息查询的功能,支持 Windows.Linux 和 macOS 操作系统.该库通过不同平台下的系统接 ...

  6. min-max 容斥(最值反演)学习笔记

    min-max 容斥,又名最值反演(我其实更喜欢后面这个名字),是一种常用的反演思想. 引入 在皇后游戏一题中,我们曾经证明过 \(\max(a,b)-a-b=-\min(a,b)\). 我们尝试推广 ...

  7. 盘点10个.NetCore实用的开源框架项目

    连续分享.Net开源项目快3个月了,今天我们一起梳理下10个,比较受到大家欢迎的.NetCore开源框架项目. 更多开源项目,可以查看我创建的,.Net开源项目榜单! 一个专注收集.Net开源项目的榜 ...

  8. typecho引入五秒盾,缓解服务器压力

    功能是:对访客的访问频率会先一步判断,根据用户自定义的范围,将频率过高的访客跳转向127.0.0.1,而没有达到频率的访客则会进行cookies验证,这样更大程序的对恶意流量攻击进行拦截,并且有效缓解 ...

  9. 单页应用(SPA)是什么?

    来源:https://zhuanlan.zhihu.com/p/648113861 概述 单页应用(SPA,Single Page Application)是一种网页应用或网站的设计模式,它在浏览器中 ...

  10. 掌握 K8s Pod 基础应用 (一)

    Pod 介绍 Pod结构 每个Pod中都可以包含一个或者多个容器,这些容器可以分为两类: 用户程序所在的容器,数量可多可少 Pause容器,这是每个Pod都会有的一个根容器,它的作用有两个: 可以以它 ...