Theme UI: encouraging consistent and responsive styling practices

Dong Chen
5 min readSep 3, 2019
Photo by Randy Fath on Unsplash

CSS is not fun to me personally. But the css-in-js solution provided by tools like emotion and styled-components makes it a lot more fun as I feel I am developing a react component with all props available beyond simply css.

I like both emotion and styled-component. Albeit that they implement in different mechanisms under the hood and thus their size and performance differ, the exposed API and developer experience is very similar. They would be my "go-to" solution for styling a component.

…until I came across Theme UI recently.

Is this yet another css-in-js solution?

Not really. Theme UI is built upon emotion. It does not care about how to enable css in js but relies on emotion to do the hard work. Instead, it provides a high level, opinionated, and purposely constraint API to shape how developers style components.

I have mixed feeling towards Theme UI. I want to share what I like and what I don’t like.

Likes

Constraint based

What distinguishes Theme UI is that it offers a constraint based design system. It allows you to define an array of scales (or reuse such scales defined in other themes) and makes it easy to refer to the value in the scales when you define your css later. For example, in your theme you can have an array of spaces

And then you can define your css:

Here 3 does not mean 3px, but actually the third value in the space scale array. It is basically equal to:

By providing this sweet syntax sugar, it encourages developers to use the style predefined in the theme, which pushes for a consistent UI across app. Such constraint will be especially useful for large team/organization development.

Concise syntax

As you see above, you can put a sx prop to style a component. There you have access to the theme.

A problem I have though, is not able to add sx to a custom component

But emotion actually lets you do that.

Considering Theme UI builds upon emotion, I’m wondering if there is a way to do that in Theme UI. I cannot find anything in its document though.

Responsive style as array

I live this feature most and it is really powerful and beautiful. You can define some breakpoints In your theme

Then you can have any array for your css, whose value corresponds to the screen size defined in the theme breakpoints.

Boom! You have a responsive font! You don’t need any media query to make responsive design! By making responsive styling easy, I believe it will encourage more developers to create responsive design.

Dislikes

Styled component?

What bugs me most is that its limited support of styled components. For example, with emotion, you can create a styled component using @emotion/styled

With Theme UI, you can still use @emotion/styled to create styled components since Theme UI builds upon emotion. However, the scale system is not readily available. That is, you can't write something like

You do still have access to the theme, but you end up with more code

Fixed scale system

As much as I like the constraint based solution, I do have two issues. First, it seems to add extra mental burden while developing because I have to look up the index of the space value first. I have to keep my theme file open when I am styling a component. This problem might get better as I become more used to the design system though.

A bigger issue is the scale system is fixed. But what if you want to change the scale system itself. Since things are referred to with the array index, if you change the array, say insert a new value in the middle of the array, values referred by the index are likely to change. There is one time when I really need a space of 24. But if I added it between 16 and 32, css like { m: 4 } which stands for { margin: 32px } before will become { margin: 24px }. Of course you can always break out from the scale system and put { m: '24px' } directly. This is a caution that the theme, or the design system, should not be changed regularly.

Conclusion

Overall I like the idea of Theme UI, and it is a great example of how to shape developer behavior with tooling. By making the desired practice easier for developers to implement (rather than forbidding them to do otherwise), developers naturally follow the suggested practice while they always have a way to escape. This reminds me of react-testing-library, which shares exactly the same philosophy: it exposes a set of API to encourage desired testing practices (test what end users see but not implementation detail). Similarly, Theme UI exposes a set of API to encourage desired styling practices, that is, consistent and responsive.

--

--

Dong Chen

Web engineer @robinhood; PhD in Human-Computer Interaction