preflight by tailwind css

this article was written by: andrew

they started writing it: Feb 25, 2022

it was last updated: May 31, 2022

excited => confused => happy - AKA the learning-Tailwind-CSS version of the Gartner hype cycle.

When I first started out with Tailwind CSS, it was exciting to see some of the awkward html/body/etc defaults get blown away (yay, no awkward margins!). The explicit nature of Tailwind CSS felt a little clonky, but ultimately super powerful - no hidden styling and everything is right next to your components.

That said, have you ever styled a list with Tailwind? The first time you throw that <ul><li></li></ul> tag combo out there, the list comes out flush against the left border, no bullets anywhere to be found. Chaos reigns.

Where are the default styles!?

Tailwind CSS by default has a thing they call Preflight, also known as clearing nearly all the default CSS styling. For the reasons I mentioned earlier, it's super useful! But since Tailwind focuses on explicit-styling, it means that things like MDX that I used to build this garden make assumptions about some styling that will exists globally/by default on the page.

How this looks in practice:

a screenshot of the about-this-garden page. there is primitive styling (bold/italics work), but headers are not differentiated, bullets are missing, and spacing is gone.
Before styling
a screenshot of the about-this-garden page. headers are offset, bullets are present, and spacing spreads sections apart.
After styling

In the before, some very basic styling remains (<i> and <b> tags, for example), but the vast majority of styling is missing. The after shows the basic styling that was added using a custom MDXProvider.

Styling content with limited control

Don't turn off default (un-)styling unless you absolutely must.

Building this site put me into the case where I've got unstyled MDX content with limited control over individual elements due to the auto-generation. This flies directly in the face of how Tailwind likes to operate with its styles cozied up alongside elements.

A Custom MDXProvider

Instead of globally disabling this (it's super useful anywhere you're actually using Tailwind), we can write a custom MDXProvider, starting with the setup from the Next.js blog. I copied over the full file at the time of writing and threw it in a gist:

Alternative: Tailwind Typography Plugin

A few months after I wrote this, I discovered @tailwindcss/typography, which is specifically created for situations like this. The rough idea is that you add a prose class to the parent of the uncontrolled output (i.e. the Markdown), and some default styles are used, plus you still have some flexibility over things like responsiveness and dark/light mode.

I tried it out - it works! It took less than 5 minutes to get up and running and a halfway-decent page with styling. My relatively hot takes (spending very little time with it):


  • Quick as heck to get started, and avoids having to do a custom MDXProvider
  • Supports mostly everything (the obvious - headings, lists, but also code blocks, quotes, and tables)
  • Recently added support for not-prose, which would be very useful for the clean unstyled baseline for compenents embedded in the mdx


  • Yet another styling customization point - either you style all the prose-*, or accept subtely different styles from the rest of your site

Ultimately, I chose not to use it, since I had already done the necessary work - which ended up not being that much work - and was built to match the rest of the site! However, if you're starting fresh, it's almost certainly worth it to just use the plugin.

Happy Tailwinding!