讲解
HTML 元素按默认排版行为分为两大类。块级元素(block)独占一行,宽度默认撑满父容器,可以设置宽高和上下左右 margin:<p>、<h1>–<h6>、<div>、<ul>、<table>、<form>、<header> 等都是。行内元素(inline)只占据内容所需的宽度,多个行内元素在同一行内从左到右排布、放不下才折行:<a>、<span>、<strong>、<em>、<img>、<code> 等都是。
行为差异直接决定样式效果:给行内元素设置 width、height 不生效,上下 margin/padding 也不会推开相邻行(左右方向有效)——这就是为什么给 <span> 设宽高没反应。想让行内元素既能排在行内又能控制盒模型,用 CSS display: inline-block,导航菜单的横向按钮常用它。事实上块级/行内只是 CSS display 属性的默认值,任何元素都能通过 display: block、display: inline 改写行为——<a> 设成 block 就是整行可点的链接条。
结构上还有一条嵌套约束要心里有数:行内元素不能装块级元素——<span><div></div></span> 是非法的;<p> 里不能放 <div>、<ul>,浏览器会在遇到块级子元素时自动提前闭合 <p>,生成你没料到的结构。例外是 <a>:HTML5 允许 a 包裹块级内容(卡片链接就是这么做的)。写结构时记住「块可以装块和行内,行内只能装行内(a 例外)」,再遇到浏览器「自作主张」的解析结果就不困惑了。
示例
<!-- 块级元素:各自独占一行 -->
<p>第一段,占满整行。</p>
<p>第二段,另起一行。</p>
<!-- 行内元素:排在同一行内 -->
<p>这是一段含 <strong>强调</strong>、<a href="/docs">链接</a> 和 <code>code</code> 的文字。</p>
<!-- 非法嵌套:p 遇到 div 会被提前闭合 -->
<!-- <p>说明文字 <div>块级内容</div> </p> 实际解析成三个独立元素 -->
<!-- a 可以包裹块级内容(HTML5 起合法) -->
<a href="/products/42">
<div class="card">
<h3>商品卡片</h3>
<p>整块都可点击。</p>
</div>
</a>
用 CSS 改变默认行为:
/* 链接变成整行可点的菜单项 */
.menu a {
display: block;
padding: 12px 16px;
}
/* 行内元素需要宽高时 */
.badge {
display: inline-block;
padding: 2px 8px;
}
/* 列表项横排 */
.nav li {
display: inline-block;
}
常见坑
- 给行内元素设宽高还疑惑没效果:span、a 的 width/height 默认被忽略,先改 display(inline-block 或 block)。
- p 里塞 div/ul 导致结构「诡异」:浏览器自动闭合 p 后,后面的样式选择器全部对不上。段落里只放行内内容。
- 行内元素之间的换行产生空隙:源码里两个 inline-block 之间的换行会被渲染成一个空格的宽度,导致间距对不齐。删除换行、设 font-size: 0 或改用 flex 布局解决。
- img 底部多出一条缝:img 默认是行内元素,基线对齐会在下方留出字母降部的空间。给 img 设 display: block 或 vertical-align: middle 即可。
小结
块级独占一行可控盒模型,行内随文字流排列不管宽高;display 可以改写任何元素的行为;嵌套守「行内不装块(a 例外)、p 不装块」的规矩。下一章看看 HTML 怎么影响搜索排名。