THE GITHTML FIELD GUIDE

Add syntax highlighting to static HTML without JavaScript

Highlight code before the document is published instead of in the reader's browser. Pygments, Pandoc, and Shiki all emit HTML spans with colors already applied, either as inline styles or as classes with a small stylesheet you embed. The result is colored code that renders offline and with JavaScript disabled, unlike highlight.js or Prism loaded from a CDN.

Why client-side highlighters disappear

Libraries such as highlight.js and Prism run in the browser, find code blocks, and wrap tokens in spans. If the script cannot load, or scripts are off as they are by default in gitHtml, readers get plain monospace text. That is still readable, but long examples lose the visual cues that separate strings, keywords, and comments.

Build-time highlighting produces the same spans once, on the author's machine. Nothing needs to run when the document is opened.

Three build-time options

Pygments is a Python library and command-line tool. Its HTML formatter can write a full standalone page, or a fragment plus a separate stylesheet you paste into a style element. The noclasses option writes inline styles, which is convenient for a single snippet but grows large for long files.

Pandoc highlights fenced code blocks during conversion. Since Pandoc 3.8 the option is --syntax-highlighting; earlier versions use --highlight-style, which still works with a deprecation warning. Shiki, a JavaScript library, runs at build time in Node and emits HTML with inline token colors, including dual light and dark themes through CSS variables.

bash
# Pygments: standalone page with line numbers
pygmentize -f html -O full,style=default,linenos=1 -o example.html example.py

# Pygments: fragment plus stylesheet to inline
pygmentize -f html -o snippet.html example.py
pygmentize -f html -S default -a .highlight > highlight.css

# Pandoc 3.8+ (use --highlight-style on older versions)
pandoc guide.md --standalone --embed-resources --syntax-highlighting=tango -o guide.html
pandoc --list-highlight-styles

# Shiki (Node, at build time)
# import { codeToHtml } from 'shiki'
# const html = await codeToHtml(source, { lang: 'ts', theme: 'github-light' })

Make highlighted code readable on phones

Color is a supplement, not the message. Check that the theme has adequate contrast against its background, and that the code is still understandable in grayscale. Keep lines reasonably short in examples, and let the pre element scroll horizontally rather than wrapping in ways that change meaning for languages where indentation matters.

  1. Embed the highlighter's CSS in the document's style element rather than linking to it.
  2. Set pre { overflow-x: auto; } and a readable monospace size around 14 to 15 pixels.
  3. Pick a theme with sufficient contrast, or provide light and dark variants with prefers-color-scheme.
  4. Open the result with JavaScript disabled to confirm colors come from markup and CSS alone.
  5. Label each block's language in nearby text so color is never the only cue.

Keep source and output aligned

Highlight from the same source files your tests run, or from a document that is regenerated in the same commit as code changes. Copy-pasted, pre-highlighted HTML drifts quickly. Record the highlighter and version in a comment so the next author can reproduce the styling.

Sources and further reading

AI-assisted writing with source-linked guidance and illustrative examples. Read our editorial approach or report a correction.

All reading html on your phone guides →

Read as MarkdownAll guides