Skip to content

✨ 常规流 👌

1. 基本概念

盒模型:规定单个盒子的规则

视觉格式化模型(布局规则):页面中的多个盒子排列规则

视觉格式化模型,大体上将页面中盒子的排列分为三种方式:

  1. 常规流
  2. 浮动
  3. 定位

在线演示

2. 常规流布局

常规流也叫文档流、普通文档流、常规文档流

所有元素,默认情况下,都属于常规流布局

总体规则:块盒独占一行,行盒水平依次排列

2.1. 包含块(containing block)

包含块(containing block):每个盒子都有它的包含块,包含块决定了盒子的排列区域

绝大部分情况下:盒子的包含块,为其父元素的内容盒

2.2. 块盒

2.2.1. 宽度计算规则

:::important 仅适用于“常规流中的非替换块级元素(非浮动、非绝对/固定定位、非替换元素)”。

其水平等式为: margin-left + border-left + padding-left + width + padding-right + border-right + margin-right = 包含块的内容宽度 :::

  • width 的初始值为 auto;左右 margin 也可以是 auto(默认使用值为 0)。用户代理会计算“使用值”以满足上面的等式。
  • 具体分配规则:
    • widthauto 且左右 margin 均为非 auto 时,width 计算为剩余空间。
    • width 已指定、且一侧 marginauto 时,auto 的那一侧吸收全部剩余空间。
    • width 已指定、且左右 margin 都为 auto 时,左右均分剩余空间,实现水平居中。
    • width、左右 margin 都是非 auto 时,margin-right 吸收剩余空间(可能为负值导致溢出)。

提示:默认情况下,块级盒会占据整行并贴齐行内起始边;要实现水平居中,需为元素设定一个确定的 width,并将 margin-leftmargin-right 设为 auto

css
/* 块级元素水平居中示例 */
.center-block {
  width: 80%; /* 或任何固定宽度 */
  margin-left: auto;
  margin-right: auto;
}

2.2.2. 垂直方向上的 auto 值

css
/* 垂直方向auto值示例 */
.auto-height {
  height: auto; /* 会自动适应内容高度 */
}

.auto-margin-vertical {
  margin-top: auto; /* 实际等同于margin-top: 0 */
  margin-bottom: auto; /* 实际等同于margin-bottom: 0 */
}

2.2.3. 百分比取值

width、padding(四个方向)、margin(四个方向) 可以取值为百分比,表示相对于包含块的宽度。

css
/* 百分比取值示例 */
.percentage-example {
  width: 50%; /* 包含块宽度的50% */
  padding-left: 10%; /* 包含块宽度的10% */
  margin-right: 5%; /* 包含块宽度的5% */
}

高度的百分比:

  1. 包含块的高度取决于子元素的高度,设置百分比无效
  2. 包含块的高度不取决于子元素的高度,百分比相对于包含块高度
css
/* 高度百分比示例 */
.parent {
  height: 200px; /* 固定高度 */
}

.child {
  height: 50%; /* 父元素高度的50%,即100px */
}

/* 当父元素高度由内容决定时 */
.auto-height-parent {
  /* 高度由内容决定 */
}

.child-percentage {
  height: 50%; /* 无效,因为父元素高度不确定 */
}

2.2.4. 上下外边距的合并

:::important 两个常规流块盒,上下外边距相邻(父子元素、兄弟元素),会进行合并。两个外边距取最大值。 :::

css
/* 外边距合并示例 */
.box1 {
  margin-bottom: 20px;
}

.box2 {
  margin-top: 30px;
}
/* 两个盒子之间的实际间距是30px,而不是50px */

3. 最佳实践

3.1. 盒模型选择

为了更直观地控制元素尺寸,建议使用 box-sizing: border-box

css
/* 全局应用border-box */
* {
  box-sizing: border-box;
}

3.2. 避免外边距合并问题

当不希望发生外边距合并时,可以:

  • 使用 padding 代替 margin
  • 在父元素上添加 border 或 padding
  • 使用 overflow: hidden 创建 BFC
css
/* 防止外边距合并 */
.parent {
  padding-top: 1px; /* 防止子元素margin-top穿透 */
  padding-bottom: 1px; /* 防止子元素margin-bottom穿透 */
}

3.3. 响应式设计考虑

在常规流中使用百分比和媒体查询实现响应式布局:

css
/* 响应式布局示例 */
.container {
  width: 90%;
  max-width: 1200px;
  margin: 0 auto;
}

@media (max-width: 768px) {
  .container {
    width: 95%;
  }
}