一. CSS属性 - transform
1. 定义
CSStransform属性允许对某一个元素进行某些形变, 包括旋转,缩放,倾斜或平移等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+translateYtop: 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下是webkitTransitionEndjsel.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和reverseanimation-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影响,因为是独占父元素的一行,所以不存在像同一行中的行内级元素在一个行盒中可调整垂直方向的位置这样的说法
- 方法一:
