Skip to content

盒子模型(三) ​

本页对应 盒子模型,共 8 段视频,约 1 小时 13 分。

学习目标 ​

  • 能够使用通配符选择器或并集选择器完成 CSS 初始化,清除默认内外边距、去除列表小圆点,并设置 box-sizing: border-box。
  • 能够根据内容溢出场景正确选择 overflow: hidden、scroll、auto,并说明三者在显示与滚动条行为上的差异。
  • 能够识别垂直外边距合并与父子外边距塌陷,并运用 padding、overflow: hidden、透明上边框等方法解决塌陷问题。
  • 能够说明行内元素设置垂直方向 margin/padding 时的异常表现及处理方式,并解释并集选择器不存在权重叠加。
  • 能够使用 border-radius 的单值、双值、三值、四值语法设置圆角,并制作圆形和胶囊形效果。
  • 能够使用 box-shadow 设置盒子阴影,并独立完成产品卡片案例的初始化、卡片尺寸背景、圆角、水平居中及内容结构搭建。

知识点 ​

盒子模型组成:先理解“盒子”再布局 ​

布局网页,本质是摆放盒子和内容。盒子由内容区、内边距、边框、外边距组成:width/height 管内容区,padding 在内容与盒子边缘之间,border 是边框线,margin 在盒子外面。为什么需要?因为只有分清这四层,才能判断“盒子为什么变大了”“两个盒子为什么挨在一起”。怎么想?先画盒子,再量尺寸。怎么做?看下面代码,注意背景色只覆盖内容+padding+border,margin 不包含在背景里。

css
div {
  margin: 50px;
  border: 5px solid brown;
  padding: 20px;
  width: 200px;
  height: 200px;
  background-color: pink;
}

盒子模型组成示意图

盒子模型四层结构示意图

易错点:默认盒子尺寸 = 内容尺寸 + border + padding,所以加 border/padding 会撑大盒子。解决可手动减尺寸,或用内减模式 box-sizing: border-box。

边框线与内边距:先会写,再会算 ​

边框为什么需要?它既能把盒子边界画出来,也能在调试时看清盒子范围。怎么想?border 的值是“粗细 样式 颜色”,顺序不区分。怎么做?四边相同用 border,单方向用 border-方位名词。

css
div {
  border: 5px solid brown;
  width: 200px;
  height: 200px;
  background-color: pink;
}

边框线四方向示意图

css
div {
  border-top: 2px solid red;
  border-right: 3px dashed green;
  border-bottom: 4px dotted blue;
  border-left: 5px solid orange;
  width: 200px;
  height: 200px;
  background-color: pink;
}

内边距设置内容与盒子边缘的距离,属性是 padding 或 padding-方位名词。多值写法从上开始顺时针,当前方向没写就取对面值。提示:加 padding 会撑大盒子。

css
div {
  padding: 30px;
  padding-top: 10px;
  padding-right: 20px;
  padding-bottom: 40px;
  padding-left: 80px;
  width: 200px;
  height: 200px;
  background-color: pink;
}

padding多值写法示意图

尺寸计算易错点:看到“盒子变胖”不要先怪浏览器,先算 width + padding + border。转写稿中的调试过程就是通过 box-sizing: border-box 让宽高包含 border 和 padding。

html
<!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>
    .box {
      box-sizing: border-box;
      width: 200px;
      height: 200px;
      background-color: pink;
      border: 10px solid red;
      padding: 10px;
    }
  </style>
</head>
<body>
  <div class="box">qwe</div>
</body>
</html>

尺寸计算示意图

外边距、版心居中与清除默认样式 ​

margin 用来拉开盒子之间的距离,写法与 padding 相同。版心居中需要盒子有宽度,并让左右外边距为 auto。

css
div {
  margin: 0 auto;
  width: 1000px;
  height: 200px;
  background-color: pink;
}

版心居中示意图

