Skip to content

CSS 进阶(一) ​

本页对应 CSS 进阶,共 8 段视频,约 1 小时 31 分。

学习目标 ​

  1. 能分别写出后代选择器、子代选择器、并集选择器和交集选择器的语法,并说明各自使用的分隔符与选择范围。
  2. 能根据给定 HTML 结构,正确选用后代或子代选择器,只选中目标元素而不误选其他同级或后代元素。
  3. 能使用交集选择器和并集选择器完成“既是某标签又带某类名”及“多个选择器共用同一样式”的样式编写。
  4. 能使用 :hover 伪类实现鼠标经过链接或盒子时改变颜色、下划线、背景色等状态样式。
  5. 能按 link → visited → hover → active 的正确顺序编写链接伪类,并说明顺序颠倒后的影响。
  6. 能依据层叠性规则判断相同属性冲突时由后写样式覆盖、不同属性叠加生效,并能借助浏览器调试工具识别被覆盖的样式。

知识点 ​

复合选择器是什么 ​

为什么需要:标签、类、id 等基础选择器只能“单点选择”,页面一复杂就不够精确。怎么想:把两个或多个基础选择器按规则组合,先缩小范围,再命中目标。怎么做:复合选择器由基础选择器组合而成,作用是更准确、更高效地选择目标元素。易错点:复合选择器不是新标签,也不是随便拼接;不同组合符号含义不同,空格、>、,、连写不能混。

后代选择器 ​

为什么需要:页面里常有多个同名标签,只想改“某一组里的后代”。怎么想:先找父级限定范围,再找里面的后代;后代包括儿子、孙子等。怎么做:父选择器 子选择器,中间用空格隔开。

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>
    /* li {
      color: red;
    } */

    /* .red {
      color: red;
    } */
    /* 后代选择器 中间用空格隔开 */
    /* ul li {
      color: red;
    } */

    /* 只让第一组ul 里面的li变色 */
    .first li {
      color: red;
    }
  </style>
</head>

<body>
  <ul class="first">
    <li>我是无序列表</li>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
  </ul>
  <ul>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
  </ul>
  <ol>
    <li>我是有序列表</li>
    <li>我是有序列表</li>
    <li>我是有序列表</li>
    <li>我是有序列表</li>
  </ol>
</body>

</html>

易错点:空格不是“和”,而是“里面的”;.first li 只选第一组 ul 的后代 li。转写稿补充:后代选择器执行时先找孩子再找父亲,像找刘德华先确定人,再确定“淄博的刘德华”;一般不建议超过三层。

子代选择器 ​

为什么需要:只想选“亲儿子”,不想选孙子。怎么想:后代范围太大时,用 > 限定最近一级子级。怎么做:父选择器 > 子选择器。

html
<style>
  div > span {
    color: red;
  }
</style>

<div>
  <span>这是 div 里面的 span</span>
  <p>
    <span>这是 div 里面的 p 里面的 span</span>
  </p>
</div>

易错点:div span 会选儿子和孙子;div > span 只选最近的 span。> 两边可有空格,但符号不能写成逗号。

并集选择器 ​

为什么需要:多组标签要设置相同样式,逐个写重复。怎么想:把多个选择器“合在一起”,理解为“和”。怎么做:选择器1, 选择器2, …,用逗号隔开。

html
<style>
  div,
  p,
  span {
    color: red;
  }
</style>

<div> div 标签</div>
<p>p 标签</p>
<span>span 标签</span>

易错点:逗号不能漏;最后一个选择器后可不加逗号。并集是“都要”,不是“既又”。

交集选择器 ​

为什么需要:只选“既是某标签,又带某类名”的元素。怎么想:两个条件同时满足才命中。怎么做:选择器连写,没有任何符号。

html
<style>
  p.box {
  color: red;
}
</style>

<p class="box">p 标签,使用了类选择器 box</p>
<p>p 标签</p>
<div class="box">div 标签,使用了类选择器 box</div>

易错点:p.box 中间不能空格;有标签选择器时,标签必须写在最前面。转写稿提醒:p.box 可理解为“既是 p,又有 box 类名”。

伪类选择器与 :hover ​

为什么需要:元素有状态,如鼠标悬停、点击,普通选择器选不到“状态”。怎么想:先选元素,再限定状态;:hover 表示鼠标经过。怎么做:选择器:hover { CSS 属性 }。

html
<style>
  a:hover {
    color: red;
  }
  .box:hover {
    color: green;
  }
