Discovering Theme UI
Tags: webdev, javascript, css, productivity
Published: 2020-05-12 15:03:18

---
title: Discovering Theme UI
published: true
description: Having never worked with Theme UI before this is a retelling of my introduction to it.
tags: webdev, javascript, css, productivity
canonical_url: https://laurieontech.com/posts/discovering-theme-ui/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/8s158dau6idz983v6ls2.png
---

*Originally posted on [laurieontech.dev](https://laurieontech.com/posts/discovering-theme-ui/)*

One of my first challenges in my new role has been to make changes to [gatsby-plugin-theme-ui](https://github.com/system-ui/theme-ui/tree/master/packages/gatsby-plugin-theme-ui). As it turns out, it's a pretty sparse plugin, more of a passthrough than anything.

So, how hard could adding functionality be? 

As it turns out, quite difficult if you've never used [Theme UI](https://theme-ui.com/) in your life! I consider myself a bit of a global styles girl. My closest experience with CSS-in-JS is the way Vue does scoped styles. Which is to say, not really close at all.

But over the past few weeks I've learned quite a bit and thought I'd share it with you all.

## A "theme"

Theme UI works off of a "theme". I know, only slightly confusing since I work on [Gatsby themes](https://www.gatsbyjs.org/docs/themes/) 😅.

 In this case a theme is a JSON object that specifies styling in a number of different ways. You can checkout the [base preset](https://github.com/system-ui/theme-ui/tree/master/packages/gatsby-plugin-theme-ui) for an example of what I mean.

A theme can include various things. The most common is `theme.colors` that defines a series of colors such as `primary`, `background`, etc. 

Themes can also specify typography with `fonts`, `fontSizes`, `lineHeights` and more.

The part of themes I spent a lot of time digging into was `theme.styles`. Much of what gets included in styles feels very familiar to global CSS people like me. You can assign styling for specific HTML tags such as `h1`, `p`, etc. 

When I first started working with the `theme.styles` object I assumed it was applying the styling to the `h1` tags in my site, but it didn't appear to be! I was missing something pretty important to understanding Theme UI.

## MDX

Theme UI was designed in large part to support styling MDX files. Seems natural that Gatsby uses it once you realize this! 

So, as it turns out, my `h1` tags do automatically receive my styles. However, it's only the `h1` tags that are generated from MDX.

```md
# Like this!
```

`h1`'s in my JavaScript files have to do something else. But I'll get back to that in a second.

## pre

Once I realized that `theme.styles` is for MDX styling I started to understand the internal objects a lot better. One of those objects is `theme.styles.pre`. I've been playing around with `theme.styles.pre` quite a bit lately, and for good reason. When shadowing themes in Gatsby, code snippets in MDX get wrapped by a Prism component, like this.

```jsx
import Prism from "@theme-ui/prism"

export default {
  pre: props => props.children,
  code: Prism,
}
```

When this happens, the `Prism` component uses `prism-react-renderer` to tokenize code snippets and create `<span>` elements with class names. This allows Theme UI to target those class names with styles found in the `theme.styles.pre` object.

Which means I can do something like this:
```js
styles: {
    pre: {
        ".variable": {
        color: `#6F0DAB`,
        },
    }
}
```

Pretty cool stuff! Plus, it means I can take advantage of a number of [prism presets](https://github.com/system-ui/theme-ui/tree/master/packages/prism/presets) Theme UI has available in its repo.

## sx prop

Once I understood that `theme.styles` was for MDX, the `sx` prop made a lot more sense. `sx` allows you to make use of your Theme UI styles inside JSX. This can be inline styles, or reference your `theme` object directly.

```jsx
/** @jsx jsx */
import { jsx } from 'theme-ui'

<div
sx={{
      color: 'primary',
      bg: '#FFC0CB',
    }}
>
    Let's test this out!
</div>
```
Note the pragma up top! That's essential in order to leverage this feature.

## Theme composition

One of the most interesting pieces of using Theme UI is the way styles compose. For example, when leveraging Gatsby themes, local styles perform a deep merge with whatever the theme sets. This allows you to make small changes without overriding everything.

## What's Next?
As it turns out, `gatsby-plugin-theme-ui` can do more than it's doing right now. Make it easier to use the theme and prism presets that are available. Make it simpler to share those between projects. 

Excited to finish up some new functionality and see what amazing things the community does with it. Theme UI is incredibly powerful, I might even give up my global styles 😜.