:not([href]) 选中的是未声明 href 属性的 <a> 元素,而非语义上的“占位链接”;真正占位链接(如 href="#"、href="javascript:void(0)")均含 href 属性,故无法被 :not([href]) 匹配。
![如何通过css :not([href])选择所有不可点击的占位链接?](https://img.php.cn/upload/article/000/969/633/178424519867298.jpeg)
:not([href]) 不能用来选中“不可点击的占位链接”,它选中的其实是**根本没写 href 属性的 <a> 元素**——这类元素在语义和行为上本就不该是链接,不是“占位链接”,而是无效或待补全的标记。
为什么 :not([href]) 不等于“占位链接”
浏览器对“可点击链接”的判定依据是:是否具有有效 href 值(哪怕值为空字符串或 #)。只要写了 href 属性,无论内容是什么,<a> 就会被当作链接处理(有手型光标、可聚焦、能触发点击事件)。
-
<a>Hello</a>—— 没href,:not([href])能匹配,但它不是链接,只是普通内联容器,无法点击 -
<a href="">Hello</a>—— 有href,:not([href])完全不匹配,但它实际可点击(会跳到页面顶部) -
<a href="#">Hello</a>—— 同样有href,:not([href])不匹配,但它是典型占位链接 -
<a href="javascript:void(0)">Hello</a>—— 有href,:not([href])不匹配,也是常见占位写法
真正想筛“占位链接”,得靠属性值判断
所谓“占位链接”,通常指写了 href 但无真实跳转意图的链接,常见值包括 #、javascript:void(0)、空字符串 ""、或仅含空格。CSS 层面只能基于字符串前缀/包含关系做粗筛:
- 排除空
href:a[href=""] - 排除
#开头:a[href^="#"] - 排除
javascript:开头:a[href^="javascript:"] - 排除仅空格(需配合 JS 清洗后才可靠,CSS 无法 trim)
- 组合使用:
a[href]:not([href^="http"]):not([href^="/"]):not([href^="mailto"]):not([href^="tel"])—— 筛出有href但又不像真实外链/路径/协议链接的元素
用 :not() 时最容易踩的坑
:not() 只作用于当前选择器命中的元素本身,不会穿透后代,也不改变匹配逻辑层级:
立即学习“前端免费学习笔记(深入)”;
- 写
nav a:not([href])只会选中nav下那些**没写href的<a>**,不是“所有导航里可点击链接之外的其他东西” -
:not([href])和:not([href=""])完全不同:前者排除所有带href属性的<a>,后者只排除href值恰好为空字符串的 - IE 11 及更早版本不支持
:not(),如果需要兼容,得用显式类名(如.placeholder-link)替代 - 别试图用
*:not([href])—— 通配符加伪类在多数浏览器中被忽略或报错
真要统一控制占位链接样式,最稳妥的方式还是主动加类:<a href="#" class="placeholder">,再写 a.placeholder。CSS 的 :not() 是筛选工具,不是语义识别器——它看不到“意图”,只认属性是否存在、值是否匹配字符串模式。


