</style>

<a href="#">a 标签</a>
<div class="box">div 标签</div>

易错点:冒号左右不要加空格;:hover 本质类似“既是该元素,又处于悬停状态”。调试时 Chrome 里样式被划掉不是代码错误,而是被后面同属性覆盖;出现黄色感叹号才要检查单词拼写。取消下划线用 text-decoration: none,添加下划线用 text-decoration: underline。

超链接伪类 ​

超链接四种伪类状态示意图

为什么需要:链接有访问前、访问后、悬停、点击等状态。怎么想:按状态分别写样式,但要固定顺序。怎么做:按 LVHA 顺序书写::link、:visited、:hover、:active。工作中常用 a 设基础样式,再用 a:hover 特殊设置。

css
a {
  color: red;
}

a:hover {
  color: green;
}

易错点:顺序乱写可能导致 hover 不生效;提示要按 LVHA 顺序。转写稿中的“RVHA”是记忆口诀,正式顺序仍以笔记的 LVHA 为准。

基本选择器与复合选择器对照 ​

基本选择器说明举例
标签选择器选择页面中同名标签div
类选择器选择1个或者多个.red {color: red;}
id选择器唯一的,只能使用一次#red {color: red;}
通配符选择器选择所有的标签*
复合选择器说明举例
后代选择器选择子孙后代 用 空格 隔开div span
子代选择器只选最近一级孩子(亲儿子选择器) 用 > 隔开div>span
并集选择器选择多个标签, 用 逗号 隔开 理解为 和div, span, p
交集选择器既又的关系,既是某标签,又是某类名p.one
伪类选择器状态关系, :hover 鼠标经过div:hover

CSS特性总览 ​

CSS特性主要用来化简代码、定位问题并解决问题,核心包括继承性、层叠性、优先级。理解它们,才能知道“样式为什么生效/失效”。

继承性 ​

为什么需要:很多文字样式在父级设置一次,子级自动拥有,减少重复代码。
怎么想:子级默认继承父级的文字控制属性,如颜色、字号、字重等;但标签自带默认样式时会继承失败。转写稿中演示了:p 里的 a 不继承父级颜色,h1 不继承 div 的字号和加粗。
怎么做:给父级设置文字样式,子级通常不用重复写;遇到链接、标题要单独选中修改。
易错点:继承的是文字类属性,宽高、背景等不继承;继承权重为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>继承性</title>
    <style>
      /* div {
      color: red;
      font-size: 30px;
      height: 100px;
      }

      span {
      color: green;
      } */

      p {
        color: pink;
      }

      /* 特殊情况1: 链接不会继承颜色 */
      a {
        color: red;
      }

      div {
        color: red;
        font-weight: 400;
        font-size: 14px;
      }

      /* 特殊情况2: 标题的字号和加粗不会继承 */
      h1 {
        font-weight: 400;
        font-size: 14px;
      }
    </style>
  </head>

  <body>
    <!-- <div>
<span>我是孩子</span>
</div> -->
    <p>
      <a href="#">我是链接</a>
    </p>
    <div>
      <h1>一级标题</h1>
    </div>
  </body>

</html>

层叠性 ​

为什么需要:同一标签可能被多条规则命中,必须规定冲突时听谁的。
怎么想:相同属性后写的覆盖先写的;不同属性会叠加,都生效。注意:选择器类型相同才按层叠性判断,否则看优先级。
怎么做:如下方代码,color后写绿色生效,font-weight和font-size不同属性叠加。调试工具中样式被划掉但没有黄色感叹号,说明不是写错,而是被层叠;若带黄色感叹号,才要检查单词/语法。
易错点:被划掉不等于错误;不要一看到失效就乱改,先往上找覆盖规则。

html
<style>
  div {
    color: red;
    font-weight: 700;
  }
  div {
    color: green;
    font-size: 30px;
  }
</style>

<div>div 标签</div>

层叠性示意图

优先级 ​

为什么需要:当一个标签被多种选择器同时选中,需要判断哪条样式生效。
怎么想:权重公式为:通配符/继承 < 标签选择器 < 类选择器/伪类 < id选择器 < 行内样式 < !important。复合选择器要权重叠加,每一级之间不进位,从左向右比较。
怎么做:例如 div 与 .box 同时命中,类选择器权重更高,绿色生效。
易错点:!important权重最高;继承权重最低;复合选择器不是简单看最后一级,要累加比较。

html
<style>
  div {
    color: red;
  }
  .box {
    color: green;
  }
