Home / Snippets / Typography /

Diff display (green/red)

Git-style diff rendering with CSS — added lines in green, removed in red, context lines plain.

@@ -4,7 +4,8 @@ .card {
  background: oklch(0.19 0.02 260);
  border-radius: 0.75rem;
  padding: 1rem;
  padding: 1.5rem;
  gap: 1rem;
  color: var(--text);
}
Widely Supported
typographycolorno-js

Quick implementation

.diff-block {
  background: oklch(0.15 0.02 260);
  border-radius: 0.75rem;
  padding: 1.25rem 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.85rem;
  line-height: 1.7;
  overflow-x: auto;
}

.diff-block .line {
  display: block;
  padding: 0 1.5rem;
}

/* Added lines */
.diff-add {
  background: oklch(0.25 0.08 145);
  color: oklch(0.85 0.10 145);
}
.diff-add::before {
  content: "+ ";
  color: oklch(0.70 0.16 145);
  font-weight: 700;
}

/* Removed lines */
.diff-remove {
  background: oklch(0.25 0.08 25);
  color: oklch(0.85 0.10 25);
}
.diff-remove::before {
  content: "- ";
  color: oklch(0.70 0.16 25);
  font-weight: 700;
}

/* Context lines */
.diff-ctx {
  color: oklch(0.70 0.02 260);
}
.diff-ctx::before { content: "  "; }

/* Hunk header */
.diff-hunk {
  color: oklch(0.62 0.12 265);
  font-style: italic;
}
.diff-hunk::before { content: "  "; }

Prompt this to your LLM

Includes role, constraints, line type classes, oklch palette, and edge cases.

You are a senior frontend engineer building a code diff display component.

Goal: A CSS-only git-style diff viewer — added lines green, removed lines red, context lines plain.

Technical constraints:
- Use oklch() for all colors — no hex, no rgba().
- Added lines (.diff-add): background oklch(0.25 0.08 145), text oklch(0.85 0.10 145).
- Removed lines (.diff-remove): background oklch(0.25 0.08 25), text oklch(0.85 0.10 25).
- Context lines (.diff-ctx): plain dark background, muted text oklch(0.70 0.02 260).
- Hunk headers (.diff-hunk): accent color, italic.
- Use ::before pseudo-element for the +/- sigil (content: "+ " or "- ").
- Sigil must be bold and slightly brighter than the line text.
- Each line is a <span class="line diff-add"> etc. inside a <pre class="diff-block">.
- Lines must use display: block so backgrounds span full width.
- Horizontal scroll: overflow-x: auto on .diff-block.

Framework variants (pick one):
A) HTML/CSS — produce the span markup statically.
B) React component — accept a diff string, parse it line-by-line, classify each line, render spans.

Edge cases to handle:
- Empty context lines still render a numbered-height row (display: block handles this).
- Hunk header lines (@@ ... @@) should be visually distinct — italicised accent color.
- Ensure added/removed backgrounds extend to the full line width, not just the text.

Return CSS only.

Why this matters in 2026

Diff views appear in documentation, code review tools, changelogs, and tutorial sites. A CSS-only implementation means no dependency on a diff renderer for the visual layer — you control the markup and the theme independently. Using oklch() ensures the green and red hues carry equal perceptual weight and remain distinguishable for people with reduced colour vision when paired with the + and - sigils.

The logic

Each line is a display: block span so its background colour spans the full container width. The ::before pseudo-element injects the + or - sigil, keeping it out of the DOM text and clipboard selection. The oklch() color space makes it straightforward to tune the background and foreground together: both green and red lines use the same lightness (0.25) and chroma (0.08) for backgrounds, differing only in hue — 145 for green, 25 for red.

Accessibility & performance

Colour alone must never be the only differentiator. The + and - sigils in the ::before pseudo-elements provide a text-based signal that works for colour-blind users and screen readers (when not suppressed with aria-hidden). Both oklch hues are distinguishable under deuteranopia because the red-green contrast at hue 25 vs 145 is retained in the blue channel. The entire component is pure CSS — no JavaScript diff parsing, no runtime cost.