No. 01 / 16 · PixelSpecimen · 2026-10-27
Cap 2100X 1200Base 0Desc −600Outline
The pixel font drawn on the grid of my mark. Five sizes, zero grey pixels.
Try it
72 px · 9 px cells · kerning on · click the text to edit it
How it is built
A pixel font that refuses to blur. Set it at 16, 32, 48, 72 or 120 px and every edge lands on a whole pixel. Other sizes work too. They just look disappointed in you.
Regular, a Bold drawn by hand, and Grid, a variable face that draws every cell as its own square. Tabular figures, curly quotes, dashes, arrows, the dh mark (type dh) and seven project glyphs in the private-use area. Version 1.001.
One cell is the font size divided by eight, so at 16, 32, 48, 72 and 120 px every edge lands on a whole pixel. The tester and the waterfall only offer those sizes.
- NodeAn on-curve point at (0, -600). 12 in this glyph.
- Cell300 units, an eighth of the em: 2 px at 16, 15 px at 120, never a fraction.
- Advance1500 units wide: 0 of space on the left, 300 on the right.
- The mark's barThe bar of the dh mark sits on row 4, so the x-height is 4 cells (1,200 units) and every bar, dash and arrow sits there too.
It started as a logo
My mark is a d and an h sharing one stem, drawn on 7 × 7 cells. Its stem set the cap height, its bar set the x-height, and the rest of the alphabet had to fit around it. Type dh in Stem 7 and you get the mark back.
The mark · 7 × 7
Drawn in a text file
No font editor. Each glyph is nine rows of X and . in a plain text file, with the reason for the drawing written above it. Diffs are readable and every argument with myself is in version control.
The built font at 120 px
Eight cells to the em
The em is 2,400 units, or 8 cells of 300. So one cell is always the font size divided by eight, and at the five house sizes that comes out to a whole number of pixels.
Zero grey pixels
A crisp pixel font has two colours: ink and not ink. Any pixel in between is the rasteriser guessing. This loupe renders the font in your browser right now and counts the guesses.
| Build | 16 | 32 | 48 | 72 | 120 |
|---|---|---|---|---|---|
| The first build (1,000 UPM) | 63.5% | 35.5% | 25.9% | 18.4% | 0% |
| Stem 7 1.001, Regular | 0 | 0 | 0 | 0 | 0 |
| Stem 7 1.001, Bold | 0 | 0 | 0 | 0 | 0 |
The one with gaps
Grid draws every cell as its own square, with a gap cut from the top and right. No single gap stays whole at every size, so Grid is a variable font: the gap is half a cell up to 40 px and a third of a cell from 48 px. Browsers pick it automatically.
Three rounds of arguing with myself
The first draft looked fine as an alphabet and fell apart in words. place read as ploce, and 64×64 had a lowercase x in the middle. Each fix below has its reason written into the source.
Bold, by hand
The bold draft is a rule: double every column that carries a stem. That works for H and falls apart on diagonals, curves and dots. 64 of the 120 bold glyphs were redrawn by hand.
Kerning in whole cells
Kerning comes from the drawings, not from my eyes at 2 a.m. For each pair, compare the facing edges row by row and average the gap. Under 3 cells: leave it. 3 to 5: pull in one cell. 5 or more: two. Never closer than one cell, and never into a mouth like C's.
How it fits
- UnkernedThe second letter where its advance width alone would put it: hairline.
- KernedThe pair as the font sets it, pulled in by the value under it, in units of a 2400-unit em.
Every size it is drawn for
All 121 characters
- Char
- g
- Code point
- U+0067
- Glyph
- g
- Advance
- 1500
- LSB · RSB
- 0 · 300
- Contours · points
- 2 · 12
Uppercase · 26
Lowercase · 26
Figures · 10
Punctuation and symbols · 59
Good at
HUDs, counters, labels, numbers that change while you watch. Figures are tabular, so they don't jiggle. Not recommended for your novel.
$ stemctl crispRegular 16 0 grey PASSRegular 120 0 grey PASSall crisp
Get Stem 7
TTF for desktops, WOFF2 for the web, or the zip with both, the licence and a readme. Free for anything, commercial included, under the SIL Open Font License 1.1.
Buy me a coffee ↗Optional. The fonts stay free.
@font-face {
font-family: "Stem 7";
src: url("Stem7-Regular.woff2") format("woff2");
font-weight: 400;
font-display: swap;
}
@font-face {
font-family: "Stem 7";
src: url("Stem7-Bold.woff2") format("woff2");
font-weight: 700;
font-display: swap;
}
@font-face {
font-family: "Stem 7";
src: url("Stem7-Grid.woff2") format("woff2");
font-weight: 400;
font-display: swap;
}
h1 { font-family: "Stem 7", sans-serif; font-size: 48px; /* 16 32 48 72 120 */ }Install straight from GitHub. No registry account involved.
npm install github:davidghatley/stem7import "stem7/stem7.css";<h1 class="stem7 stem7--48">Hello</h1>Served from GitHub by jsDelivr. Paste it into your <head> and move on with your life.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/davidghatley/stem7@v1.0.1/stem7.css">@font-face {
font-family: "Stem 7";
src: url("https://cdn.jsdelivr.net/gh/davidghatley/stem7@v1.0.1/fonts/Stem7-Regular.woff2") format("woff2");
}
.pixel {
font-family: "Stem 7";
font-size: 32px; /* 16, 32, 48, 72 or 120 */
line-height: 1;
-webkit-font-smoothing: none;
}- Five sizes. 16, 32, 48, 72, 120 px. Anything else is a blur with extra steps.
line-height: 1. The baseline then sits exactly 7 cells below the top of the line, at every size.- Caps and figures at 16 px. Lowercase there has an x-height of 8 pixels. It tries its best. Start lowercase at 32.
- Smoothing off.
-webkit-font-smoothing: noneon macOS. The font has nothing to smooth. - Whole-pixel positions. Half a pixel of offset buys you all of the blur.
- Grid from 48 px up. Smaller works, but it gets thin.
Changelog and licence
| Version | What changed |
|---|---|
| 1.001 | F now kerns against a, c, e, g, m, n, o, r, u, w and y. The source asked for it all along; the build quietly dropped those 11 pairs. A new test shapes every pair with HarfBuzz so it can't happen again. |
| 1.000 | Regular, hand-drawn Bold and variable Grid. 0 grey pixels at all five sizes. |
Free for anything, commercial included, under the SIL Open Font License 1.1. There is no reserved font name, so subset it, convert it, rename it. Just don't sell the font files on their own. The sources, build tools and tests are on GitHub.