</style>

<div class="box">div 标签</div>

优先级权重叠加示意图

选择器权重说明
继承/ *通配符0没有权重
标签选择器1累加
类选择器/伪类选择器10累加
id选择器100累加
行内1000
!important∞

继承的权重是0 ​

为什么需要:解释“为什么给父级写了样式,甚至加了!important,子级仍不变”。
怎么想:继承来的样式权重是0;直接选中li的标签选择器权重是1,1>0,所以li红色生效。转写稿强调:想修改谁的样式,就要选择谁。
怎么做:下面代码中.box的颜色即使加!important,继承到li后仍无法直接覆盖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>
      /* li的权重是1 ,比 0 高 */
      li {
        color: red;
      }

      /* 继承的权重是 0, 所以无法直接修改 li的样式 */
      .box {
        color: green !important;
      }
      /* 结论: 想要修改谁的样式,就要选择谁 */
    </style>
  </head>

  <body>
    <ul class="box">
      <li>我是文字</li>
    </ul>
  </body>

</html>

先理解 Emmet:把重复代码“压缩”成缩写 ​

为什么需要:写 HTML、CSS 时经常要重复输入标签、类名、属性。如果每次都手打,既慢又容易漏闭合标签。Emmet 的价值就是把“常见结构”变成一段缩写,让 VS Code 自动展开成完整代码。

怎么想:把 Emmet 当成“代码的简写方式”。先判断我要写的是 HTML 结构,还是 CSS 样式;再想这个结构/属性有没有固定缩写;最后输入缩写让编辑器生成,而不是从零手敲。

怎么做:在 VS Code 的 HTML/CSS 文件里输入缩写,编辑器会给出提示并生成对应代码。课堂演示中,输入后按回车即可生成。比如写列表时,转写稿中演示了“无序列表里放 4 个小 li”的写法:

html
输入:ul>li*4
生成:
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

易错点:Emmet 是“缩写展开”,不是替代理解结构。生成后仍要检查标签嵌套、类名、闭合是否正确;不要把“简写”写成“减写”,也不要把 Emmet 当成万能代码。

HTML 标签缩写:从骨架到常用结构 ​

为什么需要:HTML 标签多、嵌套多,尤其列表、链接、图片、段落经常重复。用缩写能快速搭骨架,减少手写错误。

怎么想:先看结构关系:父子用 >,重复用 *数量;单个标签可直接写标签名。课堂中写段落时用 p,写链接用 a,写图片用 img,都是把标签名作为缩写起点。

怎么做:保留本节笔记中的 HTML 标签示例图:

Emmet 生成 HTML 标签示例

常见做法是先输入 ul>li*4 生成列表骨架,再把 ul 改成 ol 就得到有序列表;需要段落时输入 p,需要链接时输入 a,需要图片时输入 img。生成后再补文字、href、src 等内容。

易错点:> 表示父子关系,不要和后代选择器的空格混淆;*4 是重复数量,不要漏写;生成后要检查是否多生成了标签,写错时可用 Ctrl+Z 撤销。

CSS 属性缩写:多数取属性单词首字母 ​

为什么需要:CSS 属性名较长,如 font-size、background-color、text-decoration。反复手写效率低,也容易拼错。

怎么想:本节笔记明确说:CSS 大多数简写方式为属性单词的首字母。所以先记属性英文,再取首字母组合。课堂中反复用到 fz 表示字体大小、bgc 表示背景色、tdn 表示取消下划线、tdu 表示添加下划线。

怎么做:保留本节笔记中的 CSS 简写示例图:

Emmet 生成 CSS 属性简写示例

课堂中常见写法可整理为:

css
fz26      /* font-size: 26px; */
bgc       /* background-color */
tdn       /* text-decoration: none; 取消下划线 */
tdu       /* text-decoration: underline; 添加下划线 */

写盒子时还会用“加号”连续写多个样式,例如宽、高、背景色一起写,减少反复敲属性名。

易错点:CSS 缩写依赖属性英文,单词不熟就容易写错;tdn 和 tdu 只差一个字母,分别对应“不要下划线”和“要下划线”;生成后要看单位、颜色值是否补全。

组合缩写与类名:.box、p.box、strong.pink ​

为什么需要:页面里经常要生成“带类名的标签”。如果先写标签再补 class,步骤多;Emmet 可以把标签和类名一起写出来。

