Skip to content

盒子模型(一) ​

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

学习目标 ​

  • 能独立编写结构伪类选择器,使用 :first-child、:last-child、:nth-child(n) 选中首项、末项和指定项,并通过 2n、2n+1、5n、-n+5、n+5 完成奇偶、倍数及范围选择。
  • 能准确区分伪类选择器与伪元素选择器,说明二者书写符号、选择依据和权重差异,并能判断样式覆盖原因及通过调整顺序或权重解决覆盖问题。
  • 能使用 ::before 和 ::after 创建装饰性内容,正确设置必需的 content 属性,并在需要时转换显示模式以设置宽高。
  • 能使用 PxCook 导入图片或 PSD 设计稿,在设计视图和开发视图中测量宽高、间距、坐标,提取颜色、字号、行高和文字内容,并复制可用样式信息。
  • 能配置 Markdown 笔记的图片插入选项,将截图保存到 assets 文件夹并使用相对路径插入,完成代码、效果图与说明的对应整理。

知识点 ​

结构伪类选择器:按结构找元素 ​

为什么需要:以前选第一个、最后一个或第 6 个 li,常要给元素起类名;元素一多,类名难起也难维护。结构伪类选择器能按元素的结构关系直接查找。

怎么想:先写基础选择器定位范围,如 ul li,再在 li 后加伪类冒号,如 :first-child。转写中强调:ul li 是后代选择器,li:first-child 才表示“既是 li,又是第一个孩子”。

怎么做:作用是根据元素的结构关系查找元素。

结构伪类选择器示意

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>
    /* 结构伪类选择器 */
    /* 1.选择第一个li */
    ul li:first-child {
      color: pink;
    }

    /* 2. 最后一个小li */
    ul li:last-child {
      color: green;
    }

    /* 3. 选择其中任意一个 */
    ul li:nth-child(6) {
      color: red;
    }
  </style>
</head>

<body>
  <!-- ul>li{第$个}*8 -->
  <ul>
    <li>我是第1个小li</li>
    <li>我是第2个小li</li>
    <li>我是第3个小li</li>
    <li>我是第4个小li</li>
    <li>我是第5个小li</li>
    <li>我是第6个小li</li>
    <li>我是第7个小li</li>
    <li>我是第8个小li</li>
  </ul>
</body>

</html>

结构伪类选择器运行效果

易错点:first-child、last-child 前的空格不能乱加;nth-child(6) 写几选第几个,写 666 不会报错,但页面没有第 666 个 li,所以不会选中。结构伪类本身权重为 10,加上 ul、li 两个标签后为 12。

:nth-child(公式):一次选多个 ​

为什么需要:只选一个不够,表格隔行变色、每 5 个去右边距等,需要按公式批量选。

怎么想:把 n 看成从 0 开始自增的变量:2n 得 0、2、4、6……即偶数;2n+1 得 1、3、5……即奇数;5n 是 5 的倍数;-n+5 得 5、4、3、2、1,即前 5 个且包含第 5 个;n+5 从第 5 个往后且包含第 5 个。

nth-child公式表

提示:公式中的n取值从 0 开始。

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>
    /* 公式 */
    /* 2n 是偶数个 */

    ul li:nth-child(2n) {
      background-color: #eee;
    }

    ul li:hover {
      background-color: #bbb;
    }

    /* 2n+1 奇数 */
    /* ul li:nth-child(2n + 1) {
      background-color: #eee;
    } */

    /* 5n 5的倍数 */
    /* ul li:nth-child(5n) {
      background-color: #eee;
    } */

    /* -n+5 选择第5个以前的 包含第5个 */
    /* ul li:nth-child(-n + 5) {
      background-color: #eee;
    } */

    /* n+5 选择第5个以后的 包含第5个 */
    /* ul li:nth-child(n + 5) {
      background-color: #eee;
    } */
  </style>
</head>

<body>
  <ul>
    <li>我是第1个小li</li>
    <li>我是第2个小li</li>
    <li>我是第3个小li</li>
    <li>我是第4个小li</li>
    <li>我是第5个小li</li>
    <li>我是第6个小li</li>
    <li>我是第7个小li</li>
    <li>我是第8个小li</li>
    <li>我是第9个小li</li>
    <li>我是第10个小li</li>
    <li>我是第11个小li</li>
    <li>我是第12个小li</li>
    <li>我是第13个小li</li>
    <li>我是第14个小li</li>
    <li>我是第15个小li</li>
  </ul>
