#4109·prism

Changed lines in `diff:<lang>` blocks are visually unmarked

Author: DmitrySharabinCreated Sep 15, 2026Updated Sep 15, 2026
Labelsbugthemes
  • diff:<lang> blocks have no way to mark changed lines beyond the one-character prefix.
  • Cause: themes color .token.deleted/.token.inserted in the foreground, and inner-language tokens override it.
  • Was covered by diff-highlight's opt-in class="diff-highlight", removed in #4105.
  • Blocking a fix: a companion plugin is not the solution we want (per #4105 review), and a CSS-only plugin is not buildable today.

Repro

javascript
Prism.highlight('-let a = 1;\n+const a = 1;\n', 'diff:javascript');
xml
<span class="token deleted-sign deleted">
  <span class="token prefix deleted">-</span>
  <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span>
</span>

let, = and 1 carry their own JavaScript colors, so the deleted foreground color set by every theme reaches only the spaces between them. Plain diff is unaffected — there are no inner tokens to override it.

What was removed

src/plugins/diff-highlight/diff-highlight.css painted translucent line backgrounds behind changed lines, leaving inner syntax colors intact:

css
pre.diff-highlight > code .token.deleted:not(.prefix),
pre > code.diff-highlight .token.deleted:not(.prefix) {
	background-color: rgba(255, 0, 0, 0.1);
	color: inherit;
	display: block;
}

Default rendering never used it, so only users who opted in lost anything.

Notes for whoever fixes this

  • The selector still matches the new output unchanged: diff.js:38 derives the deleted/inserted alias from the token name, so deleted-sign and deleted-arrow both carry it and :not(.prefix) still excludes the markers.
  • color: inherit is load-bearing — without it the inner language's colors are lost.
  • Consecutive changed lines are a single token, so display: block paints one block per run, not per line.
  • A CSS-only plugin is not possible today: scripts/build.js:150 and :414 both require plugins/<id>/<id>.js.
  • diff:diff:<lang> nests the wrappers, so any background stacks.
  • If this moves into the default theme, funky.css previously overrode it with a stronger background and display: inline.