如何仅用CSS检测两个直接相邻的链接?
TL;DR: 简而言之:如何为彼此相邻且中间无其他内容的链接(或任何HTML元素)设置样式?
有时链接会被放置在一起,但指向不同的位置(← 就像这样),如果网站仅通过颜色区分链接,会造成识别困难。这是一种相当常见的做法,维基百科的超链接相关文章中就采用了这种形式:

当然,永久或hover时为链接添加下划线的良好实践足以区分被空格分隔的情况,但确实存在链接直接相邻的情况,就像这样。这种情况不太常见,但在实际场景中会遇到。
我尝试定义用户样式表来让这些链接易于识别,想到使用相邻兄弟选择器来实现,例如:
a+a { border-left: 1px solid red; }
这确实可以检测像 <a href="1"/><a href="2"/>(为简洁使用自闭合语法)这样的“粘合”链接,以及像 <a href="1"/> <a href="2"/> 这样的空格分隔链接。但它也会捕获中间有文本的链接,比如 <a href="1"/> foobar <a href="2"/>:
<ul> <li><a href="1">one</a><a href="2">two</a></li> <li><a href="1">one</a> <a href="2">two</a></li> <li><a href="1">one</a> foobar <a href="2">two</a></li> </ul>
a+a { border-left: 1px solid red; }
搜索相关内容后发现,似乎无法区分前两种情况和第三种情况——也就是仅在中间无文本内容时为相邻链接设置样式。是否有遗漏的技巧可以实现这种功能?
目前纯CSS无法直接区分“仅含空白符的相邻链接”和“中间有非空白文本的相邻链接”,因为CSS的相邻兄弟选择器(+)只会判断元素的位置关系,不会检查它们之间的文本内容。不过可以通过两种思路来近似实现需求:
1. 利用:has()选择器间接区分(现代浏览器支持)
通过:has()选择器检测父元素中是否存在“链接+非空白文本+链接”的结构,以此排除不符合要求的情况:
/* 先给所有相邻链接左侧加边框和内边距 */ a+a { border-left: 1px solid red; padding-left: 4px; } /* 排除中间有非空白内容的相邻链接 */ li:has(a + :not(br):not(hr):not(span:empty) + a) a+a { border-left: none; padding-left: 0; }
:has()选择器能识别父元素内的元素组合结构,从而精准排除中间有实际文本内容的相邻链接,但需要浏览器版本支持(Chrome 105+、Firefox 121+已支持)。
2. 用JavaScript精准处理(兼容所有浏览器)
通过JS检测链接之间的文本内容是否仅为空白符,再给符合条件的链接添加样式类:
const links = document.querySelectorAll('a'); links.forEach((currentLink, index) => { if (index === 0) return; const prevLink = links[index - 1]; // 检查两个链接之间的文本节点是否仅含空白 let siblingNode = prevLink.nextSibling; let isOnlyWhitespace = true; while (siblingNode && siblingNode !== currentLink) { if (siblingNode.nodeType === Node.TEXT_NODE && siblingNode.textContent.trim() !== '') { isOnlyWhitespace = false; break; } siblingNode = siblingNode.nextSibling; } if (isOnlyWhitespace) { currentLink.classList.add('adjacent-link'); } });
再定义对应的CSS样式:
.adjacent-link { border-left: 1px solid red; padding-left: 4px; }
这种方法能精准识别所有仅含空白内容的相邻链接,兼容性覆盖所有浏览器。
补充说明
纯CSS之所以无法直接实现,是因为CSS选择器仅关注元素的层级、位置和属性,无法访问文本节点的内容。如果不需要兼容旧浏览器,:has()方案是最接近纯CSS的解决方式;如果需要全兼容,JavaScript方案更可靠。
内容的提问来源于stack exchange,提问作者waldyrious