</body>

</html>

调试过程:转写中给偶数行加 #eee,再写 ul li:hover { background-color:#bbb; } 做鼠标经过高亮。结果第 14 个等偶数行鼠标经过不变色,因为 ul li:nth-child(2n) 和 ul li:hover 权重都是 12,后面的 #eee 覆盖了前面的 #bbb。解决:把 :hover 放到后面,或提高其权重。

易错点:n 从 0 开始;-n+5 和 n+5 都包含第 5 个;公式写错不会“智能修正”,要按数学结果理解。

伪元素选择器:用 CSS 造装饰盒子 ​

为什么需要:小箭头、小图标等装饰内容,不必额外写一个标签,可用伪元素模拟。

怎么想:::before 放在盒子内容前面,::after 放在内容后面,相当于盒子里有两个“虚拟小盒子”。它们不是 HTML 标签,检查时显示为 ::before、::after。

伪元素示意

伪元素前后位置示意

怎么做:

css
div::before {
  content: "before 伪元素";
}
div::after {
  content: "after 伪元素";
}

注意点:必须设置 content: "",没有内容也要引号留空;伪元素默认是行内显示模式,不能直接设宽高,需要 display: inline-block 等转换;权重和标签选择器相同。转写中强调:一个冒号是伪类,两个冒号是伪元素;content 漏写,伪元素直接失效。

易错点:把 ::before 写成一个冒号;忘记 content;直接给伪元素写宽高却不转显示模式;以为伪元素是真实 HTML 标签。

为什么需要 PxCook ​

PxCook(像素大厨)是一款切图设计工具软件,支持 PSD 文件的文字、颜色、距离自动智能识别。做页面时,如果只盯着效果图猜尺寸、猜颜色、猜字号,还原度会很低,而且反复问设计或反复截图取色很浪费时间。
怎么想:把它当成“设计稿到代码”的测量助手——能自动识别的优先看开发面板,识别不了的再用设计面板手动量。
怎么做:打开 PxCook,导入设计稿,在开发面板看文字、颜色、距离;在设计面板用测量、吸管等工具补数据。
易错点:不要把它当成“一键生成页面”的工具。它给的是参考数据,最终仍要自己判断选哪个盒子、哪些属性该复制。

先分清设计面板与开发面板 ​

PxCook 里重点看两个面板:开发面板和设计面板。开发面板用于自动智能识别,设计面板用于手动测量尺寸和颜色。
为什么需要:同一个设计稿,文字字号、颜色适合在开发面板直接拿;两个元素之间的距离、某个区域的宽高,则常常要在设计面板里量。
怎么想:先点目标元素,看开发面板有没有现成的字号、颜色、宽高;如果没有或不准,再切到设计面板手动测。
怎么做:在开发面板点击文字或盒子,查看它给出的宽高、字号、字体、颜色、行高、背景色等信息;在设计面板用测量工具、智能标注、吸管取色。
易错点:选错元素时,拿到的宽高可能不是你要的大盒子,而是里面某个小元素;不要看到一个数值就全盘复制。

创建项目并导入设计稿 ​

使用方法:创建项目 → 输入项目名称、项目类型 Web → 单击按钮【创建项目】 → 单击按钮【添加】,导入设计稿。
为什么需要:先建项目,PxCook 才能按项目组织设计稿和标注信息。
怎么想:课程阶段做网页,项目类型选 Web;以后做 iOS、Android 移动端页面,再按对应类型选。
怎么做:打开 PxCook,点击创建新项目,名称可自定义,类型选 Web,点击创建项目;进入项目后点【添加】,把图片或 PSD 设计稿拖进来或选择导入。PSD 文件较大时稍等加载。
易错点:项目类型别误选成 iOS 或 Android;普通 PNG/JPG 里的文字不能像 PSD 那样直接选中,PSD 导入后文字通常可以选中并查看字号、颜色。

像素大厨创建项目界面

设计面板:手动测量尺寸、颜色和距离 ​

