深入掌握Divider分割线的实现与应用场景

A. 恒菽 组件 阅读 2,734
赞 13 收藏
二维码
手机扫码查看
反馈

说实话,我以前真没把Divider当回事

直到有次在做一个后台管理系统的页面重构,设计师甩过来的设计稿里,分割线到处都是:卡片之间、表单项之间、菜单分组……而且要求还特别细,有的要带文字居中,有的要虚线,有的左边对齐文字右边线条,甚至还有渐变色的。我才意识到,这玩意儿真不能随便用个 hr 或者 border-bottom 就糊弄过去。

深入掌握Divider分割线的实现与应用场景

于是我开始认真对比几种实现 Divider 的方案。常见的无非就三种:用 HTML 标签(比如 hr)、用 CSS 伪元素、用组件库封装的 Divider 组件。本来以为都差不多,结果一上手才发现,每个都有坑,各有各的适用场景。

最后我的结论很明确:能用组件库就用组件库,尤其是你项目已经在用 Ant Design 或 Element Plus 这类 UI 框架的时候。但如果你是搞独立项目、轻量级应用,或者想控制 bundle 体积,那自己写 CSS 其实更灵活,也更可控。

谁更灵活?谁更省事?

先说最简单的——直接用 hr 标签。HTML 原生支持,一行代码搞定:

<hr />

看起来省事吧?但问题来了:样式太死板。默认就是一条灰色实线,宽度 100%,上下还有 margin。你想改颜色、改粗细、去 margin、加文字?得重写一堆 CSS,最后写的代码可能比你自己用 div 实现还多。

而且语义上也有点奇怪。hr 表示“主题分隔”,但在现代前端里,很多分割线并不是内容主题的切换,而是 UI 布局的视觉分隔。硬用 hr 反而会让语义变得模糊。所以我现在基本不用它了,除非是写文档类页面。

伪元素才是我的常用打法

我自己写项目时,最常用的其实是 CSS 伪元素 + flex 布局的组合。这种方案自由度高,代码也不复杂,关键是能适应各种布局需求。

比如最常见的“文字居中分割线”:

<div class="divider-with-text">或登录方式</div>
.divider-with-text {
  display: flex;
  align-items: center;
  margin: 16px 0;
  color: #999;
  font-size: 14px;
}

.divider-with-text::before,
.divider-with-text::after {
  content: "";
  flex: 1;
  height: 1px;
  background-color: #e5e5e5;
}

.divider-with-text::before {
  margin-right: 16px;
}

.divider-with-text::after {
  margin-left: 16px;
}

这个方案我用了好几年,亲测有效。优点很明显:

  • 一行 HTML 解决,结构干净
  • 支持自定义颜色、线型(改成 dashed 就是虚线)、间距
  • 文字可以动态插入,支持 i18n
  • 不需要额外 DOM 节点

当然也有缺点:比如你想让左右线条高度和文字行高对齐,有时候会因为字体渲染差异出现轻微错位。这里注意,我踩过好几次坑,后来统一加上了 line-height: 1height: 1px 强制对齐。

另外如果要做垂直方向的分割线,这套逻辑就得换,得用 ::before::after 做 top/bottom,或者干脆用两个伪元素做上下延伸。稍微麻烦点,但也不是不能解。

组件库的 Divider,真香但有点重

再说说 Ant Design 那套 <Divider>。我最近接的一个项目用了 Ant Design Vue,一开始我还嫌弃它太重,结果用上之后发现,它对 Divider 的封装确实到位。

比如这个写法:

<Divider>Or</Divider>
<Divider orientation="left">Left Text</Divider>
<Divider dashed>With Dashed Line</Divider>
<Divider style="color: red; border-color: #ccc; margin: 32px 0;">
  Custom Style
</Divider>

它直接支持文字位置、虚线、自定义样式,甚至连垂直分割都能用 type="vertical" 实现:

<span>Link 1</span>
<Divider type="vertical" />
<span>Link 2</span>
<Divider type="vertical" />
<span>Link 3</span>

说实话,这种场景下自己写 CSS 反而费劲。你得处理 inline-block 的间隙、vertical-align 对齐、高度控制……折腾半天效果还没人家稳定。

所以我的结论是:如果你项目已经引入了 Ant Design / Element Plus / PrimeVue 这类框架,别犹豫,直接用它们自带的 Divider 组件。省事、稳定、语义清晰,还支持无障碍访问(ARIA)。

但如果只是个小项目,或者你追求极致轻量,为了一个分割线引入整个 UI 库,那确实是杀鸡用牛刀。

性能对比:差距比我想象的小

我原本以为自定义 CSS 会比组件库快很多,毕竟没 React/Vue 的 vnode 开销。但实际测了一下首屏渲染和内存占用,差别几乎可以忽略。主要是因为 Divider 这种静态元素,DOM 节点少,不管哪种方案都不会成为性能瓶颈。

真正影响体验的反而是样式重绘。比如你在 SPA 里频繁切换带 Divider 的列表,用内联 style 的组件可能会触发更多 reflow。而用 class + BEM 命名的 CSS 方案,复用性更好,浏览器缓存也更友好。

但这都不是大问题。归根结底,Divider 不是性能敏感组件,选型还是应该以开发效率和维护成本为主。

我的选型逻辑

我现在是怎么选的?很简单:

  • 项目用了 Ant Design / Element Plus?→ 直接用官方 Divider
  • 纯静态页或轻量项目?→ 用伪元素方案,写成通用 class 复用
  • 需要 SSR 或 SEO 友好?→ 考虑用 div + aria-role=”separator”,提升可访问性
  • 就一行横线,没啥花哨需求?→ 用 hr 也行,但记得重置默认样式

另外提一嘴 Tailwind 的玩法。现在很多人用 Tailwind,实现分割线也很简单:

<div class="flex items-center my-4 text-gray-500">
  <div class="flex-1 h-px bg-gray-300"></div>
  <span class="mx-4">Or</span>
  <div class="flex-1 h-px bg-gray-300"></div>
</div>

这种写法其实和我前面的伪元素思路一样,只是把样式拆到了 class 里。好处是不用写额外 CSS,适合快速原型。但缺点是 HTML 结构变臃肿,而且不好复用。你要是在多个地方都这么写,不如抽个组件或者写个 @apply。

以上是我的对比总结,有不同看法欢迎评论区交流

这个技巧的拓展用法还有很多,比如带图标、动画出现、响应式隐藏……后续会继续分享这类博客。目前这套方案在我手上几个项目都跑得挺稳,改完后仍有一两个小问题(比如 Safari 下 1px 线条模糊),但加了 transform: scaleY(0.5) 后基本解决。

以上是我个人对这个 Divider 的完整讲解,有更优的实现方式欢迎评论区交流。毕竟前端这东西,没有银弹,只有权衡。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论