是语义化主题分隔符,仅用于标识相邻内容块间的话题、场景或逻辑切换;滥用会破坏可访问性与seo,纯视觉分隔应使用css border或伪元素。

hr 标签不是“画线工具”,而是语义分隔符。用错地方,样式再漂亮也白搭——屏幕阅读器会读它,SEO 会解析它,可访问性检查会盯上它。
什么时候必须用 hr
只有当两个相邻内容块存在明确的主题切换时才该用:hr 表示“话题断开”,不是“视觉留白”。比如:
- 一篇博客正文结束后,进入「作者说」评论区前
- 产品介绍段落与用户评价列表之间
- 表单中「登录方式」区块和「注册入口」区块的交界处
如果只是想在两个按钮之间加条细线、或卡片底部压一条浅灰线,hr 就是误用——它会向辅助技术发出错误信号,且可能被搜索引擎降权。
怎么让 hr 看起来不像默认那条灰线
浏览器对 hr 的默认渲染差异大(Firefox 默认 box-sizing: content-box,Chrome 是 border-box),直接设 height 容易错位。稳妥做法是清空边框,用背景撑高:
hr {
border: none;
height: 2px;
background: #4a6fa5;
margin: 1.5rem auto;
box-sizing: border-box;
}
关键点:
- 别用
color属性改色——它在现代浏览器里基本无效 - 虚线/点线优先用
border-top: 1px dashed #999,比background+height更稳 - 加渐变要小心:用
background: linear-gradient(...)时,height必须设为具体像素值,否则可能塌掉 - 移动端若需缩窄宽度,用
max-width: 80%+margin: 1rem auto,别只靠width
为什么很多时候该用 border-bottom 而不是 hr
当你需要的是纯视觉分隔,且位置绑定在某个容器上(比如每个列表项下方、每个卡片底部),border-bottom 才是正解:
<div class="card">
<p>卡片内容</p>
</div>
<style>
.card { border-bottom: 1px solid #e0e0e0; padding-bottom: 1rem; }
</style>
好处很实在:
- 样式完全受控:不依赖
hr的块级独占行为,不会意外换行 - 响应式友好:可随父容器宽度自动缩放,
hr的width在 flex 或 grid 里常失效 - 无障碍干净:不引入额外语义节点,不影响焦点流和屏幕阅读器节奏
- 调试简单:出问题时直接查父元素样式,不用追
hr的隐式 margin 和 box-sizing
伪元素方案适合什么场景
需要中间带文字的横线(如“或”、“—— 以下为广告 ——”),hr 做不了,border 也不方便。这时用 ::before/::after 最自然:
.text-divider {
display: flex;
align-items: center;
text-align: center;
color: #666;
font-size: 0.875rem;
margin: 1.5rem 0;
}
.text-divider::before,
.text-divider::after {
content: "";
flex: 1;
border-top: 1px solid #ddd;
}
.text-divider::before { margin-right: 0.75rem; }
.text-divider::after { margin-left: 0.75rem; }
注意:
- 别给这个容器加语义标签(比如
<section></section>),它本质是装饰性结构 - 如果“或”字有交互(比如点击切换登录方式),得额外加
role="button"和键盘支持 - 在低对比度模式下,
#ddd可能不可见,建议用至少#999或加opacity: 0.7
真正难的从来不是怎么画出一条线,而是判断这条线该不该存在、以什么身份存在。画错了,后面所有样式、适配、无障碍补救,成本都远高于一开始选对标签。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