为什么清除默认样式?转写稿中调试发现:body 默认有约 8px 外边距,h1 有很大外边距,ul 既有内边距又有外边距,li 还有小圆点。不清掉,盒子永远贴不到边,标题也会把下面内容挤下去。怎么做?练习期常用通配符清零,并加上内减模式;列表小圆点用 list-style: none。

默认样式示意图

清除默认样式效果图

css
/* 清除默认内外边距 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
/* 清除列表项目符号 */
li {
  list-style: none;
}

易错点:通配符写起来简单,但会选中所有标签;标签并集写法更精准。并集选择器没有权重叠加,后写样式会覆盖前写样式。

元素溢出与外边距合并、塌陷 ​

内容超出盒子时,用 overflow 控制显示方式:hidden 隐藏超出部分,scroll 总是显示滚动条,auto 超出才显示滚动条。转写稿演示:hidden 不是删字,字还在,只是看不见;auto 更智能。重点记住 overflow: hidden。

overflow属性示意图

垂直排列的兄弟元素,上下 margin 会合并,取较大值生效。

css
.one {
  margin-bottom: 50px;
}
.two {
  margin-top: 20px;
}

外边距合并示意图

父子级中,子级加 margin-top 会把父级一起带下来,叫外边距塌陷。解决:父级设 padding;父级设 overflow: hidden;父级设 border-top,可用 transparent 透明边框。

css
.son {
  margin-top: 50px;
  width: 100px;
  height: 100px;
  background-color: orange;
}

外边距塌陷示意图

易错点:合并只发生在垂直方向;左右外边距不合并。塌陷是父子嵌套常见问题,后面写案例一定会遇到。

行内元素内外边距与圆角 ​

行内元素加 margin/padding 时,左右通常有效,垂直位置不能靠它们真正撑开。解决可加 line-height,或转换成行内块/块级元素。

css
span {
  margin: 50px;
  padding: 20px;
  line-height: 100px;
}

圆角用 border-radius,值是半径。正方形设 50% 或宽高一半可得正圆;长方形设高度一半可得胶囊形。多值从左上角顺时针,缺省取对角值。

圆角半径示意图

圆角多值写法示意图

css
img {
  width: 200px;
  height: 200px;
  border-radius: 100px;
  border-radius: 50%;
}

正圆头像效果图

css
div {
  width: 200px;
  height: 80px;
  background-color: orange;
  border-radius: 40px;
}

胶囊形状效果图

易错点:border-radius 是半径不是角度;胶囊半径取高度一半,不是宽度一半。

盒子阴影:让盒子有层次 ​

阴影用 box-shadow,值依次为 X 偏移、Y 偏移、模糊半径、扩散半径、颜色、内外阴影。X/Y 必须写,默认外阴影,内阴影加 inset。开发中常用半透明 rgba 让影子自然。

css
div {
  width: 200px;
  height: 80px;
  background-color: orange;
  box-shadow: 2px 5px 10px 0 rgba(0, 0, 0, 0.5) inset;
}

易错点:直接写纯黑影子会显得生硬;先写 X/Y 和模糊半径,再调颜色透明度,最后按需加 inset。

先看成品与结构 ​

产品卡片效果图

产品卡片的目标很明确:一个灰色页面中放一张白色卡片,卡片内有图片、标题和说明文字,整体水平居中,卡片带圆角。转写稿里先分析页面:页面灰色背景、卡片居中、卡片有圆角,内部按“图片—标题—段落”三块组织。于是 HTML 不需要复杂嵌套,一个大盒子包住三个内容即可。为什么需要先分析结构?因为先确定盒子层级,后面写 CSS 才知道谁负责居中、谁负责间距。怎么想?把卡片看成“外层容器 + 三个子内容”。怎么做?按笔记写:

html
<div class="product">
  <img src="./images/liveSDK.svg" alt="">
  <h4>抖音直播SDK</h4>
  <p>包含抖音直播看播功能</p>
</div>

易错点:不要一上来堆样式,先确认图片、标题、段落都在同一个卡片容器里;标题用 h4 会带默认外边距,后面必须处理。

清除默认样式与盒模型 ​

为什么需要?转写稿中调试时发现:文字不贴浏览器边缘,检查 body 有默认 8px 外边距;标题也有默认外边距,会把下面的内容挤偏。产品卡片里如果不清 h4 的默认 margin,标题位置就会偏下。怎么想?开发时先把标签“天生带的”内外边距清掉,让盒子写多大就是多大。怎么做?用通配符清 margin 和 padding,并用 C3 盒模型,避免后面加 padding 把盒子撑大:

html
<style>
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  body {
    background-color: #f1f1f1;
  }

  .product {
    margin: 50px auto;
    padding-top: 40px;

    width: 270px;
    height: 253px;
    background-color: #fff;
    text-align: center;

    border-radius: 10px;
  }

  .product h4 {
    margin-top: 20px;
    margin-bottom: 12px;
    font-size: 18px;
    color: #333;
    font-weight: 400;
  }

  .product p {
    font-size: 12px;
    color: #555;
  }
</style>

易错点:忘记 * { margin:0; padding:0; } 时,h4 的默认外边距会让标题和图片间距不受控;忘记 box-sizing:border-box 时,padding-top:40px 可能把卡片总高度撑大。

量尺寸、定卡片与水平居中 ​

为什么需要?卡片不能凭感觉写宽高。转写稿中用像素工具测量,宽约 270px,高约 255px,最终笔记取 270px × 253px,以笔记代码为准。怎么想?先写外层卡片的宽高、白底、圆角,再处理位置。怎么做?width:270px; height:253px; background:#fff; border-radius:10px;。水平居中用块级盒子的经典写法 margin:50px auto;:上下 50px,左右自动。转写稿中还讨论过只留上方距离的写法,但本节最终代码是 50px auto,教学时以最终代码为准。易错点:text-align:center 只能让卡片内部的行内内容居中,不能让卡片盒子本身居中;卡片本身居中要靠 margin:auto。

内容居中与文字样式 ​

为什么需要?图片、标题、段落要整齐地居中排列。怎么想?外层 .product 写 text-align:center,内部行内内容会继承居中;标题和段落再单独控制字号、颜色和间距。怎么做?h4 设 margin-top:20px; margin-bottom:12px; font-size:18px; color:#333; font-weight:400;,段落设 font-size:12px; color:#555;。转写稿里特别强调标题默认有较大外边距,清除后要手动补回合适间距,否则标题会贴图或偏下。易错点:h4 默认加粗,若不写 font-weight:400 会显得过重;margin 上下不要重复叠加得太大;图片是行内元素,外层 text-align:center 可让其居中,不要额外编造未讲的定位写法。

CSS 书写顺序与调试 ​

为什么需要?顺序清楚,调试时才知道改的是盒子还是文字。笔记给出顺序:1)盒子模型属性;2)文字样式;3)圆角、阴影等修饰属性。怎么想?先让盒子占好位置,再管文字,最后加圆角等“好看”的属性。怎么做?看 .product:先 margin/padding/width/height/background,再 text-align,最后 border-radius;h4/p 再写文字样式。转写稿中的调试过程也说明:先写 body 背景和清除默认样式,再写卡片宽高、白底、圆角、居中,最后填内容。易错点:不要先写圆角再反复改宽高;阴影属于修饰属性,本节案例没有使用,不要强行添加;改样式时优先检查默认 margin、盒模型和居中方式。

代码示例 ​

示例一:盒子模型组成 + 清除默认样式 + 内减模式 ​

html
<!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>盒子模型</title>
  <style>
    /* 清除默认内外边距 + 内减模式:开发时的第一句 */
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    /* 清除列表项目符号 */
    li {
      list-style: none;
    }

    /* 内容 + 内边距 + 边框 + 外边距 */
    .box {
      /* 内减模式:加 border / padding 不再撑大盒子 */
      box-sizing: border-box;
      width: 200px;
      height: 200px;
      background-color: pink;
      border: 10px solid red;
      padding: 10px;
      margin: 50px;
    }

    /* 单方向边框线 */
    .border-demo {
      border-top: 2px solid red;
      border-right: 3px dashed green;
      border-bottom: 4px dotted blue;
      border-left: 5px solid orange;
      width: 200px;
      height: 200px;
      background-color: pink;
      margin: 50px;
    }

    /* padding 多值:从“上”开始顺时针,当前方向没写就取对面 */
    .padding-demo {
      padding: 10px 20px 40px 80px;
      width: 200px;
      height: 200px;
      background-color: skyblue;
      margin: 50px;
    }

    /* 版心居中:盒子必须有宽度 */
    .center {
      margin: 0 auto;
      width: 1000px;
      height: 200px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div class="box">qwe</div>
  <div class="border-demo"></div>
  <div class="padding-demo">padding 多值</div>
  <div class="center">版心居中</div>
  <ul>
    <li>小圆点已被清除</li>
  </ul>
</body>

</html>

关键行与易错点

  • * { margin: 0; padding: 0; box-sizing: border-box; }:body 默认有 8px 外边距,h 系列标题、ul 默认有较大的内外边距,不清掉盒子永远挨不到一起,这是“写 CSS 的第一句话”。
  • box-sizing: border-box(內减模式):默认盒子尺寸 = 内容 + border + padding,加边框和内边距会撑大盒子;加了內减模式后写多大就是多大,也可以手动做减法。
  • border: 10px solid red 的三个值不区分顺序;单方向用 border-方位名词,如 border-top、border-left。
  • padding: 10px 20px 40px 80px 是“上右下左”顺时针赋值,缺省的方向与对面取值相同(所以 padding: 10px 20px 是上下 10、左右 20)。
  • margin: 0 auto 让有宽度的块级盒子水平居中;行内 / 行内块元素居中则是给块级父元素加 text-align: center。
  • li { list-style: none; } 去掉小圆点,开发中基本必写。

示例二:外边距合并、外边距塌陷、元素溢出 ​

html
<!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>外边距问题与溢出</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    /* 1. 兄弟元素:垂直 margin 合并,取较大值生效 */
    .one {
      margin-bottom: 50px;
      width: 100px;
      height: 100px;
      background-color: pink;
    }

    .two {
      margin-top: 20px;
      width: 100px;
      height: 100px;
      background-color: purple;
    }

    /* 2. 父子级:子级加 margin-top 会塌陷,父级被一起带下去 */
    .father {
      width: 200px;
      height: 200px;
      background-color: pink;
      margin-top: 30px;

      /* 解决塌陷方案二:父级 overflow: hidden */
      overflow: hidden;
      /* 解决塌陷方案三:父级加透明上边框
      border-top: 1px solid transparent; */
      /* 解决塌陷方案一:父级 padding-top,同时取消子级 margin-top
      padding-top: 20px; */
    }

    .son {
      margin-top: 50px;
      width: 100px;
      height: 100px;
      background-color: orange;
    }

    /* 3. 元素溢出 */
    .overflow-box {
      width: 200px;
      height: 200px;
      background-color: pink;
      margin-top: 30px;
      overflow: hidden; /* 溢出隐藏:字还在,只是看不见 */
      /* overflow: scroll; 一定显示滚动条 */
      /* overflow: auto;   超出才显示滚动条,不超出不显示 */
    }
  </style>
</head>

<body>
  <div class="one"></div>
  <div class="two"></div>

  <div class="father">
    <div class="son"></div>
  </div>

  <div class="overflow-box">
    这里写很多很多很多的文字,让内容超出盒子的范围,用来演示元素溢出的效果。这里写很多很多很多的文字,让内容超出盒子的范围,用来演示元素溢出的效果。
  </div>
</body>

</html>

关键行与易错点

  • 外边距合并只发生在垂直方向的兄弟元素上,结果是取两个 margin 中的较大值(50 和 20 最终只有 50,不是 70);实际开发中给其中一个盒子写 margin 就能避开。
  • 外边距塌陷发生在父子级:给子级加 margin-top,父级会被一起带下来,左右方向不会出现。
  • 塌陷三种解法:① 取消子级 margin,父级用 padding-top 挤下来;② 父级 overflow: hidden(这里不是为了溢出隐藏,而是防塌陷);③ 父级加 border-top: 1px solid transparent,用透明边框隔开,看不见但能生效。
  • overflow: hidden 是重点,超出的内容只是被藏起来,文字并没有被删除。
  • scroll 无论是否超出都显示滚动条,auto 是超出才显示,要分清两者区别。
  • 行内元素加 margin / padding 无法改变垂直位置,需要给 line-height 才能改变垂直位置。

示例三:综合案例 – 产品卡片 ​

html
<!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>产品卡片</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      background-color: #f1f1f1;
    }

    .product {
      margin: 50px auto;
      padding-top: 40px;

      width: 270px;
      height: 253px;
      background-color: #fff;
      text-align: center;

      border-radius: 10px;
    }

    .product h4 {
      margin-top: 20px;
      margin-bottom: 12px;
      font-size: 18px;
      color: #333;
      font-weight: 400;
    }

    .product p {
      font-size: 12px;
      color: #555;
    }
  </style>
