# CSS工作原理和性能优化

# CSS布局模型

# 流动模型(Flow)默认的网页布局模式

流动(Flow)是默认的网页布局模式。也就是说网页在默认状态下的 HTML 网页元素都是根据流动模型来分布网页内容的。

特征:

  • 块状元素都会在所处的包含元素内自上而下按顺序垂直延伸分布,因为在默认状态下,块状元素的宽度都为100%。实际上,块状元素都会以行的形式占据位置
  • 在流动模型下,内联元素都会在所处的包含元素内从左到右水平分布显示(内联元素可不像块状元素这么霸道独占一行)

块级元素 display:block

1.独占一行的上下结构垂直排列

2.在没有设置宽高大小的时候,它的宽度是父元素的宽度(浏览器窗口大小) ,高度是自己本身内容高度

3.块级元素可以设置宽高大小

4.在一行显示转化,块转换成行内块 block => inline-block / float

内联元素 display:inline

1.不独占一行的左右结构水平排列

2.在没有设置宽高大小的时候,它的宽高是它自己本身的大小

3.设置宽高属性不起作用

  • block 块级元素,上下结构的排列
  • inline-block 行内块元素,左右结构的排列
  • float 浮动

# 浮动模型(Float)

特征:

  • 通过css的 float 属性可以将元素设置为浮动元素。元素浮动之后不再占据原来的位置,它们会尽可能的往包裹它们的父元素的左边框或右边框靠,并会在它们元素所处位置的下面产生浮动流,影响下面的元素定位
  • 浮动元素并没有完全脱离文档流,它只是从包裹它的盒子中浮动起来并尽可能远的往左侧或者右侧进行移动
  • 浮动设计的初衷是为了实现文字在图片周围的环绕效果

浮动导致问题:高度塌陷,子元素浮动父元素的高度失效 height:0

常用清浮动方法:

  1. 父元素 overflow: hidden (BFC)
  2. 利用伪元素 :after 封装一个通用样式
.clearfix::after{
  content: '';
  display: block;
  clear: both;
}
1
2
3
4
5

# 层模型(Layer)其实是定位😁😁

层布局模型就像是图像软件 PhotoShop 中非常流行的图层编辑功能一样,每个图层能够精确定位操作,但在网页设计领域,由于网页大小的活动性,层布局没能受到热捧。但是在网页上局部使用层布局还是有其方便之处的

层模型有三种形式:

  • 相对定位(position: relative)
  • 绝对定位(position: absolute)
  • 固定定位(position: fixed)

# BFC / IFC

# BFC的原理和功能

块级格式化上下文(BFC)

其实BFC是上面三种布局方式中的普通流,BFC会产生一个独立的容器,该容器内部的元素不会在布局上影响到外部的元素,在外部的普通流来看它和其他普通流元素无差别,文档最终会按照上面说的普通流计算布局。

静态图片

  • MDN的定义:块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域
  • BFC(block formatting context)块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则,它决定了元素如何对齐内容进行布局,以及与其他元素的关系和相互作用。当涉及到可视化布局的时候,BFC提供了一个环境,HTML元素在这个环境中按照一定规则进行布局
  • 具有BFC特性的元素可以看做是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且BFC具有普通容器所没有的的一些特性
  • BFC是一个独立的布局环境,BFC内部的元素布局与外部互不影响

BFC的布局规则

  • 内部的盒子会在垂直方向,一个个地放置
  • 盒子垂直方向的距离由 margin 决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠
  • 每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此
  • BFC的区域不会与float box重叠
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此
  • 计算BFC的高度时,浮动元素也参与计算

触发BFC的条件

只要元素满足下面任一条件即可触发BFC特性:😸😸

  • html 根元素或其他包含它的元素
  • float 的属性不为 none
  • overflow 为 auto、scroll、hidden
  • display 为 inline-block,table-cell,table-caption 中的任何一个
  • position 为 absolute 或 fixed

静态图片

静态图片

BFC的用处

案例一: 让浮动内容和周围的内容等高

  • overflow: auto 创建一个会包含这个浮动的 BFC,通常的做法是设置父元素 overflow: auto 或者设置其他的非默认的 overflow: visible 的值。
  • 使用display: flow-root; 一个新的 display 属性的值,它可以创建无副作用的 BFC。在父级块中使用 display: flow-root 可以创建新的 BFC。
.box {
  background-color: rgb(224, 206, 247);
  border: 5px solid rebeccapurple;
  overflow: hidden;
}

.float {
  float: left;
  width: 200px;
  height: 150px;
  background-color: white;
  border: 1px solid black;
  padding: 10px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="box">
  <div class="float">我是浮动的盒子</div>
  <p>我是普通的</p>
</div>
1
2
3
4

静态图片

案例二: 外边距折叠

  • 原因: Box垂直方向的距离由 margin 决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  • 解决方法: 给上box或者下box任意一个包裹新的box并开启BFC
  • 原理: BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此;
p {
  color:#f55;
  background: #fcc;
  width: 200px;
  line-height: 100px;
  text-align: center;
}
.p1 {
  margin-bottom: 50px;
}
.p2 {
  margin-top: 100px;
}
/* 
  相加150px 
*/
.parent {
  overflow: hidden;
}

/* overflow: hidden;
  1.溢出隐藏
  2.margin的折叠问题
  3.清除浮动
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<p class="p1">块1间距50</p>

<!-- 解决办法 -->
<div class="parent">
  <p class="p2">块2 间距100</p>
</div>
1
2
3
4
5
6

静态图片

案例三: 清除浮动

  • 解决方法: 给父元素开启BFC
  • 原理: 计算BFC的高度时,浮动子元素也参与计算
.container{
  width: 300px;
  border: 5px solid #fcc;
  overflow: auto;
}
.box {
  width: 100px;
  height: 100px;
  float: left;
  border:5px solid #f66;
}
1
2
3
4
5
6
7
8
9
10
11
<div class="container">
    <div class="box"></div>
    <div class="box"></div>
</div>
<ul>
    <li>江小鱼江小鱼江小鱼江小鱼江小鱼江小鱼</li>
    <li>江小鱼江小鱼江小鱼江小鱼江小鱼江小鱼</li>
    <li>江小鱼江小鱼江小鱼江小鱼江小鱼江小鱼</li>
    <li>江小鱼江小鱼江小鱼江小鱼江小鱼江小鱼</li>
    <li>江小鱼江小鱼江小鱼江小鱼江小鱼江小鱼</li>
</ul>
1
2
3
4
5
6
7
8
9
10
11

静态图片

案例四: 自适应的两列布局(左图右文)

  • 解决方法: 给父元素开启BFC
  • 原理: BFC的区域不会与float box重叠
/* 
  原理1: 层叠上下文 - html层叠上下文元素里面
  特性:  
  层叠顺序 =>  
  背景或边框 < z-index负值 < 块级元素 < 浮动元素 < 行内块 < position < z-index正值
  aside浮动元素
  main块级元素


  原理2: BFC规则
  BFC元素不会与float容器重叠
  BFC是一个独立的容器和外面的元素互不影响

*/
.aside {
  width: 100px;
  height: 150px;
  float: left;
  background: #f66;
}

.main {
  height: 200px;
  background: #fcc;
  overflow: hidden;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="aside"></div>
<div class="main"></div>
1
2

静态图片

# IFC的原理和功能

行级格式化上下文(IFC)

存在块级格式化上下文BFC,则对应存在内联格式化上下文IFC、网格格式化上下文GFC、自适应格式化上下文FFC,这些都可以统称为格式化上下文;

静态图片

IFC的含义:

  • IFC(inline Formatting Context)叫做“内联格式化上下”
  • 内部的元素从包含块的顶部开始,从左至右(默认)排列成一行形成的一个矩形盒子叫做line box

IFC的布局规则:

  • 盒子是水平一个接一个的排列,水平的margin,内边距,边框是可以有的
  • 垂直方向的对齐,可能是底部对齐,顶部对齐,也可能是基线对齐(这个是默认的)
  • 行框中的内联盒子的高度小于行框的高度时,内联盒子的垂直方向的对齐方式取决于vertical-align属性
  • 当一个行框水平不能容纳内联盒子时,他们将会在垂直方向上产生多个行框,他们上下一个挨着一个,但是不会重叠
  • 一般来说,行框的左边界紧挨着包含容器的左边界,行框的右边界紧挨着包含容器的右边界,(是两个边都紧挨着)。然而,浮动盒子可能存在于包含边框边界和行框边界之间
  • 多个内联盒子的宽度小于包含他们的行框时,他们在水平方向的分布取决于text-align属性

IFC的作用:

  • 水平居中:当一个块要在环境中水平居中时候,设置其为inline-block则会在外层产生IFC,通过text-align:center则可以使其水平居中
  • 垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中

案例一:

水平居中

/* IFC一个作用 */
.box{
  width: 200px;
  height: 200px;
  background-color: rosybrown;
  text-align: center;
}
.child{
  width: 80px;
  height: 50px;
  background-color: seagreen;
  /* 
  当一个块要在环境中水平居中时候,
  设置其为inline-block则会在外层产生IFC,
  通过text-align:center则可以使其水平居中 
  */
  display: inline-block; /* 😸😸 */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="box">
  <div class="child">江小鱼</div>
</div>
1
2
3

静态图片

案例二:

图片默认的下间隙

/* 
解决办法:
  vertical-align 默认的线 = 基线对齐(默认) => 文字是有行高的,所以会出现一个下边距的高度
  1. 把img 的对齐vertical-align:baseline 破坏掉 => 让元素是一个块级元素,vertical-align 失效
    display: block;
  2. vertical-align:middle、bottom、top
  3. 给父元素把font-size:0; => 子元素文字会消失 - font-size加一遍 把子元素文字加回来
*/

img {
  /* display: block; */
  /* vertical-align: middle; */
}

div {
  font-size: 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div style="background-color:#000;color:#fff">
  <img src="images/mm1.jpg">
</div>
1
2
3

静态图片

静态图片

静态图片

案例三:

图片在垂直方向 line-height

/* 
  图片在垂直方向  line-height

  x middle 居中对齐

  font-size: 基线 = 中线

  */
div {
  line-height: 240px;
  font-size: 0 /* 😸😸 */
}
img {
  vertical-align: middle;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

静态图片

# CSS渲染和解析原理

CSS性能优化: 提升CSS渲染性能的方面汇总 absolute/display隐藏与回流等性能 base64:URL背景图片与web页面性能优化

参考:

CSS深入理解vertical-align和line-height的基友关系 深入理解 CSS:字体度量、line-height 和 vertical-align