【H5 前端开发笔记】第 20 期:CSS 选择器 (5) 子元素伪类选择器 详解

【H5 前端开发笔记】第 20 期:CSS 选择器 (5) —— 子元素伪类选择器 详解(结构伪类 / Structural Pseudo-classes)

这一期重点讲解 基于文档树结构 的伪类(也叫树结构伪类),它们不依赖类、ID、属性,而是根据元素在父元素中的位置关系来选择,非常适合做列表、表格、网格、卡片组的“隔行变色”“首尾特殊处理”“循环条纹”等效果。

这些伪类在 CSS3 Selectors 中引入,现代浏览器(2026 年)全部完美支持。

一、核心子元素结构伪类一览表

伪类含义计数依据从哪数起?常用场景特异性
:first-child作为父元素的第一个子元素所有子元素从前去掉第一个元素的上边距0,1,0
:last-child作为父元素的最后一个子元素所有子元素从后去掉最后一个元素的下边距0,1,0
:only-child父元素唯一的子元素所有子元素单条数据时的特殊样式0,1,0
:first-of-type同类型标签中第一个同标签类型的子元素从前文章中第一个 p 加粗标题感0,1,0
:last-of-type同类型标签中最后一个同标签类型的子元素从后去掉最后一个段落下边距0,1,0
:only-of-type同类型标签中唯一的一个同标签类型的子元素只有一个 h2 时放大显示0,1,0
:nth-child(n)第 n 个子元素(公式)所有子元素从前隔行变色、3列循环、1+4n 等0,1,0
:nth-last-child(n)倒数第 n 个子元素(公式)所有子元素从后最后 3 个元素特殊处理0,1,0
:nth-of-type(n)同类型中第 n 个(公式)同标签类型的子元素从前只给 p 标签隔行变色0,1,0
:nth-last-of-type(n)同类型中倒数第 n 个(公式)同标签类型的子元素从后最后一个 li 不同样式0,1,0

二、最重要区别:child vs of-type

  • :nth-child / :first-child / :last-child看“出生顺序”,不管标签是什么,只要是第几个孩子就行
  • :nth-of-type / :first-of-type / :last-of-type只在同类兄弟中排名,先过滤标签类型,再数第几个
<!-- 经典面试题场景 -->
<ul>
  <h3>标题</h3>
  <li>第一项</li>
  <li>第二项</li>
  <li>第三项</li>
  <p>说明文字</p>
  <li>第四项</li>
</ul>
li:first-child       { }   /* 没选中,因为第一个孩子是 h3 */
li:first-of-type     { }   /* 选中 → 第一个 li(“第一项”) */

li:nth-child(3)      { }   /* 选中 → 第3个孩子是 li(“第三项”) */
li:nth-of-type(3)    { }   /* 选中 → 第三个 li(“第四项”) */

三、:nth-child / :nth-of-type 公式速查(敲代码必备)

写法选中元素序号(从 1 开始)口诀 / 常见用途
:nth-child(5)正好第 5 个固定第几个
:nth-child(odd)1,3,5,7…奇数行 / 斑马纹
:nth-child(even)2,4,6,8…偶数行
:nth-child(3n)3,6,9,12…每3个一组
:nth-child(3n+1)1,4,7,10…1、4、7…(常用于三分栏第一列)
:nth-child(-n+3)1,2,3前 3 个
:nth-child(n+4)4,5,6…从第 4 个开始
:nth-child(4n+2)2,6,10,14…2、6、10…(常用于卡片布局)

-n+ 写法很强大:-n+5 = 前 5 个