</head>

<body>
  <div class="product">
    <img src="./images/liveSDK.svg" alt="">
    <h4>抖音直播SDK</h4>
    <p>包含抖音直播看播功能</p>
  </div>
</body>

</html>

关键行与易错点

  • CSS 书写顺序:先盒子模型属性(宽高、margin、padding、背景),再文字样式,最后圆角、阴影等修饰属性。
  • margin: 50px auto 让卡片水平居中且距顶部 50px;块级盒子居中必须左右 margin 为 auto 且盒子有宽度。
  • padding-top: 40px 把图片往下挤,配合 text-align: center 让图片、标题、段落整体水平居中,不必给每个子元素单独居中。
  • border-radius: 10px 是圆角半径;正方形盒子写 50% 或宽高一半就是正圆,长方形盒子写高度的一半就是胶囊形。
  • 图片路径 ./images/liveSDK.svg 需换成你本地实际存在的图片,否则会显示破图占位,布局看起来会不对。
  • h4 的 font-weight: 400 用来去掉标题默认的加粗,h4、p 的上下间距是用 margin 单独控制的,不要指望默认样式。

常见错误 ​

  1. 现象:给盒子加了 padding / border 后,实际占位比写的 width 大,相邻盒子被挤下去或换行。 原因:默认盒模型下,width 只算内容区,border 与 padding 是往外加的。 修法:初始化时统一写 * { box-sizing: border-box; };若不能改盒模型,就手动从 width/height 里减掉 border*2 + padding*2。

  2. 现象:给子盒子写 margin-top,结果整个父盒子跟着往下跑,子盒子并没有和父盒子拉开距离。 原因:父子级垂直外边距塌陷,子级的上外边距"传给"了父级。 修法:三选一——父级写 padding-top 代替;父级写 overflow: hidden;父级写 border-top: 1px solid transparent(用透明边框,看不见但不塌陷)。

  3. 现象:上下两个兄弟盒子,一个 margin-bottom: 50px、一个 margin-top: 20px,实际间距是 50px 而不是 70px。 原因:垂直外边距合并,取两者较大值生效。 修法:间距只由一方提供,另一个写 0;不要"你一半我一半"地平摊。

  4. 现象:页面内容贴不到浏览器左上角;写个 h1/p/ul 就凭空多出一段距离,布局整体偏移。 原因:body、标题、段落、列表等标签自带默认 margin/padding(body 默认 8px 外边距,ul 内外边距都有)。 修法:CSS 第一段就写初始化 * { margin: 0; padding: 0; box-sizing: border-box; };想更"干净"可改成标签并列选择器只清有默认值的标签。

  5. 现象:li 前面的小圆点去不掉,或列表整体往右缩进。 原因:圆点由 list-style 控制,缩进来自 ul 的默认 padding-left。 修法:li { list-style: none; } + 初始化里的 padding: 0 一起用,缺一不可。

  6. 现象:给 span 这类行内元素加 margin/padding,左右有反应、上下不动或错位。 原因:行内元素垂直方向的内外边距不能撑开行盒。 修法:改用 line-height 调整垂直位置;或 display: inline-block / block 转换后再用内外边距。

  7. 现象:margin: 0 auto 写了却没居中。 原因:盒子没有宽度(块级元素宽度默认占满),或元素本身是行内/行内块。 修法:先给盒子明确 width;行内、行内块要居中则给父级加 text-align: center。

  8. 现象:border-radius: 50% 想做成圆,结果成了椭圆;胶囊按钮怎么调都不圆润。 原因:50% 是按各自边长算的,非正方形必然变椭圆;胶囊的临界值是高度的一半。 修法:正方形用 50% 或宽高一半;长方形做胶囊用 border-radius: 高度/2。

