Skip to content

Instantly share code, notes, and snippets.

@richsilv
Last active January 24, 2023 18:44
Show Gist options
  • Save richsilv/9911437f48d707c9161951e7048fd410 to your computer and use it in GitHub Desktop.
Save richsilv/9911437f48d707c9161951e7048fd410 to your computer and use it in GitHub Desktop.
MDX decorators to apply alternative styles when using Markdown primitives

MDX CSS Decorators

MDX is super-cool, allowing one to include React Components in a markdown file:

# Title

A nicely formatted paragraph of text with [some links](www.blahblah.com).

<MyIncredibleComponent data={{ status: "brilliant }} />

More text which is *effortlessly* well-styled.

One of the most useful features is that it allows you to supply components to use in place of the defaults for markdown's fundamental building blocks, like <p> or <h1>. Whatever CSS solution you're using, this makes it easy to pass in pre-styled tags:

.my-paragraph-style {
  color: #444;
  margin-bottom: 2em;
}
const Paragraph = ({ children }) => <p className="my-paragraph-style">{children}</p> // or just a styled-component, etc.

<MDXProvider components={{ p: Paragraph }}>
  ...
</MDXProvider>

Hooray! But what happens when you occasionally want to use a slightly special style for a markdown primitive? Sure, you can inline your own markdown component, like <ParagraphWithFlair>, but for more complex primitives (e.g. tables) this would mean supplying the tag's content in a completely different format for the vanilla and alternative versions. So?

Well, you can leverage CSS sibling selectors and some hold-your-nose hackery to achieve the same thing without ruining your markup, using a kind of "decorator" style:

.my-table-style {
  table-layout: fixed;
  ...some other styles
}

.auto-layout-table + .my-table-style {
  table-layout: auto;
}
const Table = ({ children }) => <table className="my-table-style">{children}</table>
const AutoLayoutTable = () => <div className="auto-layout-table" />

<MDXProvider components={{ table: Table }}>
  ...
</MDXProvider>

And now, in your MDX:

This table is fixed layout:

| Letter        | Number        | Direction  |
|---------------|---------------|------------|
| A             | 1             | north      |
| B             | 2             | south      |

This table is auto layout:

<AutoLayoutTable />

| Letter        | Number        | Direction  |
|---------------|---------------|------------|
| C             | 3             | east       |
| D             | 4             | west       |

🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment