<p>
里可以写 <div>
吗? 你可能真的不知道
在学习 CSS
计数器 counters()
函数时, 我尝试使用 <div>
和 <p>
互相嵌套组成 HTML
结构. 如下
<p>
<div>1</div>
<div>2</div>
</p>
页面显示元素都正常, 但是计数器就是不正常😡, 于是我检查元素发现整个页面的 HTML
结构被浏览器悄悄地改了.
<p></p>
<div>1</div>
<div>2</div>
<p></p>
浏览器为什么要这么做呢?🤨
content model
HTML
规范中的每一个元素都有一个内容模型: 用来描述该元素期望的内容, 就是期望什么类型的
DOM 作这个元素的子节点
. 规范中明确了 HTML
元素的内容必须匹配这个元素的 content model
.
-
<p>
的content model
是 phrasing content- 如果我们看看下图, 就大概知道
phrasing content
很多都是常说的inline
内联元素.
- 如果我们看看下图, 就大概知道
-
<div>
的content model
是 flow content
因此, <p>
不能包含 <div>
(反过来可以), 不仅仅是 <div>
, 任何非 phrasing content
的元素都不行, 包括 <h1>
, <ul>
等, 甚至包含自身, 因为 <p>
自身类型(Categories
)属于 Flow content
.
Categories
😱怎么又出现了 Categories
啊? 规范中说的很清楚, <p>
希望 phrasing content
类型的元素作为子节点, 那么哪些元素是 phrasing content
呢? 这就是 Categories
要回答的问题了.
就简单理解下面看一下 HTML
规范中对元素所属的 Categories
的划分. 下图很有意思, 几乎所有的元素都是 Flow Content
,
还没有真正回答开头的问题, 能写吗?
是可以的, 只不过是通过 js
, 不过不推荐啦~
<p id="secondP"></p>
let secondP = document.getElementById('secondP');
let newDiv = document.createElement('div');
newDiv.innerHTML = 'Oops';
secondP.append(newDiv);
参考
- Why can’t the
<p>
tag contain a<div>
tag inside it? - https://html.spec.whatwg.org/multipage/dom.html#flow-content
- https://html.spec.whatwg.org/multipage/dom.html#contexts-in-which-this-element-can-be-used
- https://clearlydecoded.com/html-content-models
- https://html.spec.whatwg.org/multipage/dom.html#concept-element-categories