【H5 前端开发笔记】第 21 期:CSS 选择器 (6) 兄弟选择器、否定伪类选择器、选择器性能 详解

【H5 前端开发笔记】第 21 期:CSS 选择器 (6) —— 兄弟选择器、否定伪类、选择器性能 详解

这一期把关系型选择器的最后一块拼图补上:兄弟关系,再加上非常实用的否定伪类 :not(),最后聊聊选择器性能的真实情况(2026 年视角)。

一、兄弟选择器(Sibling Combinators)核心对比

符号名称写法示例匹配规则方向典型场景特异性影响
+相邻兄弟选择器h2 + p紧挨着前面的 h2 的第一个 p 兄弟向后标题后第一段去掉上边距无额外
~通用兄弟选择器h2 ~ ph2 后面所有 p 兄弟(不限紧邻)向后标题后所有段落统一缩进/样式无额外
(没有前兄弟选择器)CSS 目前无法选择前面的兄弟

关键一句话:CSS 只能“向后看兄弟”,不能“向前看”。

二、否定伪类 :not()

:not()逻辑否定,括号里写一个或多个选择器列表(CSS Selectors Level 4 后支持多参数,现代浏览器已全部支持)。

/* 旧写法(仍有效,但权重较高) */
li:not(.active):not(.disabled) { opacity: 0.6; }

/* 新写法(2022年后主流浏览器支持,权重更合理) */
li:not(.active, .disabled) { opacity: 0.6; }

/* 常见组合 */
button:not(:disabled) { cursor: pointer; }
a:not([href^="http"]) { color: inherit; }   /* 非外部链接 */
div:not(:empty) { min-height: 1em; }        /* 非空 div */
p:not(:first-child) { margin-top: 1.5em; }  /* 排除第一个段落的上边距 */

权重(Specificity)重要变化(面试常考):

  • :not() 本身不增加特异性
  • 但括号里的选择器会正常计入特异性
  • 多参数列表时,取最高那个选择器的权重(而非累加)
/* 权重都是 0,0,1 */
a:not(.external)          /* a (0,0,1) */
a:not(.external, .internal)   /* 仍然 0,0,1(取最高) */

/* 旧写法权重更高 */
a:not(.external):not(.internal)   /* 0,0,2 */

三、实战代码示例(建议敲一遍)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>兄弟 + :not 演示</title>
  <style>
    body { font-family: system-ui; max-width: 800px; margin: 3rem auto; line-height: 1.6; }

    /* 1. 标题后紧邻的第一段 → 去掉上边距 */
    h2 + p {
      margin-top: 0;
      font-size: 1.1em;
    }

    /* 2. 标题后面所有段落 → 加左边框 + 缩进 */
    h2 ~ p {
      padding-left: 1.2rem;
      border-left: 4px solid #4caf50;
      margin: 1em 0;
    }

    /* 3. 排除第一个段落的上边距(两种常见写法) */
    section p:not(:first-child) {
      margin-top: 1.5em;
    }

    /* 4. 导航:非当前项变淡 */
    nav a:not(.current) {
      opacity: 0.6;
      font-weight: normal;
    }
    nav a.current {
      color: #d32f2f;
      font-weight: bold;
    }

    /* 5. 列表:非空项 + 不是最后一个加下边框 */
    .features li:not(:empty):not(:last-child) {
      border-bottom: 1px dashed #ccc;
      padding-bottom: 0.8em;
      margin-bottom: 0.8em;
    }

    /* 6. 文章中:图片后面紧跟的说明文字特殊样式 */
    figure + figcaption {
      font-style: italic;
      color: #555;
      text-align: center;
      font-size: 0.95em;
      margin-top: 0.4em;
    }

    /* 7. 排除外部链接的小图标 */
    a[href]:not([href^="http"]):not([href^="https"]):not([href^="/"])::after {
      content: " ↗";
      color: #888;
      font-size: 0.8em;
    }
  </style>
</head>
<body>

<h1>CSS 兄弟 & :not 实战</h1>

<section>
  <h2>这是标题</h2>
  <p>紧挨着标题的第一段(+ 选择器生效,去掉上边距)</p>
  <p>这是第二段(~ 选择器生效,有绿色左边框)</p>
  <p>第三段同样有左边框</p>
</section>

<section>
  <h2>另一个标题</h2>
  <p>段落1(有上边距,因为不是 section 第一个 p)</p>
  <p>段落2</p>
</section>

<nav>
  <a href="#home" class="current">首页</a> |
  <a href="#about">关于</a> |
  <a href="#contact">联系</a>
</nav>

<ul class="features">
  <li>特性一</li>
  <li></li> <!-- 空 li 不显示下边框 -->
  <li>特性三</li>
  <li>特性四(最后一个,无下边框)</li>
</ul>

<figure>
  <img src="https://picsum.photos/600/300?random=1" alt="示例图" width="600">
  <figcaption>这是一张随机图片的说明文字(figure + figcaption 生效)</figcaption>
</figure>

<p><a href="/internal">内部链接</a> 和 <a href="https://external.com">外部链接</a></p>

</body>
</html>

四、选择器性能(2025-2026 真实情况总结)

现代浏览器(Blink、WebKit、Gecko)对选择器性能的优化已经非常成熟,绝大多数场景下“选择器性能”已经不是瓶颈

排名(由快到慢,大致)选择器类型示例2026 年相对耗时建议
最快ID #header★★★★★首选(但不要滥用)
极快单 class .btn★★★★☆日常主力
很快标签 button、属性 [type="button"]★★★★常用
子选择器 nav > a、相邻 h2 + p★★★★推荐
稍慢后代选择器 article p★★★常用但别太深
更慢通用兄弟 h2 ~ p★★★适度使用
明显慢:nth-child(复杂公式):not(复杂)★★控制数量
最慢(避免深层)超深后代 + 通配 *尽量避免

2026 年共识要点

  1. 真正影响大的是“选择器数量” × “DOM 元素数量” × “重排/重绘频率”,而非单个选择器的微秒级差距。
  2. 避免从右往左想:写 .container .list .item 而不是 .item(但现代引擎已优化很多)。
  3. :not() 现在很安全:只要里面不是超级复杂选择器,性能影响已很小。
  4. 兄弟选择器 + / ~ 性能不错:远好于深层后代。
  5. 真正要优化的优先级顺序
  • 减少样式规则总量
  • 避免在动画/滚动时触发大量重计算的伪类
  • 用 class 而非复杂结构伪类做状态切换
  • 关键渲染路径(LCP)相关的元素尽量用 ID 或单 class

下一期预告:伪类(下)—— 交互 & 表单 & 链接状态(:hover / :focus-visible / :checked / :required / :valid / :link / :visited …)

有想深入的场景(比如 :not(:has()) 组合性能、面包屑用兄弟选择器等)欢迎留言~
祝大家 CSS 选择器写得又准又快!⚡

文章已创建 5186

发表回复

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

相关文章

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

返回顶部