准确定位外链需用[href^="https://"]:not([href^="https://example.com"]):not([href^="https://www.example.com"])排除内链,补充//协议相对链接,并为::after设置content、display:inline-block及aria-label确保可访问性。

用[href^="https://"]:not()排除内链才能准确定位外链
只靠协议前缀匹配会把 https://yourdomain.com 这类内部链接也标成外链,必须配合 :not() 排除。常见失效场景包括:a[href^="https://"] 单独使用、漏掉 www. 变体、忽略协议相对链接 [href^="//"]。
实操建议:
- 先写排除规则:
a[href^="https://example.com"]:not([href*="?"]):not([href*="#"])::after { content: ""; }(重置图标) - 再写通用规则:
a[href^="https://"]:not([href^="https://example.com"]):not([href^="https://www.example.com"])::after - 补充协议相对链接:
a[href^="//"]:not([href*="example.com"])::after -
href值里不能有中文引号或不可见字符,否则整条规则静默失效
::after 必须设 content 非空且搭配 display: inline-block
::after 默认创建的是空盒子,content: "" 不会渲染任何东西。图标不显示,90% 是因为没填内容或没设显示模式。
最小可行组合:
立即学习“前端免费学习笔记(深入)”;
- 用 Unicode:
content: "\2197"; display: inline-block; vertical-align: middle; margin-left: 4px; - 用字体图标:
content: "\f1c1"; font-family: "Font Awesome 6 Free"; font-weight: 900;(注意引号和空格) - 用 SVG 背景图:
content: ""; display: inline-block; width: 1em; height: 1em; background: url("data:image/svg+xml,%3Csvg%3E...%3C/svg%3E") no-repeat center / contain; - 别漏
margin-left:它控制图标与文字间距,padding-right会缩小可点击区域
为什么不能用 [href^="http"] 或 [href*="://"]
看似省事,实则误判严重:[href^="http"] 会命中 http://localhost:3000 和 http://192.168.1.100 这类开发地址;[href*="://"] 则可能匹配到 mailto:hello@example.com 中的 :// 子串,导致邮件链接也被打标。
更稳妥的做法是分协议显式声明:
-
a[href^="mailto:"]::after→ 用 ✉️ -
a[href^="tel:"]::after→ 用 ☎️ -
a[href^="ftp:"]::after→ 用 ? - 每条都加
:not([href*="yourdomain.com"])排除内网/CDN 域名
图标必须配 aria-label,否则对屏幕阅读器不可见
::after 的 content 默认不被屏幕阅读器读取。仅靠 ↗ 图标传达“将离开本站”,对视障用户是信息黑洞。
正确做法不是靠 CSS 补语义,而是 HTML 层面加属性:
- 手动在链接上加
aria-label="在新窗口打开外部链接" - 或用构建工具/编辑器自动注入:
<a href="https://other.site" target="_blank" rel="noopener" aria-label="外部链接">官网</a> - 千万别依赖
title属性替代aria-label:它只在悬停时触发,且部分读屏软件不读 - 如果用 SVG 背景图,记得加
aria-hidden="true",避免重复播报
href 字符串值。如果 JS 动态改过链接、服务端做了 URL 重写、或原始 HTML 里 href 值前后带空格(如 href=" https://example.com "),[href^="https://"] 就会完全失效——这种情况下,:not() 也救不了。


















