一. CSS属性 - transform
1. 定义
CSS
transform
属性允许对某一个元素进行某些形变, 包括旋转,缩放,倾斜或平移等transform
是形变的意思,transformer
就是变形金刚
注意:
- 并非所有的盒子都可以进行
transform
的转换(通常行内级元素不能进行形变)transform
是对元素进行形变,不影响标准流中其他元素的布局- 同一元素设置多个
transform
属性,只会生效最后设置的那一个transform
对于行内级非替换元素是无效的,如对span
、a
元素等

2. transform的用法
transform
属性的语法如下:- 常见的函数
transform function
有:- 平移:
translate(x, y)
- 缩放:
scale(x, y)
- 旋转:
rotate(deg)
- 倾斜:
skew(deg, deg)
- 平移:
- 常见的函数
3. 位移 - translate
平移:
translate(x, y)
- 这个
CSS
函数用于移动元素在平面上的位置 translate
本身可以表示翻译的意思,在物理上也可以表示平移
- 这个
值个数:
- 一个值时,设置x轴上的位移
- 二个值时,设置x轴和y轴上的位移
值类型:
数字:100px
百分比:参照元素本身(
refer to the size of bounding box
)
4. translate的补充
补充一:
translate
是translateX
和translateY
函数的简写translate3d
后续了解
补充二:两个相同的
transform
,后者会覆盖前者设置的值csstransform: translateX(10px); /* 覆盖上面的 */ transform: translateY(10px);
补充二:
translate
的百分比可以完成一个元素的水平和垂直居中:css.box3 { position: relative; top: 50%; transform: translate(0, -50%); width: 100px; height: 100px; background-color: #f00; }
translate
函数相对于flex
布局的兼容性会好一点点不过目前
flex
布局已经非常普及,直接使用flex
布局即可
5. 缩放 - scale
缩放:
scale(x, y)
scale() CSS
函数可改变元素的大小
值个数:
- 一个值时,设置
x
轴和y
轴上的缩放 - 二个值时,也是设置
x
轴和y
轴上的缩放,只不过可以设置不一样而已
- 一个值时,设置
值类型:
- 数字:
- 0.5:缩小一半 2:放大一倍
- 百分比:
50%
跟数字0.5
的效果是一样的
- 数字:
scale
函数时scaleX
和scaleY
的缩写:scale3d
后续再了解
6. 旋转 - rotate
旋转:
rotate(<angle>)
值个数:
- 一个值时,表示旋转的角度,如:
45deg
,顺时针旋转45°
- 一个值时,表示旋转的角度,如:
值类型:
常用单位
deg
:旋转的角度(degrees
)正数为顺时针
负数为逆时针
7. rotate补充
补充一:
rotate
函数是rotateZ
的简写写法rotate3d
后续再了解
补充二:
rotate
的其他单位度(
degrees
)、百分度(gradians
)、弧度(radians
)或圈数(turns
)
8. transform-origin
transform-origin
:形变的原点比如在进行
scale
缩放或者rotate
旋转时,都会有一个原点(默认是元素中心点center
)
值的个数:
- 一个值:设置
x
轴的原点 - 两个值:设置
x
轴和y
轴的原点
- 一个值:设置
值的类型:
left, center, right, top, bottom
关键字length
:从左上角开始计算- 百分比:参考元素本身大小
9. 倾斜 - skew
倾斜:
skew(x, y)
函数定义了一个元素在二维平面上的倾斜转换
值个数:
- 一个值时,表示
x
轴上的倾斜 - 二个值时,表示
x
轴和y
轴上的倾斜
- 一个值时,表示
值类型:
deg
:倾斜的角度- 正数往左侧(逆时针)倾斜
- 负数往右侧(顺时针)倾斜
注意:倾斜的原点受
transform-origin
的影响
10. transform设置多个值
- 前面我们看到了
transform
的语法,它是可以设置多个transform-function
的:<transform-function>+
+
:一个或者多个,并且多个之间以空格
分隔transform: scale() translate();
<box-shadow>#
#
:一个或者多个,多个之间以,
分隔box-shadow: 1px 1px 1px 1px #f00,
那么就意味着,我们可以给
transform
设置多个形变的函数
二. 元素的水平和垂直居中方案
1. 水平居中
行内级元素(
inline / inline-block
)- 设置父元素的
text-align: center
- 设置父元素的
块级元素(
block
)- 元素有宽度的情况下,设置
margin: 0 auto
(为了保持block
元素独占一行的特性,浏览器会将水平方向的外边距平分给margin-right/left
) margin-left: 50%; transform: translateX(-50%)
- 元素有宽度的情况下,设置
行内块级元素(
inline-block
)- 设置父元素的
text-align: center
margin-left: 50%; transform: translateX(-50%)
- 设置父元素的
绝对定位元素(
absolute / fixed
)- 元素有宽度的情况下,设置
left0、right0、margin: 0 auto
- 元素有宽度的情况下,设置
flex
元素justify-content: center
2. 垂直居中
- 绝对定位元素(
absolute / fixed
)- 元素有高度的情况下,
top0、bottom0、margin: auto 0
- 弊端:
- 必须使用绝对定位(脱离标准流
normal flow
) - 必须给元素设置高度
- 必须使用绝对定位(脱离标准流
- 元素有高度的情况下,
flex
元素align-items: center
- 弊端:
- 当前
flex
局部中所有的item
元素都会被垂直居中 - 有一点点兼容性问题,
IE 6-9
不兼容,现在基本不需要考虑兼容IE
了
- 当前
- 定位元素 +
top
+translateY
top: 50%、transform: translateY(-50%)
- 这里为什么不使用
margin-top
呢?因为margin
百分比相对的是包含块的宽度 - 好处:
- 没有兼容性问题,元素设置相对定位,不会产生脱标问题
三. transition动画
1. 什么是transition动画
CSS transitions
提供了一种在更改CSS
属性时控制动画速度的方法可以让
CSS
属性变化成为一个持续一段时间的过程,而不是立即生效的比如将一个元素从一个位置移动到另外一个位置,默认在修改完
CSS
属性后会立即生效但是我们可以通过
CSS transition
,让这个过程加上一定的动画效果,包括一定的曲线速率变化通常将两个状态之间的过渡称为隐式过渡(
implicit transitions
),因为开始与结束之间的状态由浏览器决定- 译文:
CSS transition
告诉浏览器在初始和结束状态之间绘制中间状态,从而显示给用户一个丝滑的过渡
- 译文:
CSS transitions
可以决定:- 哪些属性发生动画效果 (明确地列出这些属性)
- 何时开始 (设置
delay
) - 持续多久 (设置
duration
) - 如何动画 (定义
timing function
,比如匀速地或先快后慢)
补充:
transition
可以不用厂商前缀,不过鉴于标准刚刚稳定,对于基于Webkit
的浏览器仍然需要厂商前缀如果想兼容旧版本的浏览器那么也需要厂商前缀(例如 Firefox 15 及之前版本,Opera 12 及之前版本)。详情见https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
auto
值常常较复杂,规范指出不要在它上动画。一些用户代理,比如基于Gecko
的,遵循这点;一些,比如基于WebKit
的,没有这么严格限制。在auto
上动画结果可能不可预期,这取决于浏览器及其版本,应当避免使用同时应当留意这种情形,在插入元素(如
.appendChild()
)或 改变属性display: none
后立即使用过渡,元素将视为没有开始状态,始终处于结束状态。简单的解决办法,改变属性前用window.setTimeout()
延迟几毫秒当过渡完成时触发一个事件,在符合标准的浏览器下,这个事件是
transitionend
, 在WebKit
下是webkitTransitionEnd
jsel.addEventListener("transitionend", updateTransition, true);
一次性修改多个属性改变,就会触发多次
transitionend
事件
2. 哪些CSS属性可以做动画呢
并非所有的
CSS
属性都可以执行动画的,那么我们如何知道哪些属性支持动画呢?方法一:在
MDN
可执行动画的CSS
属性中查询方法二:阅读
CSS
属性的文档说明
3. 过渡动画 - transition
transition CSS
属性是transition-property,transition-duration,transition-timing-function
和transition-delay
的一个简写属性transition-property
:指定应用过渡属性的名称all
:所有属性都执行动画none
:所有属性都不执行动画(默认值)CSS
属性名称:要执行动画的CSS
属性名称,比如width、left、transform
等
transition-duration
:指定过渡动画所需的时间- 单位可以是秒
s
或毫秒ms
- 单位可以是秒
transition-timing-function
:指定动画的变化曲线transition-delay
:指定过渡动画执行之前的等待时间- 单位可以是秒
s
或毫秒ms
- 单位可以是秒
4. 几个英语词汇的区分
transform
是形变:- 一个
CSS
属性,该CSS
属性用于设置形变 - 后面的值是形变的函数,比如
scale、rotate、translate
- 一个
translate
是其中一个transform-function
- 用于对元素进行平移
transition
是过渡的意思- 它本身也有转变的含义,但是更多表示的是过渡的过程
四. animation动画
1. 认识animation
- 之前我们学习了
transition
来进行过渡动画,但是过渡动画有如下的缺点:transition
只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态transition
不能重复执行,除非一再触发动画transition
需要在特定状态下会触发才能执行,比如某个属性被修改了
- 如果我们希望可以有更多状态的变化,我们可以使用
CSS Animation
CSS Animation
的使用分成两个步骤:- 步骤一:使用
keyframes
定义动画序列(每一帧动画如何执行) - 步骤二:配置动画执行的名称、持续时间、动画曲线、延迟、执行次数、方向等等
- 步骤一:使用
补充:
Webkit
内核浏览器 或者 早期版本浏览器可能需要前缀,-webkit-
前缀
2. keyframes规则
可以使用
@keyframes
来定义多个变化状态,并且使用animation-name
来声明匹配:- 关键帧使用
percentage
来指定动画发生的时间点 0%
表示动画的第一时刻,100%
表示动画的最终时刻- 因为这两个时间点十分重要,所以还有特殊的别名:
from
和to
- 关键帧使用
to
相当于100%
from
相当于0%
to
相当于100%
css@keyframes moveAnim { 0% { transform: translate(0, 0); } 33% { transform: translate(0, 200px); } 66% { transform: translate(200px, 200px); } 100% { transform: translate(200px, 0); } }
3. animation属性
CSS animation
属性是animation-name
、animation-duration
、animation-timing-function
、animation-delay
、animation-iteration-count
、animation-direction
、animation-fill-mode
和animation-play-state
属性的一个简写属性形式属性 含义 animation-name
指定执行哪一个关键帧动画 animation-duration
指定动画的持续时间 animation-timing-funtion
指定动画的变化曲线 animation-delay
指定延迟执行的时间 animation-iteration-count
指定动画执行的次数, infinite
表示无限次animation-direction
指定方向,常用值 normal
和reverse
animation-fill-mode
执行动画最后保留哪一个值 none
(默认值):执行完动画后元素保持在 未执行动画时的初始状态forwards
:执行完动画后元素保持在 动画最后一帧的状态backwards
:执行完动画后元素保持在 未执行动画时的初始状态both
:效果跟forwards
类似animation-play-state
指定动画运行或暂停(一般在 js
中使用,用于控制动画播放暂停)cssanimation: moveAnimation1 1000 liner 500 2 normal forwards;
总结:
none
跟backwards
的效果相同,都是会在动画执行完之后,恢复未执行动画时的初始状态- 区别是:
backwards
会在动画应用于元素时,立即应用第一帧中定义的值,而none
不会forwards
跟both
的效果相同,都是会在动画执行完之后,保持在动画最后一帧的状态- 区别是:
both
会在动画应用于元素时,立即应用第一帧中定义的值,而forwards
不会- 综上所述,平常开发中用的最多的是
both
注意:
@keyframes
中元素应用的样式,即使后续有主动给元素添加同属性的样式,是不生效的css.box { width: 200px; height: 200px; background-color: skyblue; } .fadeOut { animation: fadeOut 5s ease both; } @keyframes fadeOut { from { opacity: 1; } to { background-color: yellow; opacity: .2; } }
html<div class="box fadeOut"></div> <script> onload = function() { console.log('文档加载完') let box = document.querySelector('.box') box.addEventListener('animationend', () => { console.log('动画执行完') box.style.opacity = 1 // dom中可以发现该内联样式已添加,但在css计算的时候,并未使用该值 box.style.backgroundColor = 'skyblue' // dom中可以发现该内联样式已添加,但在css计算的时候,并未使用该值 }) } </script>
解决办法:
方法一(不推荐):直接重置
animation
属性jsonload = function() { console.log('文档加载完') let box = document.querySelector('.box') box.addEventListener('animationend', () => { console.log('动画执行完') box.style.animation = 'none' // 缺点:会在内联样式中添加所重置animation相关的所有的属性 box.style.opacity = 1 box.style.backgroundColor = 'yellow' }) }
方式二(推荐):通过移除该动画类即可
jsonload = function() { console.log('文档加载完') let box = document.querySelector('.box') box.addEventListener('animationend', () => { console.log('动画执行完') box.classList.remove('fadeOut') box.style.opacity = 1 box.style.backgroundColor = 'skyblue' }) }
动画示例:
- 帧动画: 在 codesandbox 中预览
五. vertical-align
1. 行盒(line boxes )

- 官方文档的翻译:
vertical-align
会影响行内级元素在一个行盒中垂直方向的位置 - 思考:一个
div
没有设置高度的时候,会不会有高度?- 没有内容,没有高度
- 有内容,内容撑起来高度
- 但是内容撑起来高度的本质是什么呢?
- 内容有行高(
line-height
:一行文字所占据的高度),撑起来了div
的高度
- 内容有行高(
- 行高为什么可以撑起
div
的高度?- 这是因为
line boxes
的存在,并且line-boxes
有一个特性,包裹每行的inline level
- 而其中的文字是有行高的,必须将整个行高包裹进去,才算包裹这个
line-level
- 这是因为
- 把一行中所有内容包裹起来的一个隐性盒子叫行盒
- 在不设置具体高度的情况下,元素高度是由其内容决定的,而本质上是由内容中每一行的行高之和决定的
- 行盒的高度等于
line-height
- 那么,进一步思考:
- 如果这个
div
中有图片,文字,inline-block
,甚至他们设置了margin
这些属性呢?
- 如果这个
2. 不同情况分析
情况一:只有文字时,
line boxes
如何包裹内容?(注意:红色是包裹的div
,下面也都一样)情况二:有图片,有文字时,
line-boxes
如何包裹内容?情况三:有图片,有文字,有
inline-block
(比图片要大)如何包裹内容?情况四:有图片,有文字,有
inline-block
(比图片要大)而且设置了margin-bottom
,如何包裹内容?情况五:有图片、文字、
inline-block
(比图片要大)而且设置了margin-bottom
并且有文字,如何包裹内容?
3. baseline
结论:
line-boxes
一定会想办法包裹住当前行中所有的内容但是,但是为什么对齐方式千奇百怪呢?
- 你认为的千奇百怪,其实有它的内在规律
- 答案就是
baseline
对齐
我们来看官方
vertical-align
的默认值:没错,就是baseline
但是
baseline
都是谁呢?- 文本的
baseline
- 是字母
x
的下方
- 是字母
- 没有基线的元素(如图片等
inline
可替换元素)- 使用外边距的下边缘替代
inline-block
内部没有文字时的baseline
- 默认是
margin-bottom
的底部(没有margin-bottom
,就是盒子的底部)
- 默认是
inline-block
有文本时- 是最后一行文本的
x
的下方
- 是最后一行文本的
- 文本的
4. vertical-align的其他值
vertical-align
用来指定行内元素(inline
)或表格单元格(table-cell
)元素的垂直对齐方式属性值 含义 baseline
(默认值)基线对齐(你得先明白什么是基线) top
把行内级盒子的顶部跟 line boxes
顶部对齐middle
行内级盒子的中心点与父盒基线加上 x
英文字母的height
一半的线对齐bottom
把行内级盒子的底部跟 line box
底部对齐<percentage>
把行内级盒子提升或下降一段距离(距离相对于 line-height
计算\元素高度),0%
意味着同baseline
一样<length>
把行内级盒子提升或者下降一段距离, 0cm
意味着同baseline
一样解决图片下边缘的间隙方法:
- 方法一:
vertical-align
设置成top/middle/bottom
- 方法二:将图片设置为
block
元素,block
不受vertical
影响,因为是独占父元素的一行,所以不存在像同一行中的行内级元素在一个行盒中可调整垂直方向的位置这样的说法
- 方法一: