CSS 知识总结

533 阅读11分钟

css transition 补充

CSS基本概念:

在CSS中最基本的概念就是以下几种:

一、文档流(Normal Flow)

文档流中有:块元素、内联元素、内联块元素

在文档流中,元素有不同的流动方向与特性:

  1. inline(内联元素):从左到右,到达了最右边才会换行,宽度为内部inline(内联元素)的和(不能用width指定),高度由 line-height 间接确定(跟 height 无关),直到与其他内联元素占满一行空间后才会再另起一行

  1. block(块元素):从上到下,每一个都另起一行,默认自动计算宽度,可以自行设定宽度与高度,并且独占一行空间,第3个div宽度是默认最大宽度(不是100%宽度)

  2. inline-block(内联块元素):从左到右,但具有内联特性(不会独占一行)又具有块的特性(块元素不可分离),结合前两者特点,可以用width改变宽度,height改变高度

注意事项:

当写的内容大于文档流内的容量时,会产生溢出现象。这时可使用overflow来设置是否显示滚动条

/* 默认值。内容不会被修剪,会呈现在元素框之外 */
overflow: visible;

/* 内容会被修剪,并且其余内容不可见 */
overflow: hidden;

/* 内容会被修剪,浏览器会显示滚动条以便查看其余内容 */
overflow: scroll;

/* 由浏览器定夺,如果内容被修剪,就会显示滚动条 */
overflow: auto;

/* 规定从父元素继承overflow属性的值 */
overflow: inherit;

二、脱离文档流

元素脱离文档流之后,将不再在文档流中占据空间,而是处于浮动状态(可以理解为漂浮在文档流的上方)。脱离文档流的元素的定位基于正常的文档流,当一个元素脱离文档流后,依然在文档流中的其他元素将忽略该元素并填补其原先的空间.

会导致脱离文档流的标签:position: absolute; position: fixed; float:left;

三、盒子模型

熟练掌握CSS的布局方法,首先要对盒模型有足够的了解。盒子模型是CSS布局网页时非常重要的概念,只有很好地掌握了盒子模型以及其中每个元素的使用方法,才能真正地布局网页中各个元素的位置

所有页面中的元素都可以看作是一个装了东西的盒子,它分为四层区域,最外面为margin(外边距),其次是border(边框),然后是padding(内边距),最里面是content(内容)

盒模型分为两种,分别是:

  • content box(内容盒) ,内容就是盒模型的边界
  • border box(边框盒) ,边框才是盒模型的边界

两者的区别是:

  • content box的宽度只包含content(内容)
  • border box的宽度包含到border,那么包含有哪些呢,border,内边距(padding),内容(content)。

四、margin 合并

  1. 当上下都有 margin 时(没有 border 等等),外边距会合并。
  • 父子合并(最上父子 margin 和最下父子 margin)
  • 兄弟合并(相邻的 margin 也会合并)
  1. 以上情况都是在 Margin 和 Margin 之间没有其他属性存在,才会合并
  • 消除父子之间合并 padding/border/overflow:hidden/display:flex;
  • 兄弟之间合并可以用 inline-block;

五、基本单位

  • 长度单位

    • px 像素
    • em 相对于自身 font-size 大小的倍数
    • 百分数
    • 整数
    • rem
    • vw和vh
  • 颜色单位

    • 十六进制(#000000 可缩写#000)
    • rgb/rgba (rgb(0-255,0-255,0-255),a(0-1)透明)
    • hsl/hsla(hsl(1-360,百分比,百分比),a(0-1)透明)

    CSS 进阶之动画

我们都知道动画电影由一帧一帧的静态画面拼接而成,一秒动画有24帧画面,如果低于24帧,人眼即可感知画面切换,就会有卡顿的感觉。

CSS 中,如果按一秒24帧的画法来写代码,未免太过繁琐。所以我们把动画拆解为动作(transition),一个动作表示从一个状态到另一个状态的变化,然后把一组动作串起来,即是 CSS 中的动画(animation)


其他诠释的浏览器渲染原理

其他诠释的浏览器渲染原理(1)

浏览器在得到服务器的响应之后,会先根据HTML去渲染成一个结构图HTML树(DOM)所有的标签具有父子关系。
HTML标签是最大的,其次是head和body两个大儿子,依次渲染。
CSS会构建成CSS树(CSSOM)。CSS也是根据标签所具备的属性。在这里body是最大的。如果body所带的属性
如果标签是共有的属性,儿子会继承父子所带的属性

这时会将HTML CSS 合并在一起成为渲染树(render tree)
Layout布局然后是计算标签的大小以及位置渲染布局。(文档流、盒模型、计算大小和位置)
paint绘制接下来是绘制标签的背景颜色、边框、字体颜色、阴影的(所有美化属性在渲染)
compose最后一步是层叠的合成,(例如拍照:就是把背景和人合成跟这个概念是一样的)

其他诠释的浏览器渲染原理(2)

一. 网页生成的过程

1. 根据HTML代码构建HTML树(DOM)

HTML代码就像一颗倒着长的大树,浏览器将收到的html代码,通过html解析器解析构建为一颗DOM树。根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点。

在节点树中,顶端节点被称为根(HTML标签),每个节点都有父节点、除了根(它没有父节点),一个节点可拥有任意数量的子节点,同胞是拥有相同父节点的节点。

2. 根据CSS代码构建CSS树(CSSOM)

结构和DOM类似,在DOM的各个节点上添加相应的样式。

3. 将两棵树合并成一颗渲染树(render tree)(包含每个节点的视觉信息)

渲染树的生成大概经过以下过程:

  • 从DOM根节点根节点开始遍历每个在HTML和CSS意义上的可见节点。
  • 对于每个可见节点,为其找到适配的CSSOM并且组合他们
  • 将每个节点(包括内容和样式)组建成render-tree

不需要渲染的节点是不会合并到渲染树中的,比如元数据元素meta,base等,还有设置了display:none的节点。

4. Layout布局(文档流、盒模型、计算大小和位置)

第一步到第三步都非常快,耗时的是第四步和第五步。

布局的最终结果是一个“盒模型”,它需要精确的计算出每个元素所占据的位置坐标。

5. Paint绘制(把边框颜色、文字颜色、阴影等画出来)

根据background, border,color等样式和HTML内容,将Layout布局生成的区域填充为最终将显示在屏幕上的像素。

6. Compose合成(根据层叠关系展示画面)

以上五步都处理好后,因为css中有层叠上下文概念,把所有层级合成为一层显示在页面中。

二. 重排和重绘

网页生成的时候,至少会渲染一次。用户访问的过程中,还会不断重新渲染。

重新渲染,就需要重新生成布局和重新绘制。前者叫做"重排"(reflow),后者叫做"重绘"(repaint)。

以下三种情况,会导致网页重新渲染。

  • 修改DOM
  • 修改样式表
  • 用户事件(比如鼠标悬停、页面滚动、输入框键入文字、改变窗口大小等等

需要注意的是,"重绘"不一定需要"重排"比如改变某个网页元素的颜色,就只会触发"重绘",不会触发"重排",因为布局没有改变。但是,"重排"必然导致"重绘",比如改变一个网页元素的位置,就会同时触发"重排"和"重绘",因为布局改变了。

三. 重新渲染对于性能的影响

重排和重绘会不断触发,这是不可避免的。但是,它们非常耗费资源,是导致网页性能低下的根本原因。

虽然浏览器已经很智能了,会尽量把所有的变动集中在一起,排成一个队列,然后一次性执行,尽量避免多次重新渲染。但是如果写得不好,就会触发两次重排和重绘。

提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。

一般的规则是:

  • 样式表越简单,重排和重绘就越快。
  • 重排和重绘的DOM元素层级越高,成本就越高。
  • table元素的重排和重绘成本,要高于div元素。

其他诠释的浏览器渲染原理(3)

  • 浏览器渲染过程

    • 根据 HTML 构建 HTML 树(DOM)

    • 根据 CSS 构建 CSS 树(CSSOM)

    • 将两棵树合并成一颗渲染树(render tree)

    • Layout 布局(文档流、盒模型、计算大小和位置)

    • Paint 绘制(把边框颜色、文字颜色、阴影等画出来)

    • Composite 合成(根据层叠关系展示画面)

  • 如何更新样式

    • 一般我们用 JS 来更新样式
  1. 比如 div.style.background='red'

  2. 比如 div.style.display='none'

  3. 比如 div.classList.add=('red')

  4. 比如 div.remove() 直接删掉节点

  • 那么这些方法有什么不同吗

    • 有三种不同的渲染方式

  • 三种更新方式

第一种,全走

div.remove() 会触发当前消失,其他元素 relayout

第二种,跳过 layout

改变背景颜色,直接 repaint + composite

第三种,跳过 layout 和 paint

改变 transform,只需 composite

注意必须全屏查看效果,在 iframe 里看有问题

  • CSS 动画优化

    • 没什么技术含量

答案都在Google 写的文章里.

  • JS 优化

使用 requestAnimationFrame 代替 setTimeout 或 setInterval

  • CSS 优化

使用 will-change 或 translate

诀窍

认真看仔细记,背下来。


关于 transform

CSStransform属性允许你旋转,缩放,倾斜或平移给定元素。这是通过修改CSS视觉格式化模型的坐标空间来实现的。

  • MDN 文档

  • 四个常用功能

    • 位移 translate

    • 缩放 scale

    • 旋转 rotate

    • 倾斜 skew

  • 经验

  1. 一般都需要配合 transition 过渡

  2. inline 元素不支持 transform,需要先变成 block

一. 位移 translate

 translateX( <length-percentage> )

 translateY( <length-percentage> )

  translate( <length-percentage> , <length-percentage>? )

  translateZ( <length> ) 且父容器 perspective

  translate3d(x, y, z)

示例

  • 经验
  1. 要学会看懂 MDN 的语法示例

  2. translate(-50%,-50%) 可做绝对定位元素的居中

二. 缩放 scale

  • 常用写法

    scaleX( <number> )
    
     scaleY( <number> )
    
     scale( <number> , <number>? )
    

示例

  • 经验

    1. 用的较少,因为容易出现模糊

三.旋转 rotate

  • 常用写法
rotate( [ <angle> | <zero> ] )

rotateZ( [ <angle> | <zero> ] )

rotateX( [ <angle> | <zero> ] )

rotateY( [ <angle> | <zero> ] )

rotate3d 较为复杂

示例

  • 经验
  1. 一般用于 360 度旋转制作 loading

  2. 用到时再搜索 rotate MDN 看文档

四. 倾斜 skew

  • 常用写法
skewX( [ <angle> | <zero> ] )

skewY( [ <angle> | <zero> ] )

skew( [ <angle> | <zero> ] , [ <angle> | <zero> ]? )

示例

  • 经验
  1. 用的较少

  2. 用到时再搜 skew MDN 文档

五. transform 多重效果

*组合使用

transform: scale(0.5) translate(-100%, -100%);

transform: none; 取消所有

transition

作用 :补充中间帧

语法.

transition: 属性名 时长 过渡方式 延迟

transition: left 200ms linear

可以用逗号分隔两个不同属性

transition: left 200ms, top 400ms

可以用 all 代表所有属性

transition: all 200ms

过渡方式有:linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier | step-start | step-end | steps,具体含义要靠数学知识

并不是所有属性都能过渡

display: none =>和 block 没法过渡
一般改成 visibility: hidden => visible(没有为什么)
  • background 颜色可以过渡吗?(可以)

  • opacity 透明度可以过渡吗?(可以)

让一个盒子消失的三种过渡方案对比,均设置为 transition: all 5s;

A. 由 display: block 过渡为 display: none

结果:盒子会在第一秒就立即消失,没有过渡效果,消失后不占位置

B. 由 visibility: visible 过渡为 visibility: hidden

结果:盒子会在最后一秒立即消失,没有过渡效果,消失后继续占位置

C. 由 opacity: 1过渡为 opacity: 0

结果:盒子会慢慢变透明最终消失,有过渡效果,消失后继续占位置

过渡必须要有起始,如果除了起始,还有中间点,怎么办?

两种办法

  • 使用两次 transform

    .a === transform ===> .b

    .b === transform ===> .c

    如何知道到了中间点呢?

    用 setTimeout 或者监听 transitionend 事件

    示例

  • 使用 animation

  1. 声明关键帧

  2. 添加动画.

示例


@keyframes 完整语法

标准写法

  • 搜索 keyframes MDN 讲的很清楚
  1. 一种写法是 from to

  2. 另一种写法是百分数

  • 如何让动画停在最后一帧

1.搜索 css animation stop at end

网友答案加个 forwards

示例

  • 缩写语法

animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 动画名;

  • 时长:1s 或者 1000ms

  • 过渡方式:跟 transition 取值一样,如 linear

  • 次数:3 或者 2.4 或者 infinite

  • 方向:reverse | alternate | alternate-reverse

  • 填充模式:none | forwards | backwards | both

  • 是否暂停:paused | running

以上所有属性都有对应的单独属性