Styling
React does not have an opinion about how styles are defined; if in doubt, a good starting point is to define your styles in a separate
*.css
file as usual and refer to them usingclassName
.
Global CSS
- just import some CSS
- no scoping
- have to use BEM
import React, { FC, useState } from 'react'
import './global.css'
import { Slider } from './slider'
export const Global: FC = () => {
const [value, setValue] = useState(100)
return (
<div className="global__wrapper">
<Slider value={value} onChange={setValue} />
<div className="global__circle" style={{ fontSize: `${value * 0.01}em` }}>
awesome circle
</div>
</div>
)
}
export default <Global />
awesome circle
CSS Modules
- just import some CSS
- must be named
*.module.css
- classes automatically scoped, worry free naming
- CSS bundled with component
- short class names in production
- less dead CSS
import React, { FC, useState } from 'react'
import classes from './example.module.css'
import { Slider } from './slider'
export const Module: FC = () => {
const [value, setValue] = useState(100)
return (
<div className={classes.wrapper}>
<Slider value={value} onChange={setValue} />
<div className={classes.circle} style={{ fontSize: `${value * 0.01}em` }}>
awesome circle
</div>
</div>
)
}
export default <Module />
awesome circle
- note that both CSS approaches have to use the
style
prop for dynamic styles
CSS in JS
common pattern in React apps provided by libraries
styled-components
most popular- Automatic critical CSS
- No class name bugs
- Easier deletion of CSS
- Simple dynamic styling
- Painless maintenance
- Automatic vendor prefixing
fantastic for dynamic styling
component fully contained in single file
needs extension for syntax highlighting
import React, { FC, useState } from 'react'
import styled from 'styled-components'
import { Slider } from './slider'
const Wrapper = styled.div`
min-height: 250px;
min-width: 250px;
`
const Circle = styled.div<{ fontSize: number }>`
align-items: center;
background-color: dodgerblue;
border-radius: 99999px;
color: aliceblue;
display: flex;
flex-direction: column;
font-family: Arial, Helvetica, sans-serif;
font-size: ${(props) => props.fontSize}em;
height: 10em;
justify-content: center;
transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
width: 10em;
`
export const Styled: FC = () => {
const [value, setValue] = useState(100)
return (
<Wrapper>
<Slider value={value} onChange={setValue} />
<Circle fontSize={value * 0.01}>awesome circle</Circle>
</Wrapper>
)
}
export default <Styled />
awesome circle
P.S.
- it doesn’t matter which approach you use, but don’t mix them