Skip to content

一. CSS属性 - transform


1. 定义

  • CSS transform属性允许对某一个元素进行某些形变, 包括旋转,缩放,倾斜或平移等

  • transform是形变的意思,transformer就是变形金刚

注意:

  • 并非所有的盒子都可以进行 transform 的转换(通常行内级元素不能进行形变)
  • transform是对元素进行形变,不影响标准流中其他元素的布局
  • 同一元素设置多个transform属性,只会生效最后设置的那一个
  • transform对于行内级非替换元素是无效的,如对spana元素等
image-20220422164730947

2. transform的用法

  • transform属性的语法如下:

    image-20220422165318434image-20220422165332599
    • 常见的函数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

      image-20220422170837180

4. translate的补充

  • 补充一:translatetranslateXtranslateY函数的简写

    • translate3d后续了解
  • 补充二:两个相同的transform,后者会覆盖前者设置的值

    css
    transform: 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 函数可改变元素的大小

      image-20220422184238365
  • 值个数:

    • 一个值时,设置x轴和y轴上的缩放
    • 二个值时,也是设置x轴和y轴上的缩放,只不过可以设置不一样而已
  • 值类型:

    • 数字:
      • 0.5:缩小一半 2:放大一倍
    • 百分比:50%跟数字0.5的效果是一样的
  • scale函数时scaleXscaleY的缩写:

    • scale3d后续再了解

6. 旋转 - rotate

  • 旋转:rotate(<angle>)

  • 值个数:

    • 一个值时,表示旋转的角度,如:45deg,顺时针旋转45°
  • 值类型:

    • 常用单位deg:旋转的角度(degrees

    • 正数为顺时针

    • 负数为逆时针

      image-20220422195608210

7. rotate补充

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

    • rotate3d后续再了解
  • 补充二:rotate的其他单位

    • 度(degrees)、百分度(gradians)、弧度(radians)或圈数(turns)

      image-20220422201859600

8. transform-origin

  • transform-origin:形变的原点

    • 比如在进行scale缩放或者rotate旋转时,都会有一个原点(默认是元素中心点center)

      image-20220422203259559
  • 值的个数:

    • 一个值:设置x轴的原点
    • 两个值:设置x轴和y轴的原点
  • 值的类型:

    • left, center, right, top, bottom关键字
    • length:从左上角开始计算
    • 百分比:参考元素本身大小

9. 倾斜 - skew

  • 倾斜:skew(x, y)

    • 函数定义了一个元素在二维平面上的倾斜转换

      image-20220422222929315
  • 值个数:

    • 一个值时,表示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设置多个形变的函数

      image-20220422223418916

二. 元素的水平和垂直居中方案


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),因为开始与结束之间的状态由浏览器决定

    image-20220422224806263
    • 译文: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

js
el.addEventListener("transitionend", updateTransition, true);

2. 哪些CSS属性可以做动画呢

3. 过渡动画 - transition

  • transition CSS 属性是transition-property,transition-duration,transition-timing-functiontransition-delay的一个简写属性

    image-20220422230749063
  • 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%表示动画的最终时刻
    • 因为这两个时间点十分重要,所以还有特殊的别名:fromto
  • 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-nameanimation-durationanimation-timing-functionanimation-delayanimation-iteration-countanimation-directionanimation-fill-mode animation-play-state 属性的一个简写属性形式

    属性含义
    animation-name指定执行哪一个关键帧动画
    animation-duration指定动画的持续时间
    animation-timing-funtion指定动画的变化曲线
    animation-delay指定延迟执行的时间
    animation-iteration-count指定动画执行的次数,infinite表示无限次
    animation-direction指定方向,常用值normalreverse
    animation-fill-mode执行动画最后保留哪一个值
    none(默认值):执行完动画后元素保持在 未执行动画时的初始状态
    forwards:执行完动画后元素保持在 动画最后一帧的状态
    backwards:执行完动画后元素保持在 未执行动画时的初始状态
    both:效果跟 forwards 类似
    animation-play-state指定动画运行或暂停(一般在js中使用,用于控制动画播放暂停)
    css
    animation: moveAnimation1 1000 liner 500 2 normal forwards;

总结:

  • nonebackwards 的效果相同,都是会在动画执行完之后,恢复未执行动画时的初始状态
  • 区别是:backwards 会在动画应用于元素时,立即应用第一帧中定义的值,而 none 不会
  • forwardsboth 的效果相同,都是会在动画执行完之后,保持在动画最后一帧的状态
  • 区别是: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 属性

    js
    onload = 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'
      })  
    }
  • 方式二(推荐):通过移除该动画类即可

    js
    onload = 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'
      })  
    }

动画示例:

五. vertical-align


1. 行盒(line boxes )

image-20220423122842962
  • 官方文档的翻译: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,下面也都一样)

    image-20220423125011686
  • 情况二:有图片,有文字时,line-boxes如何包裹内容?

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

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

    image-20220423125055361

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

    image-20220423125108744

3. baseline

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

  • 但是,但是为什么对齐方式千奇百怪呢?

    • 你认为的千奇百怪,其实有它的内在规律
    • 答案就是baseline对齐
  • 我们来看官方vertical-align的默认值:没错,就是baseline

    image-20220423125213756
  • 但是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影响,因为是独占父元素的一行,所以不存在像同一行中的行内级元素在一个行盒中可调整垂直方向的位置这样的说法

Released under the MIT License.