How Rich Text can vanish in QuickLook

It may be four years since macOS Mojave brought us Dark Mode, but I’m sad that it still doesn’t work properly, as I’m reminded every day when I see QuickLook thumbnails of Rich Text documents. Let me explain.

Take as an example my log browser Ulbow, which uses colour in its display of a log extract to distinguish different fields in each entry. In Light Mode, these include black as standard, red, blue and green.


In Dark Mode, those colours aren’t inverted, but converted to their equivalents for the changed background, with white as standard, and adjusted shades of red, blue and green.


Ulbow can save its log extracts in Rich Text format, preserving those semantic colours. When you open that RTF file in TextEdit, it accommodates correctly to the set Appearance. Light mode shows appropriate colours.


And Dark Mode also works fine.


But select that Rich Text file, rendered so well by TextEdit, and QuickLook clearly doesn’t understand how to render it correctly in its thumbnails or previews. Light Mode looks fine.


But in Dark Mode it fails to render the uncoloured (standard) text or the background correctly, putting white text on a white background, so making that text vanish, and that preview useless.


One obvious answer is that it’s my app’s fault for not following Apple’s rules for correctly rendering text in different Appearance modes. Apple laid those out in two sessions in WWDC 2018, sessions 210 Introducing Dark Mode and 218 Advanced Dark Mode. Rather than using hardcoded colours like, which had been standard until then, developers were told to use the Appearance-independent NSColor.textColor. That’s exactly what Ulbow and my other apps do, and as I’ve shown above, that works perfectly within the app, and when the RTF files it creates are rendered properly in TextEdit and my own app DelightEd. If you’re in any doubt, Apple’s current documentation is unambiguous when it comes to NSColor.textColor: “The color to use for text.”

It wasn’t long before I realised that QuickLook in Mojave hadn’t caught up with Dark Mode: on 9 October 2018, I described how its thumbnails and previews weren’t rendering Rich Text correctly. And that’s the way it has stayed over the remaining years since.

Anyone who works predominantly in Dark Mode is reminded of this failure in QuickLook every day. There are workarounds, of course, and ignoring those instructions about using NSColor.textColor seems to work for Rich Text generated by apps, even though they still need to conform to the rules internally.

The root cause is that QuickLook is cutting corners, and won’t take the trouble to parse the Rich Text properly. When Rich Text is generated directly from styled or attributed text that’s Appearance-independent, it uses a Colour Table and Expanded Colour Table designed for the purpose. Colours are even named after their NSColor values:
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0\cname textColor;\cssrgb\c15686\c80392\c25490\cname systemGreenColor;\cssrgb\c0\c47843\c100000\cname systemBlueColor;
\cssrgb\c100000\c23137\c18824\cname systemRedColor;}

Content then uses those to set those special colours, such as
\cf2 2022-08-02 08:13:23.007682+0100 \cf3 Default

The additional effort involved on the part of QuickLook should be minimal, and is built into macOS frameworks anyway.

Ironically, the Rich Text that QuickLook renders correctly ignores Appearance altogether, and has no entries in any Expanded Colour Table, such as

with content such as
\cf0 This is a quick test

Before you dismiss this as merely cosmetic, consider your reaction to previewing a major Rich Text document only to be shown a completely empty window. Do you assume that something terrible has happened to the content of that document, or merely write it off as another bug that has been left untouched for four years across four major versions of macOS?