writing
Notes from building this
Ten pieces about the parts of the web that are hard to get right and easy to get wrong: joined scripts, font metrics, smooth scroll, reduced motion, and the difference between testing a page and measuring one. Every number in them came out of this site.
- pieces
- 10
- published
- 15.02.2026 – 26.08.2026
- languages
- English, Deutsch, العربية
All pieces
-
The right-to-left bugs logical properties cannot fix
Eleven mirror rules in 15,142 lines of CSS, and every one of the seven defects that reached Arabic readers lived somewhere logical properties cannot go.
14 min
-
Why your Arabic font is setting your English text
Zain carries 166 Latin codepoints and Cairo 291, so the Arabic family sitting first in every stack quietly won every English word on the Arabic pages.
9 min
-
Why axe reports contrast errors on text you can read
The same sweep, six minutes apart, manufactured 509 contrast nodes on text a human reads perfectly and concealed 420 instances of the one defect that was real.
9 min
-
What reduced motion should do to a WebGL or canvas hero
Reduced motion has two symmetric failure modes — leaving it moving, and leaving it blank — and a canvas hero is the one element that can hit both.
10 min
-
Measure the noise floor before you set a visual diff threshold
Two identical runs disagreed about nothing on the page and about 81 per cent of a canvas — which tightened one threshold tenfold and disqualified another outright.
11 min
-
Arabic line-height is not 1.7: computing the real floor
The ratio every guide repeats has no traceable source. Here is the arithmetic that replaces it, and the four strings that set the number on this site.
10 min
-
Smooth scroll does not break your anchor links — preventDefault does
Measured in Chromium 151: the library leaves an anchor click intact, and the usual fix loses the hash, the history entry, :target and the keyboard's place.
8 min
-
Smooth scroll measured: the cost is residency, not frame time
The measurable cost of a smooth scroller is residency rather than frame time — and once it was gated to zero here, the last frame still running belonged to GSAP.
12 min
-
Arabic has no x-height: measuring size-adjust from the outlines
Arabic has no x-height, so the multiplier that matches an Arabic face to a Latin one has to be read out of the outlines — and one value is not enough.
11 min
-
GSAP SplitText breaks Arabic, and it is not a right-to-left problem
Direction and joining are different properties of a script, and conflating them is why the usual fix for broken Arabic in SplitText fixes the wrong bug.
9 min
Nothing matches that. Try a shorter word, or clear the filters.
Working on something like this?
Most of these were written because a build made me answer the question properly. If one of them is your problem this week, the fastest route is a short message.