Understanding Theme UI: 4 - Scales

Date published: 21-Jan-2021
3 min read / 800 words
Author: Paul Scanlon

JavaScript
React
Theme UI

In this post i'm going to explain how Theme UI's Theme Scales work. If you're new to Theme UI i'd suggest having a read of the first three posts in this series to bring you up to speed

    1. Understanding Theme UI: 1 - Jsx Pragma
    1. Understanding Theme UI: 2 - Styled component
    1. Understanding Theme UI: 3 - Components

Before we dive in i'm going to pull a statement from the Theme UI homepage and try and draw some comparisons between Theme UI and what we already understand about CSS.

Build themeable design systems based on constraint-based design principles

The bit i'd like to hone in on is where it says "constraint-based". For some having a CSS framework that comes with constraints might be a bad thing, personally for me, it's a really powerful thing.

Theme UI works by "mapping" certain CSS properties to a targeted object within the main theme object, and encourages you to only use values defined in the corresponding scale.

For example using any of the above methods, (Jsx Pragma, Styled or Components) you'll likely need to apply padding to a HTML element. Here's an example.

Src 👇

<Box
sx={{
padding: 4,
}}
>
I'm a Box
</Box>

Output 👇

I'm a Box

Theme 👇

// path-to-theme/index.js
export default {
...
space: [
'0px',
'4px',
'8px',
'16px',
'32px',
'48px',
'64px'
]
}

You'll see in the above "src" that the <Box /> has a CSS property of padding which is assigned a value of 4, but what is 4?

Here's some things it's not

  • 4px
  • 4em
  • 4rem

What 4 relates to is the index in the space array defined in the theme. In this case 4 is "32px" , and the reason this value is stored in the space array is because one of Theme UI's constraints is to map padding to space. The longhand for what this might look like in Object Oriented Programming is theme.space[4]

You can see the full set of scales in the docs which explain where each CSS property looks in the theme to find it's value.

Array Syntax

I've gleaned from various discussions about Theme UI that the array syntax for space can be a little confusing so to throw an alternative method in to the mix, space can also be an object. I suspect Theme UI don't mention this in the docs is because using an object syntax requires you give each key a name... and namings things is hard.

Src 👇

<Box
sx={{
padding: 'lg',
}}
>
I'm a Box
</Box>

Output 👇

I'm a Box

Theme 👇

// path-to-theme/index.js
export default {
...
space: {
none: '0px',
xs: '4px',
sm: '8px',
md: '16px',
lg: '32px',
xl: '48px',
xxl: '64px',
}
}

Object Syntax

In this example padding is given a "string" value of "lg" and if you look in the space object you'll see the lg key has a value of "32px". The longhand for this would be theme.space.lg

The space key names could be anything you want, here's another example (i'm not suggesting you do this by the way)

Src 👇

<Box
sx={{
padding: 'jaguar',
}}
>
I'm a Box
</Box>

Output 👇

I'm a Box

Theme 👇

// path-to-theme/index.js
export default {
...
space: {
none: '0px',
kitten: '4px',
cat: '8px',
cougar: '16px',
jaguar: '32px',
lion: '48px',
tiger: '64px',
}
}

Alt Syntax

As per the previous example padding is given a "string" value of "jaguar" and if you look in the space object you'll see the jaguar key has a value of "32px"

Any value mentioned in the space scale will work in this way, eg, padding-top, margin, grid-gap etc

Moreover any value named in the scales will work in this way. For instance if you wanted to define a background-color for the box you could use backgroundColor: "primary". The CSS property for background-color is mapped to the colors object in the theme, or the longhand would be theme.colors.primary.

These constraints may seem foreign at first when working with Theme UI but in theory CSS is by it's very nature providing you with a set of constraints. For example when you use the display property in CSS you are only able to use values from a constrained set as defined in the CSS spec e.g:

  • inline
  • block
  • flex
  • grid

... and so on.

Theme UI's scales are way to limit or restrict values to a certain set or predetermined values, and why would you need a constrained set of values I hear your cry... well, you don't it's entirely possible to give padding: any value you like, e.g padding: "100px" but the point behind the constraints is to limit the amount of low level thinking you need to do.

If you define a set of values for use around your site or application you'll only ever need to pick from a handful or possibilities. If you don't have these constraints you may find yourself digging around the codebase to find a similar component and try to match whatever hardcoded px value was used, or worse... you'll have to speak with the design team.

So in my opinion constraints are a good thing.

To help you better understand Theme UI's scales i've created an interactive property mapper to help you understand which CSS properties Theme UI will map, and where their respective values will be looked up in the theme object.

    👉👇
    ...

    Not every CSS property is mapped by Theme UI to a scale in the theme object, as mentioned display can be any value defined in the CSS spec.

    In the next post I'll be covering how to use breakpoints so sit tight and i'll be back with examples and explanations for how to make your styles responsive in Theme UI



    If you've enjoyed this post I'd love to hear from you: @PaulieScanlon