练习 ​

  1. 两种方案对撞:做一个 width: 300px; height: 200px、padding: 20px、border: 3px solid #333 的盒子,要求它在页面上占位正好 300×200。分别用「手动减尺寸」和「box-sizing: border-box」各写一遍,用检查器对比两者内容区大小差异,写下你的结论。

  2. 塌陷三连:父盒子 200×200 粉色,子盒子 100×100 蓝色,要求子盒子距父盒子顶部 30px 且父盒子位置不动。用 padding-top、overflow: hidden、border-top: transparent 三种方案各实现一次,并说明第三种为什么看不见边框。

  3. 救火页面:给下面这段结构写初始化样式,要求内容紧贴浏览器左上角、列表无圆点无缩进:

    html
    <h2>标题</h2>
    <p>段落文字</p>
    <ul><li>选项一</li><li>选项二</li></ul>

    写完后用检查器逐个选中 body/h2/ul/li,确认你清掉了哪些默认值。

  4. 溢出对比:一个 200×200 的盒子塞入远超容量的文字,分别设置 overflow: visible / hidden / scroll / auto。记录四次的差异,并回答:hidden 之后文字是被删除了还是只是看不见?scroll 与 auto 在内容未超出时的表现有何不同?

  5. 圆角+阴影综合:① 把一张正方形图片做成圆形头像,带柔和阴影(要求阴影用 rgba 半透明,不用纯黑);② 另做一个 200×40 的橙色胶囊按钮。完成后在检查器里把阴影参数逐个调大调小,记录哪个参数控制"虚实"、哪个控制"影子大小"。

原视频对照 ​

#视频时长
1清除默认样式10:32
2溢出隐藏05:37
3外边距塌陷和合并15:35
4小问题06:39
5圆角边框11:14
6圆角边框多个值04:50
7盒子阴影09:59
8综合案例1开始09:05

小结 ​

  1. 写任何页面的第一步永远是初始化:清默认内外边距 + 开 border-box,这一步不做,后面所有尺寸计算都不可信。
  2. 尺寸思考的默认起点是「占位」而不是「内容」——先想盒子最终占多大,再倒推 width 与 padding。
  3. 垂直方向的间距优先用父级 padding 或单侧 margin 解决,避免"子级 margin-top"这个塌陷雷区。
  4. 垂直外边距永远只由一方提供,两侧都写必然踩合并;这是纪律,不是技巧。
  5. 行内元素不要当布局盒子用,需要内外边距就转 display,需要垂直位移就用 line-height。
  6. 排查"凭空多出来的距离"最高效的手段是打开检查器看盒模型高亮:黄色是外边距、青绿色是内边距,一眼定位是谁在捣乱。
  7. 圆角与阴影这类修饰属性放在样式表最后写,先保证盒子模型正确,再谈好看;参数不确定时直接去成熟站点检查器里复制。
  8. 阴影和圆角都属于"调出来的美",写之前先用截图工具量好宽高与取色,比写完再反复试要快得多。