2025-05-04

Here’s a novel, fun, and (I think) not completely stupid way of highlighting source code on the web:

Transparent text clipping on a background drawn in css,
using the ch and lh units to fit the monospace font grid.

Click to see what I mean:

#include <stdio.h>

int main() {
  printf("Hello, World!");
  return 0;
}

The C code is the raw content of a <pre>...</pre> element. There are no spans or custom classes in the html. Instead, the colors are drawn as the background of the pre, using css linear-gradients. The css units ch (character (width)) and lh (line height) can target specific character positions on the monospace font grid.

background: 
  linear-gradient(orange,orange) 02ch 04lh / 08ch 1lh,
  linear-gradient(blue,blue) 12ch 04lh / 03ch 1lh,
  ... more linear-gradients
background-repeat: no-repeat;

The example above draws an orange rectangle on line 4, starting column 2 and 8 columns wide, and then another blue rectangle for three columns.

Then it’s just a matter of using the text as a clipping mask:

background-clip: text;
color: transparent;

Why?

I find it a bit sad that the contents of the <pre> element is not the actual code. It really bothers me when demonstrating a javascript snippet (in a <script> element) and then, the same sample code, repeated in a <pre>...</pre> element.

Here’s another hack: let’s render the <script> element visible, and use the same code for the demo and for the sample code:

that’s visible just above to reveal the background behind the code that’s being run 🙃.

Random notes and observations

  • Drawing rectangle with linear gradients inspired by css-tricks over there. I haven’t found a better way to draw rectangles in css, maybe using the new shape() function?
  • My first idea involved using the :nth-letter pseudo class. It doesn’t exist.
  • Of course the ch and lh units only make sense with a monospace font. My father used to write code in Comic Sans, you know.
  • Inspiration for this post came from writing sample code for tuiles.enliberte.fr and this post by lapcatsoftware.
  • Here’s some self-highlighting CSS. Not sure if it qualifies as a quine or not.
  • I need to work on the design of this blog.

Next steps

Of course, the CSS linear-gradients for the samples in the page were written by hand. It’s a bit tedious, yes; I suppose the next step would be to write a custom backend for higlight.js to output css instead of spans.