So I've been using styled components with theming lately. And I'm wondering a bit about my approach. It might have poor performance, and it might use a theme for more than what it's intended for.
Using the theme
obj for more than just colors
On projects I've done in the past where I've used css modules with scss, I've found it convenient to have lots of common variables to ensure consistency in sizes (margin, padding, font etc) and colors throughout a codebase. Also to be able to easily change them/and or changing themes etc.
So a theme
object might look something like this (example values):
const theme = {
width: {
content: '60vw'
},
spacing: {
sm: '0.25rem',
md: '0.5rem',
lg: '0.75rem',
xl: '1rem'
},
color: {
background: {
primary: 'black',
secondary: 'white',
someOtherColor: 'pink'
},
primary: 'white',
secondary: 'black'
},
font: {
heading: {
sm: '1.4rem',
},
text: {
sm: '0.75rem'
}
...
The attempt is to have all common properties in the same place, and be able to structure it so it's not horrible to get an overview of.
So using the values from the theme above in a component would look something like this:
const MyComponent = styled.p`
color: ${({ theme }) => theme.color.primary};
background: ${({ theme }) => theme.color.background.primary};
`;
This gets pretty tedious to write all the time, and I also feels it adds to much noise, reducing readability.
Q: Is it fine using theme
for sizes etc in addition to colors?
Using a get
helper func instead
Since I wanted a visually cleaner and lower effort way of accessing different nested properties in my theme
obj, I wrote a function I just called get
. Comparing the component above, it looks like this:
const MyComponent = styled.p`
color: ${get('colorPrimary')};
background: ${get('colorBackgroundPrimary')};
`;
get
expects a theme
property to exist on the component props
object, and also a camelCased identifier which is used to look for the value. So, in my opinion it's less noise in the styling, and also easier to type.
Q: Since this is a function, instead of just accessing props on an object, it has to perform some operation to know where to lookup the value. So it'll definitively have a performance hit. But will using a function for purposes like this have an actual noticeable/critical performance hit regarding smooth rendering etc?
Guess it probably depends on the implementation and device..
Anyway I'm liking the approach, it's straight forward to use and readability is not suffering too much.What do you think?
If anyone's interested, I can share the func.
Top comments (1)
Good! =) But maybe already built? ... github.com/styled-system/styled-sy...
The only drawback to theme-get I've found is it doesn't offer any type safety if using with TypeScript.
What I have settled on is to use the styled-components ThemeProvider higher up in the app so that all components get a 'theme' prop, then in individual components:
... wrapping the whole declaration block in the css function is still more boilerplate than I'd like, but now you don't have the verbosity in every reference to 'theme'
there's a lot of discussion on this topic here: github.com/styled-components/style...