设计面板适合手动测量。常用操作包括:Ctrl 加加号放大、Ctrl 加减号缩小,按住空格键拖动画布;用测量工具从一个边拉到另一个边看宽高;用智能标注拉两个元素之间的距离;用区域标注框出盒子;用吸管取色;用坐标查看位置。
为什么需要:开发面板不是万能的,尤其普通图片没有 PSD 图层信息时,只能靠手动测量。
怎么想:先放大画布,尽量贴边测量;尺寸出现 269、271 这类数值时,结合设计规范取 270 这类整数。
怎么做:选测量工具拉宽高;选智能标注量间距;选吸管点颜色;选区域标注框盒子大小。
易错点:拉线没贴边会差一两像素;不要为了“完全一样”死磕,课程阶段先保证结构、字号、颜色大致正确,后面学盒模型再调间距。

开发面板:自动识别文字、颜色、距离 ​

导入 PSD 后,开发面板会自动智能识别。点文字能看到字号、字体、颜色等;点盒子能看到宽高、坐标;背景还能看到透明度信息,例如半透明黑色会给出类似 rgba(0,0,0,0.3) 的参考。
为什么需要:手写文字内容、字号、颜色最容易抄错,开发面板能直接复制,减少误差。
怎么想:文字优先复制文案和字号、颜色;盒子优先确认是不是目标大盒子;距离用智能标注补。
怎么做:点目标元素,看开发面板给出的 CSS 信息,需要的内容复制到代码里;不需要的宽高、坐标不要全抄。
易错点:开发面板默认单位多为 PX,当前阶段不要误选 REM;它给出的某些宽高可能属于内部小元素,复制前先判断;复制后仍要在浏览器里调试。

易错点与使用建议 ​

PxCook 的价值是“测量和取数”,不是替代写代码。使用时先看开发面板,再用手动测量补距离;先搭结构,再调字号颜色间距。设计稿是参照,不是每个像素都必须一模一样。类似工具还有蓝湖等,后面拿到在线标注地址时,也可以按同样思路点元素、看样式、量距离。

代码示例 ​

示例 1:结构伪类选择器 —— 基本使用(first-child / last-child / nth-child) ​

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>
    /* 结构伪类选择器 */
    /* 1.选择第一个li */
    ul li:first-child {
      color: pink;
    }

    /* 2. 最后一个小li */
    ul li:last-child {
      color: green;
    }

    /* 3. 选择其中任意一个 */
    ul li:nth-child(6) {
      color: red;
    }
  </style>
</head>

<body>
  <!-- ul>li{第$个}*8 -->
  <ul>
    <li>我是第1个小li</li>
    <li>我是第2个小li</li>
    <li>我是第3个小li</li>
    <li>我是第4个小li</li>
    <li>我是第5个小li</li>
    <li>我是第6个小li</li>
    <li>我是第7个小li</li>
    <li>我是第8个小li</li>
  </ul>
</body>

</html>

要点解释 / 易错点:

  • ul li:first-child 是后代选择器 + 伪类,ul 和 li 之间有空格;伪类用一个冒号,这是与伪元素(两个冒号)区分的记忆点。
  • 结构伪类选择器的本质是「根据元素的结构关系查找元素」:第几个、第一个、最后一个,不用再起类名,选起来更简洁。
  • :first-child / :last-child 是跟着结构自动走的:把第一个 li 删掉后,原来的第二个就自动变成被选中的「第一个」,不需要改 CSS。
  • 权重:ul li:first-child 中两个标签(ul、li)= 0,0,2,伪类 = 0,1,0,合计 0,0,2,1(12),不要当成普通标签选择器的 1 来算。
  • :nth-child(6) 括号里写数字就是「第几个」,写 6 就选第 6 个;如果写 :nth-child(666) 而页面没那么多元素,就什么都不选,不是报错。

示例 2::nth-child(公式) —— 偶数行变色 + 鼠标经过高亮 ​

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>
    /* 公式 */
    /* 2n 是偶数个 */

    ul li:nth-child(2n) {
      background-color: #eee;
    }

    ul li:hover {
      background-color: #bbb;
    }

    /* 2n+1 奇数 */
    /* ul li:nth-child(2n + 1) {
      background-color: #eee;
    } */

    /* 5n 5的倍数 */
    /* ul li:nth-child(5n) {
      background-color: #eee;
    } */

    /* -n+5 选择第5个以前的 包含第5个 */
    /* ul li:nth-child(-n + 5) {
      background-color: #eee;
    } */

    /* n+5 选择第5个以后的 包含第5个 */
    /* ul li:nth-child(n + 5) {
      background-color: #eee;
    } */
  </style>
