Updating to Tailwind Typography to style markdown posts

Last year I shared some CSS to style your markdown posts with Tailwind CSS. Earlier this year a Typography plugin was released for Tailwind CSS that takes care of styling your vanilla HTML for you (the kind generated by GatsbyJS processing markdown files). This post will walk through the process of migrating from a custom stylesheet to the Typography plugin.

To get started I installed the plugin (see the installation instructions on GitHub):

yarn add @tailwindcss/typography

# or by adding the tailwind UI plugin (which includes tailwind typography)
yarn add @tailwindcss/ui

And add to the plugin array in tailwind.config.js:

plugins: [require(`@tailwindcss/typography`)],

// Or if you use tailwind UI
plugins: [require(`@tailwindcss/ui`)],

And then update the class on the element that will contain the rendered markdown:

- <article className="markdown">
+ <article className="prose prose-lg">

And done! There were a few differences between my old stylesheet and the new plugin:

  • Different default text color (bg-gray-700 instead of bg-gray-800)
  • Different link styling (gray with underline - far too edgy for me!)
  • Added quotes around inline code and blockquotes
  • More spacing around headers and between lines
  • A lower max-width for the container

I was pleasantly surprised to discover that the site didn't look all that different after switching over - my stylesheet can't have been that bad from a design perspective.

Some of the changes I've decided to stick with - I've adopted bg-gray-700 globally as well as the enhanced spacing. The other items though (link styling, quotes, container width) I wanted to undo some of the additions. Fortunately the documentation on Github made this a mostly painless experience.

Updating container width was really easy to update:

- <article className="prose prose-lg">
+ <article className="prose prose-lg max-w-none">

Changing the default link styling required adding a typography key to the tailwind.config.js file and overriding the default a styling:

typography: (theme) => {
return {
default: {
css: {
a: {
color: theme(`colors.blue.600`),
textDecoration: `none`,
"&:hover": {
textDecoration: `underline`,

Although it looks like a lot of code most of it is boilerplate, and the actual styling overrides are only a few lines. The lines above gave me back my blue links with that all-important underline-on-hover (which maybe qualifies as retro in 2020?).

The final change was to disable the additional quotes (which use before/after content) - what I used was the following addition to the css key in the config:

// in the css: { ...block ... }
"code::before": false,
"code::after": false,
"blockquote p:first-of-type::before": false,
"blockquote p:last-of-type::after": false,

And we're almost done. The one piece of custom styling I had to preserve was the rule that stops prismjs from causing extremely long pieces of inline code (like this one here) to scroll rather than wrap (now targeting prose, rather than my old markdown class):

.prose :not(pre) > code.language-text {
white-space: pre-line;

Overall I'm really happy to be building on a design foundation that will evolve as Tailwind CSS does. It also allowed me to replace about 100 lines of custom CSS with 20 lines of tailwind overrides.