Responsive, theme-based style props for building design systems with React
const Box = styled.div(space, fontSize, width, color) render( <Box mb={3} p={[ 3, 4 ]} fontSize={[ 4, 5, 6 ]} color='white' bg='magenta'> Style Props </Box> )
Styled-system is a collection of utility functions that add style props to your React components, which allows for controlling styles based on global theme constants.
To use styled-system, you'll most likely want to use a CSS-in-JS library. These examples use styled-components, but styled-system works with other libraries like emotion and glamorous as well.
npm i styled-system styled-components
Create a new component that uses style functions from styled-system.
To start with, add the color
function to the component's styles argument.
import styled from 'styled-components'
import { color } from 'styled-system'
const Box = styled.div`
${color}
`
export default Box
Now, this component will have two style props available: color
to set foreground color, and bg
to set background color.
<Box color='#fff' bg='tomato'>
Tomato
</Box>
So far, this component can be styled with any valid CSS color.
To create a more consistent UI, create a theme module with a colors
object.
// theme.js
export default {
colors: {
black: '#000e1a',
white: '#fff',
blue: '#007ce0',
navy: '#004175'
}
}
Most CSS-in-JS libraries use a ThemeProvider to handle theming in React.
Import the styled-components ThemeProvider in the root of your application and pass the theme to the theme
prop.
import React from 'react'
import { ThemeProvider } from 'styled-components'
import theme from './theme'
const App = props => (
<ThemeProvider theme={theme}>
{/* application elements */}
</ThemeProvider>
)
export default App
With the ThemeProvider, the Box component now has access to the colors defined in the theme object.
<Box color='black' bg='blue'>
Blue Box
</Box>
Styled-system will attempt to find a value based on keys in the theme and fallback to the raw value if it's not defined in the theme.
// uses the CSS color keyword `tomato` since it's not defined in the theme
<Box bg='tomato' />
To make the Box component a little more useful, add a few more styled-system functions to handle layout styles.
import styled from 'styled-components'
import { color, space, width } from 'styled-system'
const Box = styled.div`
${space}
${width}
${color}
`
// prop types can also be added from the style functions
Box.propTypes = {
...space.propTypes,
...width.propTypes,
...color.propTypes
}
Box.displayName = 'Box'
export default Box
The space
function adds margin and padding props.
The margin and padding props use a shorthand syntax, similar to
Basscss, Tachyons, and Bootstrap.
m
marginmt
margin-topmr
margin-rightmb
margin-bottomml
margin-leftmx
margin-left and margin-rightmy
margin-top and margin-bottomp
paddingpt
padding-toppr
padding-rightpb
padding-bottompl
padding-leftpx
padding-left and padding-rightpy
padding-top and padding-bottomTo set a consistent white-space scale, add a space
array to your theme.
Use numbers to set pixel values, or use strings for other CSS units such as rem
.
// theme.js
export default {
space: [
0, 4, 8, 16, 32, 64, 128, 256, 512
]
}
All spacing props accept numbers, strings, or arrays as values, where:
space
array are values from the space
array defined in themespace
array are converted to pixels'auto'
or '2em'
)The width
function adds a single width
prop for setting responsive width styles.
The width
prop accepts number, string, or array values, where:
1/2
becomes '50%'
)'50vw'
or '30em'
)All styled-system functions accept arrays as values to set styles responsively using a mobile-first approach.
<Box
width={[
1, // 100% below the smallest breakpoint
1/2, // 50% from the next breakpoint and up
1/4 // 25% from the next breakpoint and up
]}
/>
// responsive margin
<Text m={[ 0, 1, 2 ]} />
// responsive padding
<Text p={[ 2, 3, 4 ]} />
// responsive font-size
<Text fontSize={[ 3, 4, 5 ]} />
Alternatively if you define your theme breakpoints as an object
you can use the following syntax:
<Box
width={{
sm: 1,
md: 1/2,
lg: 1/4
}}
>
</Box>
Read the Responsive Styles docs for more information.
Read more about how to use Styled System to build flexible design systems in the docs:
MIT License | GitHub | npm | Made by Jxnblk