</head>

<body>
  <ul>
    <li>我是第1个小li</li>
    <li>我是第2个小li</li>
    <li>我是第3个小li</li>
    <li>我是第4个小li</li>
    <li>我是第5个小li</li>
    <li>我是第6个小li</li>
    <li>我是第7个小li</li>
    <li>我是第8个小li</li>
    <li>我是第9个小li</li>
    <li>我是第10个小li</li>
    <li>我是第11个小li</li>
    <li>我是第12个小li</li>
    <li>我是第13个小li</li>
    <li>我是第14个小li</li>
    <li>我是第15个小li</li>
  </ul>
</body>

</html>

要点解释 / 易错点:

  • 公式中的 n 从 0 开始自增:2n → 0、2、4、6…(第 0 个不存在就跳过)所以是偶数;2n+1 → 1、3、5…是奇数(2n-1 也行,但习惯写 2n+1,从 1 开始更顺)。
  • 5n 就是 5 的倍数(第 5、10、15 个),实际开发中常用来去掉「每行最后一个盒子」的右间距;想要几的倍数就写几 n。
  • -n+5 → 5、4、3、2、1,是前 5 个(包含第 5 个);n+5 → 5、6、7…是第 5 个以后(也包含第 5 个)。写的时候别把负号漏掉,n+5 和 -n+5 完全是两个结果。
  • 这里是本段最重要的易错点:ul li:nth-child(2n) 和 ul li:hover 的权重相同(都是 12),所以写在后面的 :hover 能盖住偶数行背景;一旦把 :hover 挪到上面去,鼠标经过偶数行就不变色了——相同权重下「后来者居上」。想让它一直生效,要么调换顺序,要么提高权重。
  • background-color: #bbb 比 #eee 更靠近 0,颜色更深,所以经过时能看出高亮变化。

示例 3:伪元素选择器 —— ::before / ::after ​

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>
    div::before {
      content: "before 伪元素";
      background-color: pink;
      display: inline-block;
      width: 30px;
      height: 30px;
    }

    div::after {
      content: "after 伪元素";
    }
  </style>
</head>

<body>
  <div>我是盒子里的文字</div>
</body>

</html>

要点解释 / 易错点:

  • 伪元素用两个冒号 ::(一个冒号的是伪类,别混);::before 的内容插在盒子内容的前面,::after 插在内容的后面,相当于这个盒子的「左右护法」。
  • content: "" 是必须属性,不能省。没内容就写空引号 content: "";;一旦漏写 content,伪元素直接失效,不是字没了,是整个伪元素都不生成。
  • 伪元素默认是行内显示模式,所以直接写 width: 30px; height: 30px; 是没有效果的,必须先 display: inline-block; 转成行内块才能给宽高(写成 block 就独占一行了,几个字就不在一行上)。
  • 权重:伪元素和标签选择器相同,都是 1(而伪类/类是 10)。所以 div::before 权重是 0,0,2,覆盖别人时要算清楚。
  • 伪元素是 CSS 模拟出来的虚拟盒子,HTML 里没有对应标签、内容也选不中;F12 审查时只能看到 ::before / ::after,这是正常的,不是代码写错。
  • 使用场景是「装饰性内容」:箭头、小图标、分隔线等,用它就不用在每个 a 里再套一个 span,结构更干净。

常见错误 ​

1. 伪元素写了样式却完全不显示

  • 现象:.box::before { color: red; } 页面上什么都没有。
  • 原因:漏了 content,伪元素直接失效(不是"没内容",是整个盒子不存在)。
  • 修法:任何 ::before / ::after 先补 content: "";,再写其他样式。

2. 伪元素设了宽高不生效

  • 现象:::after { width: 20px; height: 20px; } 尺寸没变化。
  • 原因:伪元素默认行内显示模式,行内元素不接受宽高。
  • 修法:加 display: inline-block;(或 block),再给宽高。

