- inline styles
- global css (styles in a stylesheet)
- for both: shortcomings (reusability, name collisions)
const BasicTitle = styled.h1`
text-align: center;
text-transform: capitalize;
color: ${(props) => props.special && 'red'}
`
// props are also used
<BasicTitle special>styled component</BasicTitle>
will become (the class avoid name collisions):
<h1 class="sc-pNWdM icjfrD">styled component</h1>
Children are automatically handled by styled components (normally we would have to render them ourselves)
We're not limited to style html tag, but we can style react components as well. In this case we use this feature to extend a Styled Component.
export const HipsterButton = styled(DefaultButton)`
width: 400px;
background: transparent;
color: #645cff;
border: 1px solid #645cff;
`
npm install @mui/material @emotion/react @emotion/styled
npm install @mui/material @mui/styled-engine-sc styled-components
Also material components can be extended:
import styled from 'styled-components'
const ComplexTitle = ({ title }) => {
return (
<Wrapper className="bg-grey">
<h1>{title}</h1>
<div className="underline"></div>
<h2 className="title">random</h2>
</Wrapper>
)
}
const Wrapper = styled.div`
h1 {
text-transform: capitalize;
text-align: center;
}
.underline {
width: 5rem;
height: 0.25rem;
background: var(--primary);
margin: 0 auto;
}
`
export default ComplexTitle
import styled from 'styled-components'
const ComplexTitle = ({ title, className }) => {
return (
<div className={className}>
<h1>{title}</h1>
<div className="underline"></div>
</div>
)
}
const Wrapper = styled(ComplexTitle)`
h1 {
text-transform: capitalize;
text-align: center;
}
.underline {
width: 5rem;
height: 0.25rem;
background: #645cff;
margin: 0 auto;
}
`
export default Wrapper
// bg-grey defined in global index.css
<Wrapper className='bg-grey'>
You can use them without import.
:root {
--primary: #645cff;
}
.underline {
width: 5rem;
height: 0.25rem;
background: var(--primary);
margin: 0 auto;
}
In alternative to CSS Global Variables... Difference: you need explicit import (preferable). But utils.js: interesting to define functions besides values (border example). Instead of value: 1px solid red for the border, we could define a function with 3 params. Very good approach for customizations.
[utils.js]
export const colors = {
secondary: '#ff4455',
}
// we could have also default types (e.g. for the color)
// using an object we can ignore the order of args
export const setupBorder = ({ width, type, color = 'red' }) => {
return `${width}px ${type} ${color}`
}
[AlternativeTitle.js]
import { colors, setupBorder } from '../utils'
.underline {
width: 5rem;
height: 0.25rem;
/* We interpolate the value */
background: ${colors.primary};
margin: 0 auto;
}
.box {
height: 10px;
border: ${setupBorder({ width: 5, type: 'solid', color: 'green'})};
}
Alternative to global CSS variables.
[global-styles.js]
e.g.: Light vs Dark Theme
To make it work we either need Babel or Macro.
This also provides better classnames (more user-friendly)
import styled from 'styled-components/macro'
Groups together multiple CSS declarations. Not related to macro.