四、实战代码示例(建议全部运行一遍)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>结构伪类演示</title>
  <style>
    body { font-family: system-ui, sans-serif; max-width: 900px; margin: 2rem auto; }
    section { margin: 3rem 0; padding: 1.5rem; border: 1px dashed #aaa; border-radius: 8px; }

    /* 经典隔行变色 */
    .zebra li:nth-child(odd) {
      background: #f0f8ff;
    }
    .zebra li:nth-child(even) {
      background: #fffaf0;
    }

    /* 前3个加粗,最后一个红色 */
    .special li:nth-child(-n+3) {
      font-weight: bold;
    }
    .special li:last-child {
      color: #d32f2f;
      font-style: italic;
    }

    /* 只针对 p 标签的 of-type 用法 */
    article p:first-of-type {
      font-size: 1.3em;
      border-left: 5px solid #4caf50;
      padding-left: 1rem;
      margin-left: 0;
    }
    article p:nth-of-type(2n) {
      color: #555;
      font-style: italic;
    }

    /* 卡片布局:每行第1个左对齐,第3个右对齐 */
    .cards {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 1.5rem;
    }
    .cards > div:nth-child(3n+1) { justify-self: start; }
    .cards > div:nth-child(3n+2) { justify-self: center; }
    .cards > div:nth-child(3n)   { justify-self: end; }

    /* only-child 场景:只有一个孩子时放大 */
    .single > :only-child {
      font-size: 2em;
      color: #1976d2;
      text-align: center;
    }
  </style>
</head>
<body>

<section class="zebra">
  <h3>隔行变色(nth-child)</h3>
  <ul>
    <li>苹果</li><li>香蕉</li><li>橙子</li><li>梨</li><li>葡萄</li><li>西瓜</li>
  </ul>
</section>

<section class="special">
  <h3>前三 + 最后一个特殊</h3>
  <ul>
    <li>置顶公告1</li><li>置顶公告2</li><li>置顶公告3</li>
    <li>普通消息A</li><li>普通消息B</li><li>普通消息C</li><li>重要结尾!</li>
  </ul>
</section>

<section>
  <h3>文章首段突出(first-of-type)</h3>
  <article>
    <h2>标题</h2>
    <p>这是第一段,会被放大和加绿线。</p>
    <p>第二段斜体灰色。</p>
    <p>第三段正常。</p>
    <p>第四段又斜体灰色。</p>
  </article>
</section>

<section class="cards">
  <h3>3列卡片布局对齐(nth-child 3n系列)</h3>
  <div style="background:#e3f2fd;padding:1rem;">卡1</div>
  <div style="background:#e8f5e9;padding:1rem;">卡2</div>
  <div style="background:#fff3e0;padding:1rem;">卡3</div>
  <div style="background:#f3e5f5;padding:1rem;">卡4</div>
  <div style="background:#e0f7fa;padding:1rem;">卡5</div>
  <div style="background:#f1f8e9;padding:1rem;">卡6</div>
</section>

<section class="single">
  <h3>只有一个孩子时特殊样式(only-child)</h3>
  <div>只有我一个 → 会变大变蓝</div>
</section>

<section class="single">
  <h3>有多个孩子 → 普通</h3>
  <div>普通A</div>
  <div>普通B</div>
</section>

</body>
</html>

五、高频面试/实战总结

  1. 表格/列表隔行变色:nth-child(odd/even) 最常用
  2. 去掉首/尾边距:first-child / :last-child 去 margin/padding
  3. 响应式网格最后一行对齐 → :nth-child(3n) / 4n
  4. 文章排版首段/首图特殊 → :first-of-type
  5. 面包屑 / 步骤条最后一个不同 → :last-child / :last-of-type
  6. 避免“幽灵元素”干扰 → 用 -of-type 更稳(当 HTML 结构可能插入其他标签时)

六、小坑 & 提示

  • :nth-child(n) 的 n 从 1 开始(不是 0)
  • 这些伪类不考虑 display:none 的元素(仍然按 DOM 顺序计数)
  • 特异性都是 0,1,0,和 class 相同,容易被更高特异性覆盖
  • 不要滥用复杂公式,代码可读性第一

下一期预告:伪类(下)—— 交互 & 状态伪类(:hover / :focus / :active / :checked / :disabled / :required …)

有特别想看的场景或公式欢迎留言~
祝大家结构伪类用得丝滑!🎨

文章已创建 5186

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部