Understanding Theme UI: 4 - Scales
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
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>
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>
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>
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.
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