【CSS in Depth 2 精译_092】第 16 章:CSS 变换(transform)概述 + 16.1 CSS 中的旋转变换、平移变换、缩放变换与倾斜变换

当前内容所在位置(可进入专栏查看其他译好的章节内容)

  • 第五部分 添加动效 ✔️
  • 【第 16 章 变换】 ✔️
    • 16.1 旋转、平移、缩放与倾斜 ✔️
      • 16.1.1 变换原点的更改 ✔️
      • 16.1.2 多重变换的设置 ✔️
      • 16.1.3 单个变换属性的设置 ✔️
    • 16.2 变换在动效中的应用

《CSS in Depth》新版封面

《CSS in Depth》新版封面

译者按
终于来到了全书倒数第二章——CSS 变换特效的学习!看来年底啃完第 2 版的小目标有望实现了。自学第一版时,最后这两章我也没仔细读过,今天静下心来学习,才发现 transform 多个属性值的渲染顺序居然是从右到左进行的!让我不禁想起数学中的矩阵复合变换,而且函数式编程中的组合函数也是类似结构。虽然看不到浏览器解析 CSS 的源码,但按照 CSS 的层叠规则,应该也是这样设计才合理。今天算是好好给自己补了一课,希望大家不要步我后尘,这些基础知识点争取第一次就记清楚。

16 变换 Transforms

本章概要

  • 利用变换操作元素,提升过渡与动画的性能
  • 为过渡添加 “弹跳” 特效
  • 浏览器的渲染流程与性能问题
  • 3D 变换与透视距离(perspective)

本章将学习 transform 属性,它可以用来改变页面元素的形状和位置,其中包括二维或三维视角下的旋转、缩放与倾斜。变换通常与过渡或动画结合起来使用,这也是为什么我把本章内容放在这两个主题之间。本书最后两章会演示大量的过渡、变换与动画等页面特效来创建页面。

首先,我会带您了解 CSS 变换在静态元素上的设置方法,这样就可以理解这些变换行为是如何独立发挥作用的,以便后续把变换融入过渡特效中。接着我们会实现一个复杂的小菜单,涉及多种变换设置与过渡效果。最后再来看看 3D 变换与透视图的用法。这部分内容会一直延续到下一章,届时我们将结合动画特效来考察 3D 变换的实际应用。

16.1 旋转、平移、缩放与倾斜 Rotate, translate, scale, and skew

以下代码定义了一个基本的 CSS 变换规则:

transform: rotate(90deg);

