[href^="https://"]仅按协议匹配会误标内部HTTPS链接为外链,必须用:not()排除本站域名(含www与子域名);::after图标方案优于background-image,因支持基线对齐、缩放和无障碍;非HTTP协议链接需单独声明并同样排除站内地址。

为什么[href^="https://"]会把内部链接也标成外链
只靠协议前缀匹配,[href^="https://"] 会把 https://example.com/about 这类内部 HTTPS 链接也当成外链——图标一加,用户点进去却没跳站,体验直接打折。
必须配合 :not() 排除本站域名。如果主站是 example.com,得写两行:
-
a[href^="https://example.com"]:not([href^="https://www.example.com"]):not([href^="https://example.com/"]) { content: ""; }(先清空) -
a[href^="https://"]:not([href^="https://example.com"]):not([href^="https://www.example.com"])::after { content: "↗"; }(再加图标)
别漏掉 www 和非 www 两种形式;如果还有子域名(如 blog.example.com),也要单独排除。
用 ::after 而不是 background-image 的真实原因
background-image 看似省事,但图标尺寸难控、高 DPI 下模糊、无法随文字缩放,更关键的是:它不参与行内布局,vertical-align 失效,图标常“飘”在文字上方或下沉。
立即学习“前端免费学习笔记(深入)”;
::after 是唯一能和文字基线对齐、响应 font-size、支持无障碍读取的方案。实操必须配齐这三样:
-
display: inline-block(让vertical-align生效) -
vertical-align: middle(不是top或transform) -
content: "↗"(或 Unicode 如"\2197",不能留空)
顺带一提:margin-left: 4px 比 padding-right 更安全——后者会缩小可点击区域。
怎么处理 ftp://、tel:、mailto: 这类非 HTTP 外链
[href^="http"] 看似简洁,但它漏掉 ftp://、tel:、mailto:,而这三类链接同样触发“出站行为”。更糟的是,[href^="http"] 还会误标 http://localhost:3000 这类开发地址。
稳妥做法是分协议显式声明:
-
a[href^="mailto:"]::after→content: "✉" -
a[href^="tel:"]::after→content: "?" -
a[href^="ftp:"]::after→content: "?" -
a[href^="//"]::after→ 单独处理协议相对 URL(常见于 CDN 资源)
所有规则都要加 :not() 排除本站,否则 mailto:support@example.com 也会被标成外链。
图标纯装饰,但屏幕阅读器看不见
::before 和 ::after 插入的内容不在 DOM 中,document.querySelector 找不到,屏幕阅读器也完全感知不到。如果链接语义关键(比如“联系我们(邮箱)”),仅靠 ✉ 图标传达信息,等于对视障用户关闭了通道。
必须用 aria-label 显式说明:
<a href="mailto:hello@example.com" aria-label="发送邮件至 hello@example.com">联系我们</a>
别依赖 CSS 做语义表达——这是最常被忽略、也最难事后补救的一环。


















