html嵌套必须遵循父元素的内容模型:仅允许phrasing content(如),禁止等块级元素;不能破坏父级约束;内不可嵌块级标签;语义错误嵌套虽可能渲染,但损害可访问性与js/css可靠性。

格式化标签(如 <strong></strong>、<em></em>、<span></span>、<code>)本身不决定块/行级行为,但它们的嵌套必须服从父容器的内容模型——不是“能不能写进去”,而是“父标签允不允许你放这个”。
为什么 <p></p> 里不能套 <div>,但能套 <code><strong></strong>
<p></p> 只接受 phrasing content(短语级内容),W3C 明确列出允许子元素:文本、<em></em>、<strong></strong>、<span></span>、<img>、<a></a> 等,但明确排除 <div>、<code><ul></ul>、<h2></h2> 等块级或结构型标签。
浏览器解析到 <p></p>
<div>xxx</div>
<div> 开始前就自动闭合 <code><p></p>,结果 DOM 变成:<p></p>
<div>xxx</div>。
- CSS 中
p > div永远不匹配 -
document.querySelector('p').children返回空 NodeList -
<strong></strong>在<p></p>内完全合法,且可多层嵌套:<p>这是一段<em>强调中再<strong>加粗</strong></em>的文字</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher"><img src="https://img.php.cn/upload/skill/000/000/081/179109368394970.jpg" alt="Wechat HTML Publisher" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="overflowclass">Wechat HTML Publisher</a> <p class="overflowclass">直接上传HTML富文本到微信公众号草稿箱。支持完整的HTML格式,无需Markdown转换。</p> </div> <a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>
<span></span> 看似自由,其实有隐性限制
<span></span> 是通用行内容容器,但它本身不改变语义,也不豁免父级约束。它不能出现在禁止行内容的地方。
- ❌ 错误:
<ul><span><li>项1</li></span></ul>——<ul></ul>只允许直接子元素为<li>,<span></span>插入后会被浏览器移出,变成<ul></ul> <span><li>项1</li></span> - ✅ 正确:
<ul><li><span class="highlight">项1</span></li></ul> - ⚠️ 注意:
<span></span>不能替代语义标签。比如用<span><strong>标题</strong></span>包裹标题文字,不如直接用<h3></h3>;无障碍阅读器不会把它当标题识别
<code> 和 <pre class="brush:php;toolbar:false;"></pre> 的嵌套边界在哪
<code> 表示一段计算机代码,属于行内容;<pre class="brush:php;toolbar:false;"></pre> 是预格式化块容器,允许换行和空格保留。二者常配合使用,但嵌套顺序不能颠倒:
- ✅ 推荐:
<pre class="brush:php;toolbar:false;"><code>console.log('hello');</code></pre>—— 语义清晰,<pre class="brush:php;toolbar:false;"></pre>处理空白,<code>标注类型 - ❌ 错误:
<code><pre class="brush:php;toolbar:false;">...</pre>——<code>不接受块级子元素,<pre class="brush:php;toolbar:false;"></pre>会被踢出,DOM 结构断裂 - ⚠️ 注意:
<code>内部不能再嵌<div> 或 <code><p></p>;若需高亮某部分词,用<span></span>(如<code>for <span class="keyword">let</span> i = 0;)容易被忽略的“合法但有害”嵌套
有些嵌套 W3C 不报错,但会破坏可访问性或 SSR hydration:
-
<a></a>内嵌<button></button>或另一个<a></a>—— 浏览器可能渲染,但屏幕阅读器会混乱,且违反交互语义 -
<h1></h1>里套<div> —— 虽然部分浏览器容错通过,但 SEO 和无障碍工具会降权该标题 <li>在 <code><table> 的 <code><td> 里用 <code><p></p>包文字 —— 合法,但多余;<td> 默认支持流式内容,加 <code><p></p>反而增加样式干扰点真正关键的不是“浏览器有没有报错”,而是“DOM 是否按你写的建”“CSS 选择器是否还有效”“JS 查询是否还能拿到预期节点”——这些都得靠开发者工具的 Elements 面板逐层验证,不能只看页面“看起来对”。
-