3. nth-child 选错了元素

  • 现象:ul li:nth-child(2) 高亮的不是第二个 li。
  • 原因:nth-child 数的是父元素下所有子元素的序号,不是"同类元素里的第几个"。
  • 修法:先数清父元素下第 n 个孩子是谁;结构不干净时优先保证目标位置没有别的兄弟节点插队。

4. 把公式当成"第几个"用

  • 现象:想选第 5 个,写了 nth-child(5n),结果选中一大片。
  • 原因:混淆"具体数字"和"公式",且忘记公式里的 n 从 0 开始自增。
  • 修法:选单个 → 直接写数字 nth-child(5);要规律 → 才用 2n / 5n / -n+5 这类公式,写完先数前三个命中项验证。

5. :hover 与 :nth-child 冲突,悬停没反应

  • 现象:斑马纹列表里,鼠标经过部分行颜色不变。
  • 原因:两条规则权重相同,后写的覆盖前写的,背景色被 nth-child 那条压住。
  • 修法:把 :hover 规则放到后面,或合并提升权重,如 ul li:nth-child(2n):hover { ... }。

6. 结构伪类中间多了空格

  • 现象:只想选第一个 li,结果整片都变了。
  • 原因:ul li :first-child 多了空格,变成后代选择器,含义完全变了。
  • 修法:结构伪类紧贴元素写 ul li:first-child,符号前不留空格。

练习 ​

练习 1|斑马纹 + 悬停(重点:权重) 15 个 li,偶数行浅灰底;鼠标经过任意一行(含偶数行)底色加深。 验收:把鼠标依次移过第 1、2、14、15 行,四行都必须变色。

练习 2|只写选择器,不写 HTML 给定 ul > li * 12,分别写出: ① 只选第 3 个;② 只选最后 1 个;③ 选所有奇数行;④ 选前 4 个;⑤ 选第 6 个及以后。 验收:每条规则写完立刻在页面上数一遍命中项数量。

练习 3|首尾 + 倍数组合 12 个 li:第 1 个红色、最后 1 个绿色、所有 4 的倍数加浅蓝底,其余默认。 验收:三个效果互不覆盖,且改 li 数量后首尾自动跟着变。

练习 4|伪元素做装饰箭头 给一组导航链接右侧加一个小三角,要求 HTML 里只有 a 标签,不额外加 span。 验收:① 页面结构里看不到多余标签;② 在开发者工具里能看到 ::after 及其样式;③ 用文字回答"为什么这里用伪元素比加标签更合适"。

练习 5|PxCook 取数值 用 PxCook 打开今日设计稿,任选一个卡片模块,量出:盒子宽高、标题字号、正文行高、文字颜色。 验收:输出一段可直接粘贴的 CSS,单位全部为 px,颜色为十六进制;数值与设计稿误差不超过 1px。

原视频对照 ​

#视频时长
1复习反馈和今日内容30:33
2课程回顾02:18
3结构伪类选择器12:15
4课程介绍07:29
5md笔记配置图片设置03:31
6结构伪类公式15:43
7伪元素10:43
8像素大厨12:38

小结 ​

  1. 结构伪类的价值在"免起类名"——能靠位置描述的,就别再往 HTML 里塞 class。
  2. 判断用数字还是公式:选一个用数字,选一批有规律的才用公式;公式写完必须验证前三个命中项。
  3. nth-child 数的是全体兄弟,写之前先在脑子里把父元素的子节点从头数一遍,比事后调试省时间。
  4. 伪元素三件套别丢:双冒号、content、行内模式要设宽高先转 inline-block。
  5. 伪元素只放装饰性内容(箭头、小图标、分割线);正文文字放进去就选不中、复制不了,属于用错场景。
  6. 选择器写多了必然撞权重,:hover 这类交互态规则建议统一写在样式块靠后位置,减少"改了没反应"的排查成本。
  7. PxCook 只负责给数值,不负责给答案——量到宽高字号颜色即可,不要整段复制它的代码,里面大量属性当前用不上。
  8. 本页的三个点(结构伪类、伪元素、切图工具)都是后面布局的零件,现在只需写对、选对,精度问题留给盒模型去解决。