Skip to content

Instantly share code, notes, and snippets.

@imdongchen
Created September 3, 2019 14:23
Show Gist options
  • Save imdongchen/b592f814a1783d4d938c7f4328bec73a to your computer and use it in GitHub Desktop.
Save imdongchen/b592f814a1783d4d938c7f4328bec73a to your computer and use it in GitHub Desktop.

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

https://gist.github.com/d99ae7890470f188280ede3afee7badd

And then you can define your css: https://gist.github.com/1c014e908817add02a8ce58c8d723b2f

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

https://gist.github.com/59bfe0f3b0a696fb2c51c33855e95066

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.

https://gist.github.com/66e5680be2ba782802f41a57bf305ae0

A problem I have though, is not able to add sx to a custom component https://gist.github.com/721954bfd723c12affb0e814b601a129

But emotion actually lets you do that.

https://gist.github.com/b38168f8e491dc8ca77407a773666399

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

https://gist.github.com/2a22e6081cd2209aa0df805bfa6f119c

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

https://gist.github.com/b535562f96ec77f6151a3569d55226d5

Boom! You have a responsive font! You don’t need any media query to make 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

https://gist.github.com/89463657b29db4fe31874f88d9799433

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 https://gist.github.com/bda046d8188b4be8d74eec3bcdc8a090

You do still have access to the theme, but you end up with more code https://gist.github.com/997b95197f4ee15ae1dae56a155ee372

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.

Style guide driven development in React with Theme UI – Mitch Gavan

#tech/js/css #writing/draft

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