Themes
Use an abstraction layer such as react-with-styles that enables theming. react-with-styles gives us things like
withStyles()
,ThemedStyleSheet
, andcss()
which are used in some of the examples in this document.Why? It is useful to have a set of shared variables for styling your components. Using an abstraction layer makes this more convenient. Additionally, this can help prevent your components from being tightly coupled to any particular underlying implementation, which gives you more freedom.
Define colors only in themes.
// bad
export default withStyles(() => ({
chuckNorris: {
color: '#bada55',
},
}))(MyComponent);
// good
export default withStyles(({ color }) => ({
chuckNorris: {
color: color.badass,
},
}))(MyComponent);
Define fonts only in themes.
// bad
export default withStyles(() => ({
towerOfPisa: {
fontStyle: 'italic',
},
}))(MyComponent);
// good
export default withStyles(({ font }) => ({
towerOfPisa: {
fontStyle: font.italic,
},
}))(MyComponent);
Define fonts as sets of related styles.
// bad
export default withStyles(() => ({
towerOfPisa: {
fontFamily: 'Italiana, "Times New Roman", serif',
fontSize: '2em',
fontStyle: 'italic',
lineHeight: 1.5,
},
}))(MyComponent);
// good
export default withStyles(({ font }) => ({
towerOfPisa: {
...font.italian,
},
}))(MyComponent);
Define base grid units in theme (either as a value or a function that takes a multiplier).
// bad
export default withStyles(() => ({
rip: {
bottom: '-6912px', // 6 feet
},
}))(MyComponent);
// good
export default withStyles(({ units }) => ({
rip: {
bottom: units(864), // 6 feet, assuming our unit is 8px
},
}))(MyComponent);
// good
export default withStyles(({ unit }) => ({
rip: {
bottom: 864 * unit, // 6 feet, assuming our unit is 8px
},
}))(MyComponent);
Define media queries only in themes.
```js
// bad
export default withStyles(() => ({
container: {width: '100%',
'@media (max-width: 1047px)': {
width: '50%',
},
},
}))(MyComponent);// good
export default withStyles(({ breakpoint }) => ({
container: {width: '100%',
[breakpoint.medium]: {
width: '50%',
},
},
}))(MyComponent);
```
Define tricky fallback properties in themes.
Why? Many CSS-in-JavaScript implementations merge style objects together which makes specifying fallbacks for the same property (e.g.
display
) a little tricky. To keep the approach unified, put these fallbacks in the theme.```js
// bad
export default withStyles(() => ({
.muscles {display: 'flex',
},
.muscles_fallback {
'display ': 'table',
},
}))(MyComponent);// good
export default withStyles(({ fallbacks }) => ({
.muscles {display: 'flex',
},
.muscles_fallback {
[fallbacks.display]: 'table',
},
}))(MyComponent);
// good
export default withStyles(({ fallback }) => ({
.muscles {
display: 'flex',
},
.muscles_fallback {
[fallback('display')]: 'table',
},
}))(MyComponent);
```
Create as few custom themes as possible. Many applications may only have one theme.
Namespace custom theme settings under a nested object with a unique and descriptive key.
// bad
ThemedStyleSheet.registerTheme('mySection', {
mySectionPrimaryColor: 'green',
});
// good
ThemedStyleSheet.registerTheme('mySection', {
mySection: {
primaryColor: 'green',
},
});
CSS puns adapted from Saijo George.