这条样式规则在元素上生效后,会使该元素向右(顺时针)旋转 90 度。变换函数 rotate() 用于指定元素具体的变换方式。此外还有另外几种变换函数,它们通常被分为以下四类(如图 16.1 所示):

  • 旋转(Rotate —— 让元素围绕某个轴心转过一定的角度。
  • 平移(Translate —— 可实现元素的上、下、左、右等各个方向的移动(与相对定位类似)。
  • 缩放(Scale —— 可缩小或放大元素。
  • 倾斜(Skew —— 改变元素的形状,使其顶边沿着某个方向滑动、而底边沿相反的方向滑动。

图 16.1 四种基本变换类型(虚线代表元素的初始位置与大小)

【图 16.1 四种基本变换类型(虚线代表元素的初始位置与大小)】

每种变换都会使用对应的函数来作为 transform 属性的值。下面创建一个简单的示例页,并在浏览器中小试牛刀。如图 16.2 所示,示例页为一张图文卡片。接下来就给该元素添加变换效果。

图 16.2 应用了旋转变换的简单卡片效果图

【图 16.2 应用了旋转变换的简单卡片效果图】

新建一个示例页面并关联一个新的样式表,然后将代码清单 16.1 所示的 HTML 标记添加到页面中。

代码清单 16.1 创建简单卡片示例页的 HTML 标记

<div class="card">
  <img src="images/chicken1.jpg" alt="a chicken">
  <h4>Mrs. Featherstone</h4>
  <p>
    She may be a bit frumpy, but Mrs. Featherstone gets the job done. She
    lays her largish cream-colored eggs on a daily basis. She is gregarious
    to a fault.
  </p>
  <p>This Austra White is our most prolific producer.</p>
</div>

接下来在样式表中添加代码清单 16.2 中的 CSS,其中包含了一些基础样式、颜色设置以及卡片元素的旋转变换设置。

代码清单 16.2 带旋转变换效果的示例卡片样式代码

body {
  background-color: hsl(210, 80%, 20%);
  font-family: Helvetica, Arial, sans-serif;
}

img {
  max-inline-size: 100%;
}

.card {
  max-inline-size: 300px;
  padding: 0.5em;
  margin-inline: auto; /* 居中卡片 */
  background-color: white;
  transform: rotate(15deg); /* 令卡片向右旋转 15 度 */
}

在浏览器中加载页面,会看到旋转后的卡片。不妨多试试,以建立对 rotate() 函数的初步印象。若角度为复制,卡片将向左旋转(比如改为 rotate(-30deg))。

接下来可以尝试使用其他函数修改变换类型。分别改为以下属性值,并观察它们的行为:

  • skew(20deg) —— 令卡片倾斜 20 度。再试试负的角度值,让卡片向另一个方向倾斜。
  • scale(0.5) —— 将卡片缩小到原始尺寸的一半。函数 scale() 的参数为一个百分数,或者介于 01 之间的某个数值;取值小于 1.0(或 100%)表示缩小该元素;若大于 1.0(或 100%)则表示放大该元素。
  • translate(20px, 40px) —— 令该元素右移 20px、并下移 40px。同样,也可以使用负的属性值让元素朝相反的方向变换。

设置 CSS 变换时需要注意一点:虽然元素可能会移动到页面上的新位置,但它不会脱离(shift)文档流。您可以在屏幕范围内任意平移某个元素,其初始位置不会被其他元素占用。此外,当旋转某个元素时,它的某个角可能会移出屏幕边缘,同样也可能会遮住另一个元素的某些内容(如图 16.3 所示)。

图 16.3 变换元素不会令其他元素移动,因此可以发生重叠现象

【图 16.3 变换元素不会令其他元素移动,因此可以发生重叠现象】

某些情况下,为这样的变换元素(或者连同受牵连的元素)预留出足够的外边距,可以有效避免不必要的重叠。

警告

CSS 变换无法对 <span> 或者 <a> 这样的行内元素生效。若确实要对此类元素设置变换效果,要么将该元素的 display 属性手动改为除 inline 之外的其他属性值(例如 inline-block);要么将元素改为弹性子元素或者网格元素项(grid item,即对父元素声明 display: flex 或者 display: grid)。

16.1.1 变换原点的更改 Changing the transform origin

变换是围绕某个原点发生的。它是旋转的轴心,也是缩放或者倾斜开始的位置。换言之,元素的原点是固定不动的,而元素的其余部分则围绕该原点进行变换(但 translate() 是个例外,因为平移过程中整个元素都会移动)。

默认情况下,原点就是元素的中心点,但也可以通过 transform-origin 属性进行修改。图 16.4 展示了几个围绕不同原点位置实现的元素变换效果。

图 16.4 以不同的边角位置为原点实现的元素旋转、缩放与倾斜变换效果示意图

【图 16.4 以不同的边角位置为原点实现的元素旋转、缩放与倾斜变换效果示意图】

上图中左侧的元素,其围绕旋转的原点位置,由 transform-origin: right bottom 来定义;中间的元素也向着原点位置(即 right top)缩放;而右侧的元素的倾斜方式为:原点(即 left top)保持不动,元素其余部分向外拉伸(stretches away)。

原点位置也可以用百分比设定,从元素的左上角开始测量。一下两句声明是等效的:

transform-origin: right center;
transform-origin: 100% 50%;

此外,也可以使用 pxem 或者其他单位的长度值来设置原点。不过根据我的经验,使用 toprightbottomleftcenter 这些关键字,在大部分项目中已经够用了。

16.1.2 多重变换的设置 Applying multiple transforms

transform 属性也可以设置多个值,用空格分隔即可。变换的每个值将按照 从右向左 的顺序依次生效。例如设置 transform: translate(50px, 0) rotate(15deg),元素会先顺时针旋转 15 度角,然后再向右平移 50px。请根据代码清单 16.3 同步更新本地样式表。

代码清单 16.3 设置多重变换的示例样式代码

.card {
  max-inline-size: 300px;
  padding: 0.5em;
  margin-inline: auto;
  background-color: white;
  transform: translate(50px, 0) rotate(15deg); /* 先顺时针旋转 15 度,然后再向右平移 50px */
}

最简单的查看这种效果的方法就是打开浏览器的开发者工具,实时修改属性值,看看它们是如何影响元素行为的。

弄错变换的执行顺序可能会让情况变得非常棘手。通常情况下,将 translate() 操作放在时间上最靠后的位置往往更简单(这样 transform 对应的源码顺序就要放到开头的位置),如本例所示。这样就可以使用正常的上/下、左/右坐标系来设置旋转后的元素效果了。

为了更好的理解这一点,不妨再将变换设置反转为 transform: rotate(15deg) translate(50px, 0)。注意,在开发者工具 DevTools 中修改 translate() 的参数值貌似会沿着某个倾斜的坐标轴进行平移,而非正常期望的方向;这是因为先执行的是平移变换、后执行的旋转变换。同理,人们通常也习惯先执行 scale() 变换、再执行 translate() 变换。

16.1.3 单个变换属性的设置 Individual transform properties

CSS 最常见的三个独立的变换属性分别为 translaterotatescale。对于简单的变换效果,使用它们往往更加简便;而对于倾斜变换、以及后续将会介绍的一些更高级的 3D 变换效果,CSS 则没有提供单独的样式属性。

根据代码清单 16.4 同步更新本地样式表。该代码启用了单独的 translate 属性和 rotate 属性来实现上个示例所演示的变换效果。

代码清单 16.4 单个变换属性的用法示例

.card {
  max-inline-size: 300px;
  padding: 0.5em;
  margin-inline: auto;
  background-color: white;
  translate: 50px 0;
  rotate: 15deg;
}

当存在多个单独的变换属性声明时,首先生效的应该是 scale 倾斜变换,其次为 rotate 旋转变换、最后生效的应该是 translate 平移变换;这往往是最简单的工作顺序。这三个变换属性会在其他利用 transform 属性声明的样式生效后再生效。

通常,无论是在设计简单变换效果的时候,还是希望单独对其中的某个变换添加过渡或动画特效的时候,我都更倾向于启用这三个独立属性。在后续构建的示例页中我还会给出几个这样的示例。另一方面,当我想修改变换效果的顺序、或者希望对它们同时使用过渡/动画特效时,则会考虑用 transform 属性来实现。



关于《CSS in Depth》(中译本书名《深入解析 CSS》)

第 1 版第 2 版
读者评分原版:4.7(亚马逊);中文版:9.3(豆瓣)原版:5.0(亚马逊);中文版:暂无,待出版
出版时间原版:2018 年 3 月;中文版:2020 年 4 月原版:2024 年 7 月;中文版:暂无,待出版
原价原版:$44.99;中文版:¥139.00原版:$59.99;中文版:暂无,待出版
现价原版:$36.49;中文版:¥52.54 起步原版:$52.09;中文版:暂无,待出版
原版国内预订起步价 ¥461.00起步价 ¥750.00

本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!

目前已完结的章节(可进入本专栏查看详情,连载期间完全免费):

  • 第一章 层叠、优先级与继承(已完结)
    • 1.1 层叠
    • 1.2 继承
    • 1.3 特殊值
    • 1.4 简写属性
    • 1.5 CSS 渐进式增强技术
    • 1.6 本章小结
  • 第二章 相对单位(已完结)
    • 2.1 相对单位的威力
    • 2.2 em 与 rem
    • 2.3 告别像素思维
    • 2.4 视口的相对单位
    • 2.5 无单位的数值与行高
    • 2.6 自定义属性
    • 2.7 本章小结
  • 第三章 文档流与盒模型(已完结)
    • 3.1 常规文档流
    • 3.2 盒模型
    • 3.3 元素的高度
    • 3.4 负的外边距
    • 3.5 外边距折叠
    • 3.6 容器内的元素间距问题
    • 3.7 本章小结
  • 第四章 Flexbox 布局(已完结)
    • 4.1 Flexbox 布局原理
    • 4.2 弹性子元素的大小
    • 4.3 弹性布局的方向
    • 4.4 对齐、间距等细节处
    • 4.5 本章小结
  • 第五章 网格布局(已完结)
    • 5.1 构建基础网格
    • 5.2 网格结构剖析 (上)
      • 5.2.1 网格线的编号(下)
      • 5.2.2 网格与 Flexbox 配合(下)
    • 5.3 两种替代语法
      • 5.3.1 命名网格线
      • 5.3.2 命名网格区域
    • 5.4 显式网格与隐式网格(上)
      • 5.4.1 添加变化 (中)
      • 5.4.2 让网格元素填满网格轨道(下)
    • 5.5 子网格(全新增补内容)
    • 5.6 对齐相关的属性
    • 5.7 本章小结
  • 第六章 定位与堆叠上下文(已完结)
    • 6.1 固定定位
      • 6.1.1 创建一个固定定位的模态对话框
      • 6.1.2 在模态对话框打开时防止屏幕滚动
      • 6.1.3 控制定位元素的大小
    • 6.2 绝对定位
      • 6.2.1 关闭按钮的绝对定位
      • 6.2.2 伪元素的定位问题
    • 6.3 相对定位
      • 6.3.1 创建下拉菜单(上)
      • 6.3.2 创建 CSS 三角形(下)
    • 6.4 堆叠上下文与 z-index
      • 6.4.1 理解渲染过程与堆叠顺序(上)
      • 6.4.2 用 z-index 控制堆叠顺序(上)
      • 6.4.3 深入理解堆叠上下文(下)
    • 6.5 粘性定位
    • 6.6 本章小结
  • 第七章 响应式设计(已完结)
    • 7.1 移动端优先设计原则(上篇)
      • 7.1.1 创建移动端菜单(下篇)
      • 7.1.2 给视口添加 meta 标签(下篇)
    • 7.2 媒体查询(上篇)
      • 7.2.1 深入理解媒体查询的类型(上篇)
      • 7.2.2 页面断点的添加(中篇)
      • 7.2.3 响应式列的添加(下篇)
    • 7.3 流式布局
    • 7.4 响应式图片
    • 7.5 本章小结
  • 第八章 层叠图层及其嵌套
    • 8.1 用 layer 图层来操控层叠规则(上篇)
      • 8.1.1 图层的定义(上篇)
      • 8.1.2 图层的顺序与优先级(下篇)
      • 8.1.3 revert-layer 关键字(下篇)
    • 8.2 层叠图层的推荐组织方案
    • 8.3 伪类 :is() 和 :where() 的用法
    • 8.4 CSS 嵌套的使用
      • 8.4.1 嵌套选择器的使用
      • 8.4.2 深入理解嵌套选择器
      • 8.4.3 媒体查询及其他 @规则 的嵌套
    • 8.5 本章小结
  • 第九章 CSS 的模块化与作用域
    • 9.1 模块的定义
      • 9.1.1 模块和全局样式
      • 9.1.2 一个简单的 CSS 模块
      • 9.1.3 模块的变体
      • 9.1.4 多元素模块
    • 9.2 将模块组合为更大的结构
      • 9.2.1 模块中多个职责的拆分
      • 9.2.2 模块的命名
    • 9.3 CSS 的作用域
      • 9.3.1 CSS 作用域的就近原则
      • 9.3.2 划定作用域的边界
      • 9.3.3 CSS 中的隐式作用域
      • 9.3.4 关于 CSS 作用域与层叠图层
    • 9.4 CSS 模式库
    • 9.5 本章小结
  • 第十章 CSS 容器查询
    • 10.1 容器查询的一个简单示例
      • 10.1.1 容器尺寸查询的用法
    • 10.2 深入理解容器
      • 10.2.1 容器的类型
      • 10.2.2 容器的名称
      • 10.2.3 容器与模块化 CSS
    • 10.3 与容器相关的单位
    • 10.4 容器样式查询的用法
      • 10.4.1 将模块与所在容器解耦
      • 10.4.2 减少重复代码
    • 10.5 本章小结
  • 第 11 章 颜色与对比
    • 11.1 通过对比进行交流
      • 11.1.1 模式的建立
      • 11.1.2 还原设计稿
    • 11.2 颜色的定义
      • 11.2.1 色域与色彩空间
      • 11.2.2 CSS 颜色表示法(RGB、Hex、HSL、HWB、LAB/OKLAB、LCH/OKLCH)
    • 11.3 利用 OKLCH 处理颜色(上篇)
      • 11.3.4 从页面其他颜色衍生出新颜色(下篇)
    • 11.4 思考字体颜色的对比效果
    • 11.5 本章小结
  • 第 12 章 CSS 排版与间距
    • 12.1 间距设置
      • 12.1.1 使用 em 还是 px
      • 12.1.2 对行高的深入思考
      • 12.1.3 行内元素的间距设置
    • 12.2 Web 字体
    • 12.3 谷歌字体
    • 12.4 @font-face 的工作原理
      • 12.4.1 字体格式与回退处理
      • 12.4.2 同一字型的多种变体形式
    • 12.5 性能因素考量
      • 12.5.1 font-display 属性解析
      • 12.5.2 可变字体的用法
    • 12.6 调整字间距,提升可读性
      • 12.6.1 正文的字间距
      • 12.6.2 标题、小元素和间距
    • 12.7 本章小结
  • 第 13 章 渐变、阴影与混合模式
    • 13.1 渐变
      • 13.1.1 使用多个颜色节点(上)
      • 13.1.2 颜色插值方法(中)
      • 13.1.3 径向渐变(下)
      • 13.1.4 锥形渐变(下)
    • 13.2 阴影
      • 13.2.1 利用渐变和阴影打造立体感
      • 13.2.2 使用扁平化设计创建元素
      • 13.2.3 创建混合风格的按钮外观
    • 13.3 混合模式
      • 13.3.1 为图片上色
      • 13.3.2 混合模式的类型
      • 13.3.3 图片纹理的添加
      • 13.3.4 融合混合模式的用法
    • 13.4 本章小结
  • 第 14 章 蒙版、形状与剪切
    • 14.1 滤镜
      • 14.1.1 滤镜的类型
      • 14.1.2 背景滤镜
    • 14.2 蒙版
      • 14.2.1 带渐变效果的蒙版特效
      • 14.2.2 基于亮度来定义蒙版
      • 14.2.3 其他蒙版属性
    • 14.3 剪切路径
      • 14.3.1 多边形的裁剪路径
      • 14.3.2 Firefox 内置的剪切路径工具
      • 14.3.3 其他剪切路径类型
    • 14.4 浮动与形状
      • 14.4.1 浮动
      • 14.4.2 形状的定义
    • 14.5 本章小结
  • 第 15 章 过渡
    • 15.1 状态间的由此及彼
    • 15.2 定时函数
      • 15.2.1 定制贝塞尔曲线
      • 15.2.2 阶跃
    • 15.3 非动画属性
      • 15.3.1 不可添加动画效果的属性
      • 15.3.2 淡入与淡出
    • 15.4 过渡到自然高度
    • 15.5 自定义属性的过渡设置
    • 15.6 本章小结
  • 附录
    • 附录A:CSS 选择器参考
    • 附录B:CSS 预处理器简介
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安冬的码畜日常

您的鼓励是我持续优质内容的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值