怎么想:点 . 后面跟类名,表示给元素加类名;前面不写标签时,默认生成 div。前面写标签,就生成指定标签加类名。转写稿中明确演示了 .box 默认生成 div class="box",p.box 生成 p class="box",strong.pink 生成带 pink 类名的 strong。

怎么做:

html
输入:.box
生成:<div class="box"></div>

输入:p.box
生成:<p class="box"></p>

输入:strong.pink
生成:<strong class="pink"></strong>

易错点:标签和类名之间不要加空格;.box 默认是 div,不是任意标签;类名拼错后生成结果也会错,发现不对先用 Ctrl+Z 撤回再改。

调试与易错点:生成不对时先撤销、再查找替换 ​

为什么需要:Emmet 写得快,但写错缩写、类名或批量内容时,错误也会被快速放大。课堂中强调过写错不要硬改,可以用 Ctrl+Z 撤销;批量改文字可用 Ctrl+F 查找、Ctrl+H 替换;代码长了可用 Ctrl+G 跳到指定行。

怎么想:先判断是“缩写写错”还是“生成后内容要批量调整”。缩写错就撤销重写;批量文字/标签要统一改,就用查找替换,而不是一个个手改。

怎么做:例如把页面中多处“web 前端”统一替换成 em 包裹的内容时,课堂演示了 Ctrl+H 查找替换;替换后若样式不对,再回到 CSS 中检查选择器。调试工具里如果样式被划掉,不一定是代码写错,可能是被后面的层叠覆盖;若出现黄色叹号,才要重点检查单词/语法是否写错。

易错点:不要看到样式失效就乱改,先看是否被覆盖;Ctrl+Z 是撤销,不要用成删除;Emmet 生成的是“起点代码”,最终仍要按页面结构检查标签、类名和样式是否对应。

课件图示 ​

课件第2页:l 复合选择器 l CSS 特性 l 背景属性 l 显示模式

课件第18页:Emmet 写法 Emmet写法:代码的简写方式,输入缩写 VS Code 会自

课件第16页:优先级 – 叠加计算规则 叠加计算:如果是复合选择器,则需要权重叠加计算。 公式

课件第8页:交集选择器 – 了解 交集选择器:选中同时满足多个条件的元素。 选择器写法:选择

课件第9页:伪类选择器 伪类选择器:伪类表示元素状态,选中元素的某个状态设置样式。 鼠标悬停

课件第30页:背景属性 描述 属性 背景色 background-color 背景图 back

代码示例 ​

1. 后代选择器 ​

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>
    /* 后代选择器 中间用空格隔开 */
    /* ul li {
      color: red;
    } */

    /* 只让第一组 ul 里面的 li 变色 */
    .first li {
      color: red;
    }
  </style>
</head>
<body>
  <ul class="first">
    <li>我是无序列表</li>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
  </ul>
  <ul>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
    <li>我是无序列表</li>
  </ul>
  <ol>
    <li>我是有序列表</li>
    <li>我是有序列表</li>
    <li>我是有序列表</li>
    <li>我是有序列表</li>
  </ol>
</body>
</html>

关键行与易错点:

  • .first li:父选择器与子选择器之间用空格隔开,表示选中 .first 元素的后代 li。
  • 后代包括儿子、孙子等所有后代,不只是亲儿子;如果写成 ul li,会选中页面中所有 ul 里的 li。
  • 易错点:空格不能丢;.first li 只限定类名为 first 的那一组 ul,不会影响第二组 ul 和 ol。
  • 笔记小技巧:后代选择器执行时先找孩子再找父亲,类似“先确定刘德华,再确定他在淄博”。

2. 子代选择器 + 伪类选择器 ​

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>
    /* 子代选择器:只选最近一级子元素 */
    div > span {
      color: red;
    }

    /* 超链接伪类 */
    a {
      color: red;
    }

    a:hover {
      color: green;
    }

    /* 鼠标悬停状态 */
    .box:hover {
      color: green;
    }
  </style>
</head>
<body>
  <div>
    <span>这是 div 里面的 span</span>
    <p>
      <span>这是 div 里面的 p 里面的 span</span>
    </p>
  </div>

  <a href="#">a 标签</a>
  <div class="box">div 标签</div>
</body>
</html>

