块级标签不能直接嵌套在里,因只允许短语级内容;浏览器会静默修正为先闭合再将块级元素置外;display属性可改变视觉表现但不改变html内容模型约束。

块级标签为什么不能直接嵌套在 <p></p> 里
HTML 解析器会静默修正这种结构错误,而不是报错或警告。<p></p> 的内容模型是 phrasing content(短语级内容),只允许文本、<em></em>、<strong></strong>、<a></a>、<img> 等行内元素。一旦你写 <p></p>
<div>xxx</div>
<p></p>,再把 <div> 插到外面——DOM 结构和你写的完全不一致。
<p>常见错误现象:</p>
<ul>
<li>预期段落内有个容器,结果容器跑到了段落下一行</li>
<li>
<code><h2></h2> 放进 <p></p> 后,标题样式失效、语义丢失
<span></span> 包裹大段内容再设 display: block,看似“绕过限制”,但实际仍违反规范,可能影响可访问性与 SEO
<img> 和 <input> 明明是行内标签,为什么能设 width 和 height
因为它们属于 replaced element(可替换元素):渲染时由外部资源(如图片文件、表单控件引擎)决定内容,浏览器为其预留盒空间,并允许 CSS 控制尺寸。这不是“行内元素能设宽高”的例外,而是特例规则。
关键区别:
-
<span></span>是纯行内元素,设width: 100px完全无效 -
<img>设width会缩放图像本身,不是撑开一个空盒子 -
<input type="text">的宽高控制的是控件 UI 尺寸,不是文本行高 - 把
<img>设为display: block后,margin: auto居中才生效;但它的行内盒本质没变,vertical-align依然起作用(比如和文字混排时)
vertical-align 只对三类元素有效
这个属性常被误用:给 <div> 或 <code><p></p> 加 vertical-align: middle 永远无效。它只作用于:
- 行内盒(
<span></span>、<em></em>、<img>等默认 display 为 inline 的元素) - 表格单元格(
<td>、<code><th>) <li> <code>display: inline-block元素(如<button></button>、显式设了 inline-block 的<div>) <p>典型使用场景:</p> <ul> <li>图标 <code><img>与文字垂直居中:给图标加vertical-align: middle - 多个
<input>和<label></label>对齐:统一设vertical-align: baseline或middle - 避免
inline-block元素间的空白缝隙干扰对齐:改用vertical-align: top+ 字体大小归零等方案
用 display 改变布局行为,但改不了 HTML 内容模型约束
把 <span></span> 设成 display: block,它就能换行、设高宽、接受上下 margin——但依然不能作为 <h1></h1> 的子元素,因为 <h1></h1> 的内容模型只接受 phrasing content,而 <span></span> 即使视觉上像块,语义上仍是行内元素。
容易踩的坑:
- 以为
display: block能让<a></a>套整个卡片就“合法”了——其实<a></a>里放<div> 在 HTML5 中已允许,但放 <code><h1></h1>仍不行(除非用<hgroup></hgroup>或语义重构) - 用
<div> 做按钮并设 <code>display: inline,虽然视觉并排,但它仍能包含<p></p>,而真实按钮(<button></button>)是行内块,内容模型更严格 - 依赖 CSS 改变 display 来“修复”嵌套错误,却忽略 screen reader 和搜索引擎仍按原始 HTML 结构解析
真正决定能否嵌套的,是每个标签在 HTML 规范里的 content model,不是你后来加的 CSS。











