CSS属性 - transform

  • CSS transform 属性允许对某一个元素进行某些形变、包括旋转、缩放、倾斜或者平移等。
  • transform 是形变的意思,transformer 就是变形金刚
  • 注意事项:并非所有的盒子都可以进行 transform 的转换(通常行内级元素不能进行形变)

  • 所以,transform 对于行内级非替换元素是无效的
    • 比如对 spana元素等

transform 的用法

  • transform 属性的语法如下:

    • .box{ transform: transform-list; }
  • 常见的 transform function 有:

    • 平移:translate(x,y)
    • 缩放:scale(x,y)
    • 旋转:rotate(deg)
    • 倾斜:skew(deg,deg)

位移-translate

  • 平移:translate(x,y)
    • 这个 CSS 函数用于移动元素在平面上的位置
    • translate 本身可以表示翻译的意思,在物理上也可以表示平移
  • 值的个数
    • 一个值时,设置 x 轴上的位移
    • 两个值时,设置 x 轴 和 y 轴上的位移
  • 值类型
    • 数字:100px
    • 百分比:参照元素本身(Percentages:refer to the size of bounding box)
<!DOCTYPE html>  
<html lang="en">  
<head>  
 <meta charset="UTF-8">  
 <meta http-equiv="X-UA-Compatible" content="IE=edge">  
 <meta name="viewport" content="width=device-width, initial-scale=1.0">  
 <title>Document</title>  
 <style>  
  .container {  
      display: inline-block;  
      border: 5px solid #f00;  
  }  
  .container .box {  
      width: 200px;  
      height: 200px;  
      background-color: orange;  
  
      /* 百分比:相对于谁?*/  
      /* 不同地方的百分比相对参照物是不一样的 */      /* transform的百分比是相对于自己的  
     设置x轴参考的是自身的宽度  
     设置y轴参考的是自身的高度  
    */      /*transform: translate(100px, 100px);*/      transform: translate(100%, 100%);  
    /*transform: translateX(100%);  
    transform: translateY();*/  }  
 </style>  
</head>  
<body>  
  
<div class="container">  
 <div class="box">  
  
 </div>  
</div>  
</body>  
</html>