关键行与易错点:

  • div > span:> 表示子代选择器,只选中 div 的最近一级子元素 span,不会选中 p 里面的 span。
  • 易错点:如果写成 div span(空格),会选中 div 里所有后代 span,包括 p 里的 span。
  • a:hover:伪类表示元素状态,这里表示鼠标悬停在 a 标签上时变绿色;.box:hover 表示鼠标悬停在类名为 box 的元素上时变绿色。
  • 易错点::hover 冒号左右不要加空格;超链接四个状态要按 LVHA 顺序书写(link、visited、hover、active),否则可能不生效。
  • 工作中常见写法:a 设置基础样式,a:hover 单独设置悬停样式。

3. CSS 特性:层叠性 + 继承权重为 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>层叠性与继承权重</title>
  <style>
    /* 层叠性:相同属性后面覆盖前面,不同属性叠加 */
    div {
      color: red;
      font-weight: 700;
    }

    div {
      color: green;
      font-size: 30px;
    }

    /* li 的权重是 1,比继承的 0 高 */
    li {
      color: red;
    }

    /* 继承的权重是 0,所以无法直接修改 li 的样式 */
    .box {
      color: green !important;
    }
  </style>
</head>
<body>
  <div>div 标签</div>

  <ul class="box">
    <li>我是文字</li>
  </ul>
</body>
</html>

关键行与易错点:

  • 层叠性:两个 div 选择器中,color 相同,后面的 green 覆盖前面的 red;font-weight 和 font-size 是不同的属性,会叠加生效。
  • 易错点:选择器类型相同才按层叠性判断;如果选择器类型不同,要按优先级判断。
  • li { color: red; } 直接选中 li,权重为 1;.box { color: green !important; } 选中的是 ul,li 的颜色是继承来的,继承权重为 0,所以 li 最终仍为红色。
  • 易错点:不要以为给父级加 !important 就一定能覆盖子级;想修改谁的样式,就要选择谁。
  • 补充:继承的是文字控制属性;a 标签的颜色、标题的字体大小等有默认样式时,继承会失败。

常见错误 ​

1. 后代选择器的空格被写成逗号或连写

  • 现象:div, span { color: red; } 写成本意是"div 里的 span",结果页面里所有 span 和所有 div 全变红。
  • 原因:把"和"(并集,逗号)当成了"里面的"(后代,空格)。
  • 修法:记住三种符号的语义——div span(空格=里面的)、div, span(逗号=和)、div.span(连写=既是又是);写完扫一眼选择器里有没有多余的逗号。

2. 给父元素设宽高/背景,指望子元素变成盒子

  • 现象:ol { width:100px; height:100px; background:pink; } 后,里面的 li 并没有变成 100×100 的小方块。
  • 原因:继承只发生在文字类属性上,宽高、背景、边框、内外边距一律不继承。
  • 修法:要改谁的样式就选中谁——ol li { width:100px; height:100px; background:pink; }。父级只负责"圈范围",不负责"改长相"。

3. 父级加 !important 仍然改不动子元素

  • 现象:.box { color: green !important; } 套在 ul 上,li 里已经有 li { color: red; },结果 li 依旧是红色。
  • 原因:继承权重恒为 0,0 再乘无穷还是 0,任何直接选中该元素的规则(哪怕权重只有 1)都能压过它。
  • 修法:想让谁变就选中谁,写成 .box li { color: green; };!important 不是用来"隔代传功"的。

4. 以为 a 和标题会乖乖继承颜色和字号

  • 现象:给 div 设了 color:red; font-size:30px;,div 里普通文字变了,里面的 a 还是蓝色带下划线,h1 还是又大又粗。
  • 原因:浏览器给 a、h1~h6 等标签内置了默认样式,有默认值就不吃继承。
  • 修法:单独写 a { color: red; text-decoration: none; }、h1 { font-size:30px; font-weight:400; } 显式覆盖。

5. 该用子代时用了后代(或多敲了空格)

  • 现象:div span { color:red; } 把 div > p > span 这个"孙子"也染红了,而需求只要"亲儿子"。
  • 原因:后代选择器不限层级,孙子、重孙全算;且 div > span 中 > 两侧多写空格在部分书写习惯下容易漏符号。
  • 修法:只选最近一级用 div > span;同时控制后代选择器嵌套不超过三层,避免"一改全崩"。

6. 交集选择器标签写到后面 / 中间加了空格

  • 现象:p.box 写成 .box p 或 .box p(带空格),样式选不中目标,或者干脆选成"box 里面的 p"。
  • 原因:交集要求"既…又…"且必须连写,标签选择器还必须写在最前面。
  • 修法:一律写成 标签.类名(如 p.box),中间不留任何符号;Emmet 里用 p.box 直接生成。

