一、简介
之前对元素之间的嵌套规则没有进行系统的梳理,一直以为各种元素之间可以随意进行嵌套,但在实际敲代码的过程中发现并不是这样,大部分标签之间是可以随意嵌套的,但也存在一些特殊规则,比如:p标签内不能再嵌套p标签和div标签等块级标签。
这篇博客就是为了彻底搞清楚不同类型元素之间的嵌套规则。
常见块级元素
<div>
、<p>
、<h1> ~ <h6>
、<ul>
、<li>
、<table>
、<form>
、<section>
、<header>
等。
MDN块级元素列表
常见行内元素
<span>
、<strong>
、<i>
、<a>
、<button>
、<em>
等。
MDN行内元素列表
补充:在MDN中将行内块元素归属在行内元素里面了。
常见行内块元素
<img>
、<input>
、<textarea>
、<button>
、<audio>
、<video>
等。
二、具体规则
1、块级元素嵌套规则
① 特殊的<p>
、<h1> ~ <h6>
、<dt>
块级元素
这几个元素具有特殊规则:这些标签内部不能嵌套任何块级元素,只能嵌套行内元素或行内块元素,就算我们给块级元素设置display: inline
,也是不行的。
如果我们在这些特殊元素内嵌套了块级元素,那么浏览器会将元素的前后两个标签解析成两对标签。那此时我们给该元素设置的样式就无法作用到嵌套的元素身上。
以<p>
为例:
<p>p标签内包裹文本</p><p>p标签内包裹行内元素 <strong>strong</strong></p><p>p标签内包裹行内元素 <span>span</span></p><p>p标签内包裹行内块元素img <img src="./image/img.png" alt="" style="width: 60px;height: 60px"></p><p>p标签内包裹行内块元素audio<audio src="./image/起风了.mp3" style="width: 300px;height: 60px" controls="controls"></audio></p><p><div>p标签内包裹块级元素div</div></p><p><div>p标签内包裹块级元素div(并设置display: inline;)</div></p><p><p>p标签内包裹块级元素p</p></p>
浏览器解析结果:
② 其他块级元素
除了前面几个特殊元素,其他块级元素内部可以嵌套任何元素。
以div
为例:
<div>div标签内包裹文本</div><div>div标签内包裹行内元素 <strong>strong</strong></div><div>div标签内包裹行内元素 <span>span</span></div><div>div标签内包裹行内块元素img <img src="./image/img.png" alt="" style="width: 60px;height: 60px"></div><div>div标签内包裹行内块元素audio<audio src="./image/起风了-买辣椒也用券.mp3" style="width: 300px;height: 60px" controls="controls"></audio></div><div><div>div标签内包裹块级元素div</div></div><div><div style="display:inline">div标签内包裹块级元素div(并设置display: inline;)</div></div><div><p>div标签内包裹块级元素p</p></div>
浏览器解析结果:
2、行内元素嵌套规则
按照MDN来看,行内元素只能包含数据和其他行内元素、行内块元素。但经过实验,发现行内元素内也可以嵌套块级元素,但在给内部的块级元素设置宽高时,无法影响到父级行内元素的宽高,且父级行内元素也会受到块级元素的影响,出现独占一行的情况。
以<span>
为例:
<span>span标签内包裹文本</span><span>span标签内包裹行内元素 <strong style="width: 100px;height: 50px">strong</strong></span><span>span标签内包裹行内元素 <i>i</i></span><span>span标签内包裹行内块元素img <img src="./image/img.png" alt="" style="width: 60px;height: 60px"></span><span>span标签内包裹行内块元素audio<audio src="./image/起风了-买辣椒也用券.mp3" style="width: 300px;height: 60px" controls="controls"></audio></span><span><div style="width: 250px;height: 50px">span标签内包裹块级元素div</div></span><span>一个普通的sapn</span><span><span style="display: block">span标签内包裹行内元素span(并设置display: block;)</span></span><span><p>span标签内包裹块级元素p</p></span>
浏览器解析结果:
页面展示效果:
补充:
如果我们在行内元素内嵌套了块级元素,那么这个行内元素通过offsetHeight
获取的实际高度,是内嵌的块级元素的高度 + 上一行元素中高度最高那个元素的高度 + 下一行元素中高度最高那个元素的高度的和,但这个高度并不会影响页面展示效果,占据的空间还是按照内嵌元素的高度来。
<span id="1">测试用的span</span><a href="#" id="2"><div id="3" style="width: 300px;height: 80px;">这是a标签内嵌套了div标签</div></a><span id="4">测试用的span2</span></body><script>(function() {let a = document.getElementById('1')let b = document.getElementById('2')let c = document.getElementById('3')let d = document.getElementById('4')console.log(a.offsetHeight); // 实际22.5 但offset向上取整 变为23console.log(b.offsetHeight); // 22.5 + 22.5 + 80 = 125console.log(c.offsetHeight);// 80console.log(d.offsetHeight);// 实际22.5 但offset向上取整 变为23console.log(a.offsetHeight + c.offsetHeight + d.offsetHeight === b.offsetHeight);})()</script>
页面效果:
上一行的高度:
当前元素的高度:
下一行的高度
执行结果:
这里之所不相等是因为,span的高度是22.5,但是但offset取值时,向上取整 变为了23。
3、行内块元素嵌套规则
行内块元素大部分都是单标签,内部不会嵌套其他元素,但也有像<button>
这样的双标签,再其内部即可以嵌套行内元素也可以嵌套块级元素,如果是内嵌块级元素,则父级行内块元素的宽高会跟随内嵌块级元素的宽高变化,但不会独占一行。如果是内嵌行内元素,则没什么变化。
以<button>
为例:
<button>button标签内包裹普通文本</button><button><span>button标签内包裹行内元素span</span></button><button><span style="display: block;width: 400px;height: 50px;">button标签内包裹行内元素span(并设置display: block;)</span></button><button><div style="width: 300px;height:100px">button标签内包裹块级元素div</div></button>
浏览器解析结果:
页面展示效果: