Notes
I’ve started incorporating sample PNGs to illustrate typefaces in the Atlas of Type, and secretly hoped they’d work as OpenGraph previews just as well. Turns out tightly cropped, black-on-transparent images like the one below were not on most platforms’ og:image
bingo cards:
The results were uniformly atrocious. To render well, the samples need a solid background and some padding:
As the Atlas is a 100% static Eleventy website, these preview images need to be computed beforehand, ideally without manual involvement. A scan of the docs for the trusty eleventy-img
plugin revealed that the 6.x release last week coincidentally added access to sharp
, the underlying image processing library, so compositing the sample PNGs onto a white canvas was no big deal.
This is the .eleventy.js
config to define an og_image
shortcode that takes an image from static/img/typeface/
and generates a corresponding 1200×800
preview image in static/img/card/
:
Usage in a Nunjucks template, and the resulting markup:
<!-- template -->
<meta
property="og:image"
content="{{ site.url }}{% og_image '/img/typeface/my-sample.png' %}"
>
<!-- result -->
<meta
property="og:image"
content="https://type-atlas.xyz/img/card/typeface/my-sample.png"
>
This is well-trodden ground, but this how I do HTTP 301 redirects in Eleventy, mostly to have a reference for the Apache vs. nginx syntax. I’m sticking with the Hugo aliases
convention in the front-matter data:
---
title: My post
aliases:
- /my-previous-url/
- /my-other-previous-url/
---
Here’s the Eleventy configuration to gather all the aliases in a collection of { from, to }
objects. All trailing slashes are removed from the paths, to make their usage clearer in the redirects.
function stripTrailingSlashes(str = '') {
return str.replace(/^\/|\/$/g, '');
}
config.addCollection('aliases', function (api) {
return api
.getAll()
.map(page => {
return (page.data.aliases ?? []).map(alias => {
return {
from: stripTrailingSlashes(alias),
to: stripTrailingSlashes(it.page.url)
};
};
})
.flat();
});
With the collection in place, it becomes a matter of producing a server-specific redirects file. Apache can use a .htaccess
file in the website’s root, produced by the Nunjucks template below:
---
permalink: /.htaccess
eleventyExcludeFromCollections: true
---
ErrorDocument 404 /404.html
<IfModule mod_alias.c>
RewriteEngine On
{% for alias in collections.aliases %}
RedirectMatch 301 ^/{{ alias.from }}/?$ /{{ alias.to }}/{% endfor %}
</IfModule>
When it comes to nginx, producing the set of redirects is only half the story. Let’s first generate a 301.redirects
file in the website root:
---
permalink: /301.redirects
eleventyExcludeFromCollections: true
---
{% for alias in collections.aliases %}
rewrite ^/{{alias.from}}/?$ /{{alias.to}}/ permanent;{% endfor %}
This file does nothing by default. It needs to be included in the nginx configuration:
server {
include path/to/301.redirects;
}
There’s a number of ways to go about it, which I won’t document here. But if the technique invovles leaving the physical 301.redirects
file in the website’s root directory, you’ll probably want to make it inaccessible to the outside world with something along the lines of:
location = /301.redirects {
internal;
}
One gotcha is that aliases added to pages having eleventyExcludeFromCollections: true
won’t be included in the redirects file, an aspect I noticed when moving some Atom feeds around. Eleventy doesn’t yet have an API to grab excluded pages, so for now I’ve added manual entries to .htaccess
.
Reviewing a recent post about my favorite records of 2024, I noticed something off about two lists rendered next to each other. The unordered list has a larger line height than the ordered one, but only in Firefox. Why’s that?
Firefox devtools showed in the Fonts tab that the marker is using a font named -moz-bullet-font
, and not inheriting the font from its ancestors like the Rules panel implied.
The Mozilla Bullet font is defined inline in Firefox’s default stylesheet for HTML, and was introduced three years ago to replace the bullet images previously in use. It contains glyphs for the all the simple symbolic counters: disc
, circle
, and square
, as well as disclosure-open
and disclosure-closed
for all writing modes.
Using a browser-defined font like this is codified in the spec: When used in
list-style-type
, a UA may instead render these styles using a UA-generated image or a UA-chosen font instead of rendering the specified character in the element’s own font. If using an image, it must look similar to the character, and must be sized to attractively fill a 1em by 1em square.
The reason why there’s no rule in the default stylesheet to apply this font…
::marker {
font-family: -moz-bullet-font;
}
…is because the marker must pick up the parent’s font-family
in all other situations, including when changing the marker’s presentation via the content
property. Instead, it’s all handled at the code level, and thus invisible to the Rules tab in devtools. (Technically a bug, but one whose resolution might not justify the effort.)
How to fix the spacing? As with other things that may affect the line height, throwing in line-height: 0
seems to do the trick, and you may very well leave it at that.
::marker {
line-height: 0;
}
But let’s see if we can align Firefox with what other browsers are doing, and inherit the font in all cases.
::marker {
font: inherit;
}
One immediate problem with this is the default character sequence used in unordered lists, "• "
(bullet followed by space), looks dainty and crammed against the text in most fonts. Mozilla Bullet works around that by defining a wider space character. Similarly, Chrome and Safari seem to use internal adjustments to the spacing to make it look a bit better than straight-up rendering the two characters.
As Šime Vidas points out, the possibilities for spacing list markers are quite limited. Moreover, built-in counter styles such as disc
can’t be overriden. The kind of solution robust enough for a CSS reset is therefore a bit verbose, and involves defining new counter styles with better spacing (via space characters, no less). This would be just for fixing the disc
list markers:
@counter-style disc-fixed {
system: cyclic;
/* bullet character… */
symbols: \2022;
/* …followed by three spaces for better spacing */
suffix: " ";
}
ul, menu, dir {
list-style-type: disc-fixed;
}
::marker {
font: inherit;
}
Kind of a hard sell, to be honest. But yeah, that’s where the line-height thing comes from.
I’m a sporadic writer. This year, I only managed a couple of articles between my end-of-year music lists doubling as mileposts, and a decade’s worth of writing fits comfortably on a single page.
To shake things up, I’ve been meaning to carve out a separate section for posts that are shorter, smaller in scope, and more frequent. A bit like what Tom MacWright, Simon Willison, or David Bushell are doing.
So, here we are. The inaugural post in the new Notes section.
If you’re reading this in a feed reader and you’ve subscribed before December 2024, you’re receiving the combined feed that includes articles, my linkblog, and these notes. If it suits you better, you can now subscribe to individual feeds.