7. 伪类冒号两侧留空格、链接四态顺序乱写

  • 现象:a :hover 或 a: hover 完全没效果;四态写成 a:hover 在最前面时,鼠标移上去颜色不变。
  • 原因:伪类本质是"连写的交集",冒号两侧不能有空格;链接四态必须按 LVHA 顺序,后写的同权重规则才能覆盖前面的。
  • 修法:写 a:hover;四态固定顺序 link → visited → hover → active,日常只写 a {} + a:hover {} 两条最省事。

8. DevTools 里样式被划掉就以为代码写错了

  • 现象:调试面板里某条 color 上有删除线,同学反复改这条代码,怎么改页面都不动。
  • 原因:删除线只代表"被同优先级的后写规则层叠覆盖了",只有前面带黄色感叹号才是语法/属性名错误。
  • 修法:看到删除线就顺着往上找同选择器的后写规则(层叠=后覆盖前);真报错才去查拼写。

练习 ​

练习 1(选择器选型) 给定结构:ul.first 下有 4 个 li,另一个 ul 下也有 4 个 li,ol 下有 4 个 li。分别写出满足下列需求的 CSS: ① 只让第一组 ul 的 li 变红;② 只让 ol 里的 li 变蓝;③ 让所有 li 的 line-height 都是 30px 但不动颜色。 要求:每题只写一行选择器,不许给 li 加 class。

练习 2(后代 vs 子代) 写一段 div > p > span 加一个 div > span 的结构,用两种写法分别实现:① 所有 span 变粉;② 只有 div 的直接子级 span 变粉。运行后说明为什么写法②能排除掉 p 里的 span。

练习 3(伪类交互) 做一个 a 链接:默认无下划线、颜色 #333;鼠标经过时变橙色并出现下划线。再做 100×100 的 p 盒子:鼠标经过时背景变 hotpink、文字变白、宽度变 200px。要求写出完整的 HTML+CSS,并用 DevTools 验证 hover 生效。

练习 4(找错并修复) 下面 4 行各有问题,指出问题并改正:

css
div,span { color: red; }        /* 本意:div 里的 span */
.box p { color: blue; }         /* 本意:既是 p 又带 box 类 */
a :hover { color: orange; }     /* 本意:a 的悬停态 */
.box { color: green !important; } /* 套在 ul 上,本意让里面 li 变绿 */

练习 5(Emmet + 权重判断) 用 Emmet 一句话生成"3 个带 item 类名的 li",再用一句话生成"带 red 类名的 p"。然后判断:#box .item 与 .item.item 谁赢?说明比较过程(提示:按 100 / 10 / 1 逐级比个数,不进位)。

原视频对照 ​

#视频时长
1复习反馈和今日内容30:33
2后代选择器11:56
3后代选择器细节07:13
4子代选择器和并集选择器07:56
5交集选择器05:45
6伪类选择器10:47
7链接伪类10:43
8层叠性07:04

小结 ​

  1. 复合选择器的四种符号必须形成肌肉记忆:空格=里面的,>=亲儿子,,=和,连写=既是又是。写错符号不会报错,只会"悄悄选错",比语法错误更难查。
  2. 复合选择器的真正价值是缩小选择范围,而缩小范围最常用的手段是"前面挂一个类名"(.first li),而不是给每一个子元素挨个加 class。
  3. 继承只覆盖文字控制属性(color、font-size、line-height、text-align 等),布局属性(宽高、背景、内外边距、边框)一律不继承;a、h1~h6 因为有浏览器默认样式而"继承失败"。
  4. 继承权重恒为 0,这是 !important 也救不了的硬限制。所有"样式不生效"的问题里,先问一句:我到底选中了那个元素没有?
  5. 层叠的两条规则要分开看:同属性看先后(后覆盖前),不同属性看叠加(都生效)。层叠只在"选择器类型相同"时才由先后决定,否则交给优先级。
  6. 优先级是四级累加、级间不进位:通配/继承 0 < 标签 1 < 类/伪类 10 < id 100 < 行内 1000 < !important;复合选择器比的是"哪一级个数多",不是"数字相加"。
  7. 调试的固定动作是:删除线=被层叠,往上找;黄色感叹号=写错了,改拼写。这条能省掉大量"改了没反应"的时间。
  8. 链接四态顺序(LVHA)不是记忆负担而是机制必然:同权重后写覆盖先写,顺序错了 hover 就会被 visited 压掉——这也是"为什么写了 hover 没反应"最常见的原因。