版本对比时怎么高亮显示差异行?

迷人的硕泽 阅读 42

我在做配置文件的版本对比功能,想用颜色区分新增、删除和修改的行,但样式总是对不齐。

试过给不同状态的行加 class,但行号和内容错位了,看起来很乱。是不是得用 table 或者特殊布局?

.diff-added {
  background-color: #e6ffed;
  padding-left: 10px;
}
.diff-removed {
  background-color: #ffeef0;
  padding-left: 10px;
}
.diff-line {
  display: block;
  font-family: monospace;
}
我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
一亚飞
一亚飞 Lv1
这个问题很常见,行号和内容错位主要是因为没有把两者分开处理。用 flex 布局就能很好的解决。

核心思路是:把行号和内容放在两个独立的容器里,各自占各自的宽度,互不干扰。

/* 外层容器用 flex */
.diff-row {
display: flex;
align-items: stretch;
font-family: monospace;
}

/* 行号区域固定宽度,右对齐 */
.diff-line-number {
width: 50px;
text-align: right;
padding-right: 10px;
color: #6e7781;
background-color: #f6f8fa;
user-select: none;
flex-shrink: 0;
}

/* 内容区域 flex 增长 */
.diff-line-content {
flex: 1;
padding-left: 10px;
white-space: pre-wrap;
word-break: break-all;
}

/* 三种状态的背景色 */
.diff-added .diff-line-content {
background-color: #e6ffed;
}

.diff-removed .diff-line-content {
background-color: #ffeef0;
}

.diff-modified .diff-line-content {
background-color: #fff5b1;
}


HTML 结构大概这样:


+12
新增的代码行


-8
被删除的代码行


你之前的问题就在于把 padding 加在了整个行上,导致行号那列也被撑开了。用我上面这个结构,行号固定宽度,内容自己管自己,完全不会乱。

如果你是后端直接生成 diff 字符串,可以考虑用现成的库来处理,比如 PHP 的 phpspec/php-diff 或者 sebastian/diff,它们直接输出带标记的数组,你拿到前端渲染就行了,省得自己在那儿拼字符串。
点赞
2026-03-14 12:13
Newb.子斌
这个需求很常见,一般这样处理:

1. 表格布局确实更稳,每行用两个单元格分别放行号和内容。这样样式不会乱跑:











42 + 这是新增的行
43 - 这是删除的行



2. CSS可以这样写,保证对齐:

.diff-table {
font-family: monospace;
border-collapse: collapse;
width: 100%;
}
.line-number {
text-align: right;
padding-right: 1em;
color: #999;
user-select: none;
}
.diff-added {
background-color: #e6ffed;
}
.diff-removed {
background-color: #ffeef0;
}


3. 如果不用table,也可以用flex布局,但处理行号对齐更麻烦。我上次折腾半天最后还是换回table了...

关键点就是行号和内容要分开容器,别混在一起。GitHub的diff实现也是类似思路,你可以F12看下他们的DOM结构。
点赞 1
2026-03-06 15:04