用做代码差异对比的核心是语义对齐而非高亮,需先完成转义、行对齐、状态分类三步预处理,再用逐行封装,配合保留格式、css区分状态、独立行号列及移动端滚动优化。

用 <table> 做代码差异对比,核心是语义对齐而非高亮
<p>直接用 <code><table> 展示两列代码差异可行,但别指望它自动识别增删——它只负责排版。真正起作用的是你提前处理好的行级对齐结果。比如 Git diff 输出的 <code>+line / -line 不能直接塞进表格,得先按逻辑行拆解、补空、标记状态。
常见错误是把原始 diff 文本原样丢进 <td>,导致左右列行数不一致、缩进错乱、特殊字符(如 <code>&、)被 HTML 解析破坏。必须先做三件事:<strong>转义</strong>、<strong>行对齐</strong>、<strong>状态分类</strong>。
<ul>
<li>用 <code>document.createTextNode() 或 textContent 插入内容,避免手动拼接字符串引发 XSS 或解析错误
<tr>,左列放“原代码”,右列放“修改后”,缺失行用 <code><td> </td> 占位
diff-add、diff-del、diff-change,不要依赖背景色硬编码
<pre class="brush:php;toolbar:false;"></pre> 必须嵌套在 <td> 里,且禁用换行截断
<p><code><pre class="brush:php;toolbar:false;"></pre> 是保留代码格式的关键,但它默认会继承父容器样式。如果 <td> 有 <code>white-space: normal(浏览器默认),<pre class="brush:php;toolbar:false;"></pre> 就失效了。
实操时必须显式重置:
td pre {
white-space: pre;
margin: 0;
padding: 4px;
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
font-size: 12px;
line-height: 1.5;
}
注意两点:
- 不要用
white-space: pre-wrap—— 它会让长行自动折行,破坏代码对齐 - 避免给
<td> 设固定宽度,否则小屏下 <code><pre class="brush:php;toolbar:false;"></pre>溢出不可滚动;改用overflow-x: auto+max-width - 如果代码含制表符(
\t),<pre class="brush:php;toolbar:false;"></pre>默认显示为 8 字符宽,需加tab-size: 4统一
diff 行号怎么对齐?用空单元格比 JavaScript 计算更稳
很多人想用 JS 动态计算左右列行号偏移,结果遇到空行、折叠块、多行插入就错位。最简单可靠的方式是:把行号也作为独立列,且和代码列严格绑定。
结构建议这样写:
<tr>
<td class="line-num">12</td>
<td class="code-origin"><pre class="brush:php;toolbar:false;">function foo() {
function bar() {好处是:
- 行号列宽度固定(如
min-width: 3em),不会被代码长度挤压 - 当某侧无对应行时,行号列填
,代码列填空<pre class="brush:php;toolbar:false;"></pre>,视觉上自然留空 - 完全规避 JS 同步问题,服务端渲染或静态 HTML 都能直接用
移动端表格横向滚动要防“双滚动条”陷阱
两列代码并排,在手机上必然要横向滚动。但很多人只给 <table> 加 <code>overflow-x: auto,结果页面出现两个滚动条:外层页面滚 + 内层表格滚,体验极差。
正确做法是限制容器宽度并隔离滚动:
- 用包裹
<div class="diff-container">,设 <code>overflow-x: auto和width: 100% <table> 设 <code>min-width: fit-content(或具体值如min-width: 800px),防止被压缩- 禁用
<td> 的 <code>text-overflow: ellipsis—— 代码截断等于废掉对比功能 - 测试时重点看 iOS Safari:它对
overflow-x支持不稳定,有时需加-webkit-overflow-scrolling: touch
真正的难点不在写法,而在于你是否提前把 diff 结果做了行粒度归一化——没这步,HTML 表格再规范也对不齐。











