HTML 规范不允许 <a> 元素内包含另一个 <a> 元素。浏览器会自动修正,将内层 <a> 移到外层 <a> 之后,导致布局结构被破坏。
规范
HTML spec 明确规定:<a> 的内容模型(content model)是 transparent,但其中不能包含 interactive content,而 <a> 本身是 interactive content。
浏览器行为
<!-- 写入的 HTML -->
<a href="/card/">
<div>标题</div>
<ul>
<li><a href="/tags/ai/">#AI</a></li> <!-- 嵌套 <a> -->
</ul>
</a>
<!-- 浏览器解析后实际结构 -->
<a href="/card/">
<div>标题</div>
<ul><li></li></ul>
</a>
<a href="/tags/ai/">#AI</a> <!-- 被移到外层 <a> 之后 -->
内层 <a> 被移出后,原来包含它的 <ul>/<li> 变成空节点留在原处,标签本身被推到卡片外,脱离 flex 布局,视觉上出现在卡片下方。
常见场景
将整个卡片用 <a> 包裹(实现整体可点击),同时在卡片内放 tag 链接:
<!-- ❌ 错误:tags 的 <a> 嵌套在卡片 <a> 内 -->
<a href="/card/" class="flex items-center gap-3">
<div>
<span>标题</span>
{tags.map(tag => <a href={`/tags/${tag}/`}>#{tag}</a>)}
</div>
</a>
<!-- ✅ 正确:tags 移到卡片 <a> 外,仍在 <li> 内 -->
<a href="/card/" class="flex items-center gap-3">
<div><span>标题</span></div>
</a>
{tags.length > 0 && (
<ul>{tags.map(tag => <li><a href={`/tags/${tag}/`}>#{tag}</a></li>)}</ul>
)}
参考
- HAT-217 YoYoCard 加入 tag 链接后布局错乱,排查发现嵌套
<a>问题 - https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element