translate 的 补充

  • 补充一:translatetranslateXtranslateY 函数的简写
    • 还有一个 `
  • 补充二:translate 的百分比可以完成一个元素的水平和垂直居中
  • translate 函数相对于 flex 布局的兼容性会好一点点
    • 不过目前 flex 布局已经非常的普及,直接使用 flex 布局即可
<!doctype html>  
<html lang="zh">  
<head>  
 <meta charset="UTF-8">  
 <meta name="viewport"  
       content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  
 <meta http-equiv="X-UA-Compatible" content="ie=edge">  
 <title>Document</title>  
 <style>  
  .container {  
      /*position: relative;*/  
      /* display: flex;    align-items: center;*/  
      height: 300px;  
      background-color: orange;  
  }  
  .box1 {  
      position: absolute;  
      width: 100px;  
      /*height: 100px;*/  
      top: 0;  
      bottom: 0;  
      margin: auto 0;  
      background-color: #f00;  
  }  
  .box2 {  
      background-color: #ff0000;  
  }  
  .box3 {  
      display: inline-block;  
      height: 100px;  
      background-color: #ff0000;  
  
      position: relative;  
      top: 50%;  
      transform: translate(0, -50%);  
  } </style>  
</head>  
<body>  
<!--  
    水平居中:  
      1.行内级元素:  
          设置父元素的text-align:center;  
      2.块级元素:  
          设置当前块级元素(有宽度):margin: 0 auto;  
      3.绝对定位:  
          元素有宽度的情况下,left:0;/right:0;/margin:0 auto;  
      4.flex          justify-content:center; -->  
<!--  
    垂直居中:  
      1.绝对定位  
          元素有高度的情况下,top:0;/bottom:0;/margin: auto 0;  
          缺点:  
            1.必须使用定位(脱离标准流)  
            2.必须给元素设置高度  
            <div class="container">       <div class="box1"></div>      </div>   2.flex布局  
    缺点:  
     1.当前flex布局中的所有元素都会被垂直居中  
     2.相对来说兼容性差一点(基本可以忽略)  
   3.top/translate(推荐,但是不好理解)  
     让元素向下位移父元素的50%,然后再让元素向上移动自身的50%  
      position: relative;         top: 50%;         transform: translate(0, -50%); -->  
<div class="container">  
 <!-- <div class="box1"></div>  
 <div class="box2"></div> --> <div class="box3">rinsan</div>  
</div>  
</body>  
</html>

缩放 - scale

  • 缩放:scale(x,y)
    • scale() CSS 函数可以改变元素的大小
  • 值的个数
    • 一个值时,设置 x 轴上的缩放
    • 两个值时,设置 x 轴 和 y 轴上的缩放
  • 值类型
    • 数字:
      • 1 保持不变
      • 2 放大一倍
      • 0.5 缩小一半
    • 百分比: 60%0.6 效果一致,但是百分比不常用
  • scale函数是 scaleXscaleY 的缩写
    • 还有一个 scale3d
<!doctype html>  
<html lang="zh">  
<head>  
 <meta charset="UTF-8">  
 <meta name="viewport"  
       content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  
 <meta http-equiv="X-UA-Compatible" content="ie=edge">  
 <title>Document</title>  
 <style>  
  body {  
      text-align: center;  
      padding-top: 200px;  
  }  
  .container {  
      display: inline-block;  
      border: 20px solid #f00;  
  }  
  .box {  
      border: 20px solid #0f0;  
      width: 200px;  
      height: 200px;  
      background-color: orange;  
  
      /* 形变 */      transform: scale(60%, 60%);  
  }  
  .box2 {  
      border: 20px solid #0f0;  
      width: 200px;  
      height: 200px;  
      background-color: purple;  
  
      /* 形变 */      /* 0~1 对元素进行缩小 */      /* 大于1 对元素进行放大 */      /*transform: scale(0.6, 0.6);*/  }  
  
  .box2:hover {  
      transform: scale(1.1, 1.1)  
  } </style>  
</head>  
<body>  
<div class="container">  
 <div class="box"></div>  
</div>  
<div class="container">  
 <div class="box2"></div>  
</div>  
</body>  
</html>

旋转 - rotate

  • 旋转:rotate(<angle>)

  • 值的个数:

    • 只有一个,表示旋转的角度
  • 值类型

    • 常用单位 deg:旋转的角度(degrees
    • 正数为顺时针
    • 负数为逆时针

rotate 补充

补充一:rotate 函数是 rotateZ 函数的简写写法
- rotate3d

补充二:rotate 的其他单位
- 事实上 rotate 支持的单位是很多的
- 度(degrees)、百分度(gradians)、弧度(radians)或圈数(turns

<!doctype html>  
<html lang="zh">  
<head>  
 <meta charset="UTF-8">  
 <meta name="viewport"  
       content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  
 <meta http-equiv="X-UA-Compatible" content="ie=edge">  
 <title>Document</title>  
 <style>  
  body {  
      text-align: center;  
      padding-top: 200px;  
  }  
  .container {  
      display: inline-block;  
      border: 10px solid red;  
  }  
  .box {  
      width: 200px;  
      height: 100px;  
      background-color: orange;  
  }  
  .box:hover {  
      /*transform: rotate(-45deg);*/  
      transform: rotate(-1.5078rad);  
  } </style>  
</head>  
<body>  
<div class="container">  
 <div class="box"></div>  
</div>  
</body>  
</html>

transform-origin 原点位置

transform-origin:形变的原点
- 比如在进行 scale 缩放或者 rotate 旋转时,都会有一个原点

只有一个值时
- 设置 x 轴的原点

有两个值时
- 设置 y 轴的原点

必须是<length>,<percentage>,或 left,center,right,top,bottom 关键字中的一个
- left/center/right/top/bottom 关键字
- length:从左上角开始计算
- 百分比:参考元素本身大小

<!doctype html>  
<html lang="zh">  
<head>  
 <meta charset="UTF-8">  
 <meta name="viewport"  
       content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  
 <meta http-equiv="X-UA-Compatible" content="ie=edge">  
 <title>Document</title>  
 <style>  
  body {  
      text-align: center;  
      padding-top: 200px;  
  }  
  .container {  
      display: inline-block;  
      border: 10px solid red;  
  }  
  .box {  
      width: 200px;  
      height: 100px;  
      background-color: orange;  
  
      /* 修改当前元素的形变的原点位置 */      /*transform-origin: center top;*/      /*transform-origin: 20px 20px;*/      transform-origin: 10% 10%;  
  }  
  .box:hover {  
      transform: rotate(45deg) scale(0.5);  
  } </style>  
</head>  
<body>  
<div class="container">  
 <div class="box"></div>  
</div>  
</body>  
</html>

倾斜 - skew

倾斜:skew(x,y)
- 函数定义了一个元素在二维平面上的倾斜转换

值的个数
- 一个值时,表示 x 轴上的倾斜
- 两个值时,表示 x 轴和 y 轴上的倾斜

值类型
- deg:倾斜的角度
- 正数为顺时针
- 负数为逆时针

<!doctype html>  
<html lang="zh">  
<head>  
 <meta charset="UTF-8">  
 <meta name="viewport"  
       content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  
 <meta http-equiv="X-UA-Compatible" content="ie=edge">  
 <title>Document</title>  
 <style>  
  .box {  
      font-size: initial;  
      width: 200px;  
      height: 100px;  
      background-color: orange;  
  }  
  .box:hover {  
      transform: skew(10deg, 10deg);  
  } </style>  
</head>  
<body>  
<div class="box">我是div元素</div>  
</body>  
</html>

transform 设置多个值

<!doctype html>  
<html lang="zh">  
<head>  
 <meta charset="UTF-8">  
 <meta name="viewport"  
       content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  
 <meta http-equiv="X-UA-Compatible" content="ie=edge">  
 <title>Document</title>  
 <style>  
  .box {  
      width: 200px;  
      height: 100px;  
      background-color: orange;  
      /*box-shadow: 1px 1px 1px 1px #f00;*/  
  }  
  
  .box:hover {  
      /*transform: translateX(50px);  
      transform: scale(1.2);    transform: rotate(45deg);*/   /*     位移              缩放         旋转   */      transform: translate(50px) scale(1.2) rotate(45deg);  
  
      /*  
    <transform-function>+     +: 一个或者多个,并且多个之间以空格分隔  
       transform: scale() translate();     <box-shadow>#      #: 表示一个或者多个,多个之间使用 , 号分隔  
      box-shadow: 1px 1px 1px 1px #f00;   */  }  
 </style>  
</head>  
<body>  
<div class="box"></div>  
</body>  
</html>

CSSTransition的介绍和可动画属性

认识 transition 动画

什么是 transition 动画
- CSS transition 提供了一种在更改 CSS 属性时控制动画速度的方法
- 可以让 CSS 属性变化成为一个持续一段时间的过程,而不是立即生效
- 比如讲一个元素从一个位置移动到另一个位置,默认在修改完 CSS 属性后会立即生效
- 但是可以通过 CSS transition ,让这个过程加上一定的动画效果,包括一定的曲线速率变化

通常将两个状态之间的过渡称为隐式过渡(implicit transitions),因为开始与结束之间的状态由浏览器决定。

CSS transitions 可以决定
- 那些属性发生动画效果(明确的列出这些属性)
- 何时开始(设置 delay
- 持续多久(设置 duration
- 如何动画(定义 timing function,比如匀速的先快后慢)

哪些 CSS 属性可以做动画呢?

并非所有的属性都是可动画的,可以在mdn上查询可动画的属性
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_animated_properties

或者在阅读 CSS 文档的时候可以查看是否支持

CSS Transition 的常见属性

过渡动画 - transition

transition CSS 属性是 transition-property, transition-duration, transition-timing-function 和 transition-delay 的一个简写属性。

transition-property:指定过渡属性的名称
- all:所有属性都执行动画
- none:所有属性都不执行动画
- CSS 属性名称:要执行动画的 CSS 属性名称,比如 widthlefttransform

transition-duration:指定过渡动画所需的时间
- 单位可以是秒(s)或者毫秒(ms)

transition-timing-function:指定动画的执行曲线
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/transition-timing-function

transition-delay:指定过渡动画执行的等待时间

几个英语单词的区分

transform 是形变:
- 一个 CSS 属性,该 CSS 属性用于设置形变
- 后面的值时形变的函数,比如 scalerotatetranslate

translate 是其中一个 transform-function
- 用于对元素进行平移

transition 是过渡的意思
- 它本身也有转变的含义,但是更多表示的是过渡的过程

认识 CSS Animation

transition 可以用来做过渡动画,但是过渡动画有如下的确定:
- transition 只能定义开始和结束状态,不能定义中间状态,也就是说只有两个状态
- transition 不能重复执行,除非再次触发动画
- transition 需要在特定的状态下才能执行,比如某个属性被修改了

如果我们希望可以有更多状态的变化,就需要使用 CSS Animation

CSS Animation 的使用分成两个步骤
- 步骤一:使用 keyframes 定义动画序列(每一帧动画如何执行)
- 步骤二:配置动画执行的名称、持续时间、动画曲线、延迟、执行次数、方向等等

frame 帧
动画或者说视频本质就是一张张的图片
比如电影的 24帧/30帧/120帧
30fps -> frame per second,相当于每秒30张图片
如果小于 16fps 人眼就能明显感觉到卡顿

@keyframes 规则

可以使用 @keyframes 来定义多个变化状态,并且使用 animation-name 来声明匹配:
- 关键帧使用 percentage 来指定动画发生的时间点
- 0% 表示动画的第一时刻,100% 表示动画的最终时刻
- 因为这两个时间点十分重要,所以还有特殊的别名: formto

也即是可以使用 fromto 关键字:
- form 相当于 0%
- to 相当于 100%

animation 属性

CSS animation 属性有 animation-name、animation-duration、animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state: paused

  • animation-name:指定执行哪一个关键帧动画
  • animation-duration:指定动画持续的时间
  • animation-timing-function:指定动画的变化曲线
  • animation-delay:指定延迟执行的时间
  • animation-iteration-count:指定动画执行的次数
  • animation-direction:指定动画执行方向,常用值 normalreverse
  • animation-fill-mode:执行动画最后保留哪一个值
    • none:回到没有执行动画之前的位置
    • forwards:动画最后一帧的位置
    • backwards:动画第一帧的位置
  • animation-play-state: paused:指定动画运行或者暂停(配合 JavaScript 使用,用于暂停动画)
<!doctype html>  
<html lang="zh">  
<head>  
 <meta charset="UTF-8">  
 <meta name="viewport"  
       content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  
 <meta http-equiv="X-UA-Compatible" content="ie=edge">  
 <title>Document</title>  
 <style>  
  .box {  
      width: 200px;  
      height: 100px;  
      background-color: orange;  
  
      /* box 要执行 moveAnim 的动画  */      animation-name: moveAnim;  
      animation-duration: 3s;  
      animation-timing-function: ease-in-out;  
  
      /* animation-delay: 2s; */  
      /* 其他属性  */      /* 动画执行的次数 */      /*animation-iteration-count: 2;*/      /* 动画执行的方向 */      /*animation-direction: reverse;*/      /* 元素停留在动画的那个位置  forwards:停留在最后一个位置 */      /*animation-fill-mode: backwards;*/      /* js 动态修改 paused:暂停 */      /*animation-play-state: paused;*/  
      /* 简写属性 */      /*animation: moveAnim 3s linear 1s 2 normal forwards;*/  }  
  
  @keyframes moveAnim {  
      0% {  
          transform: translate(0, 0) scale(0.5, 0.5);  
      }      33% {  
          transform: translate(0, 200px) scale(1.2, 1.2);  
      }      66% {  
          transform: translate(400px, 200px) scale(1.1, 1.1);  
      }      100% {  
          transform: translate(400px, 0) scale(0.5, 0.5);  
      }  } </style>  
</head>  
<body>  
<div class="box"></div>  
</body>  
</html>

CSS 属性 - vertical-align

This property affects the vertical positioning inside a line box of the boxes generated by an inline-level element

深入理解 vertical-align —— line boxes

官方文档翻译:vertical-align 会影响 行内块级元素在一个 行盒 中垂直方向的位置

思考:一个 div 没有设置高度的时候,会不会有高度?
- 没有内容,没有高度
- 有内容,内容撑起来高度

但是内容撑起来的高度本质是什么?
- 内容有行高(line-height),撑起来了 div 的高度

行高为什么可以撑起来 div 的高度
- 这是因为 line boxes 的存在,并且 line-boxes 有一个特效,包裹每行的 inline level
- 而其中的文字是有行高的,必须将其整个行高包裹进去,才算包裹整个 inline-level

那么,进一步思考
- 如果这个 div 中图片、文字、inline-block,甚至它们还设置了 margin 这些属性呢?

深入理解 vertical-align —— 不同情况分析

情况一:只有文字时,line boxes 如何包裹内容(注意:红色包裹的 div,下面也都一样)

情况二:有文字,有图片时,line boxes 如何包裹内容

情况三:有文字,有图片、有 inline-block (比图片要大),如何包裹内容

情况四:有文字,有图片、有 inline-block (比图片要大)而且设置了 margin-bottom,如何包裹内容

情况五:有文字、图片、有 inline-block (比图片要大)而且设置了 margin-bottom 并且有文字,如何包裹内容

vertical-align 的 baseline

结论:line-boxes 一定会想办法包裹住当前行中所有的内容

但是,为什么对齐方式不一样呢?
- 其实有它的内在规律
- 答案就是 baseline 对齐

看看官方 vertical-align 的默认值:就是 baseline

但是 baseline 都是谁呢?
- 文本的 baseline 是字母 x 的下面
- inline-block 默认的 baselinemargin-bottom 的底部(如果没有,那就是盒子的底部)
- inline-block 有文本时,baseline 就是最后一行文本的 x 的下方

vertical-align 的其他值

现在,对于不同的取值就非常容易理解了
- baseline(默认值):基线对齐(明白什么是基线)
- top:把行内级盒子的顶部跟 line boxes 顶部对齐
- middle:行内级盒子的中心与父盒子基线加上 x-height 一半的线对齐(而x在实际中是会有下沉一点的,所以设置 middle 并不能让元素对齐)
- bottom:把行内级盒子的底部和 line boxes 底部对齐
- <percentage>:把行内级盒子提升或者下降一段距离(距离相对于 line-height 计算\元素高度),0% 意味着和 baseline一样
- <length>:把行内级盒子提升或者下降一段距离,0cm 意味着和 baseline一样

解决图片下边缘的间隙方法:
- 方法一:设置 top/middle/bottom
- 方法二:将图片设置为 block 元素

Q.E.D.