Hướng dẫn Styled Components cơ bản
styled-components xây dựng với mục tiêu giữ cho các styles của component nằm chính trong component đó
1. Cài đặt
npm install styled-components
Cách sử dụng
import styled from 'styled-components'
2. Tạo component với các thẻ html cơ bản
import styled from 'styled-components'
// Tạo component Title render ra thẻ h1
const StyledTitle = styled.h1`
color: red;
`
export default function App() {
return <StyledTitle>Hello World!</StyledTitle>
}
Output ra HTML với class được sinh ra ngẫu nhiên không bị trùng nhau
<h1 class="sc-gsnTZi fZzjcr">Hello world</h1>
Demo: https://codesandbox.io/p/devbox/optimistic-fire-220lyc?file=%2Fsrc%2FApp.jsx%3A7%2C1
3. Props
Ta có thể truyền props vào các styled components như sau
import styled from 'styled-components'
// Tạo component Button với các styles như sau
const StyledButton = styled.button`
background: ${props => props.primary ? 'red' : 'white'};
`
export default function App() {
return (
<>
<StyledButton>Normal Button</StyledButton>
<StyledButton primary>Primary Button</StyledButton>
</>
)
}
Demo: https://codesandbox.io/s/styled-components-props-zh1092?file=/src/App.js
4. Extending Styles
Kế thừa styles từ component khác
import styled from 'styled-components'
// Tạo một base component Button
const Button = styled.button`
color: blue;
font-size: 1em;
`
// Tạo một RedButton kế thừa những styles
// từ base Button phía trên, ghi đè hoặc thêm mới styles
const RedButton = styled(Button)`
color: red;
border-color: red;
`
export default function App() {
return (
<>
<Button>Normal Button</Button>
<RedButton>Red Button</RedButton>
</>
)
}
Demo: https://codesandbox.io/s/styled-components-extend-style-q6tq0c?file=/src/App.js
5. Styles với các thư viện khác
Kế thừa cả những component của bên thứ 3
5-1. React router dom
import { BrowserRouter, Link } from 'react-router-dom'
import styled from 'styled-components'
// Thực hiện việc import Link từ react-router-dom
// Tạo một component mới kế thừa từ Link component
const StyledLink = styled(Link)`
color: red;
font-weight: bold;
`
export default function App() {
return (
<BrowserRouter>
<Link to="/about">Link chưa được CSS</Link>
<br />
<StyledLink to="/about">Sau khi CSS</StyledLink>
</BrowserRouter>
)
}
Demo: https://codesandbox.io/s/styled-component-react-router-dom-28oebw?file=/src/App.js
5-2. Material MUI
Cài đặt thư viện MUI
npm install @mui/material @emotion/react @emotion/styled @mui/styled-engine-sc
import Typography from '@mui/material/Typography'
import styled from 'styled-components'
const StyledTypography = styled(Typography)`
color: #333333;
`
export default function App() {
return (
<>
<Typography variant="h3" gutterBottom>
H3 - MUI
</Typography>
<StyledTypography variant="h3" gutterBottom>
H3 - styled components
</StyledTypography>
</>
)
}
Demo: https://codesandbox.io/s/styled-component-material-ui-r3gplj?file=/src/App.js
5-3. Ant design
Cài đặt thư viện Antd
npm install antd
import 'antd/dist/antd.css'
import { Typography } from 'antd'
import styled from 'styled-components'
const { Title } = Typography
const StyledTitle = styled(Title)`
&.ant-typography { color: red; }
/* Cách khác */
/* &&& { color: red; } */
`
export default function App() {
return (
<>
<Title level={2}>H2 - Antd</Title>
<StyledTitle level={2}>
H2 - styled components
</StyledTitle>
</>
)
}
Demo: https://codesandbox.io/s/styled-component-antd-j8j2q1?file=/src/App.js
6. custom tagName
Với styled-components
bạn cũng có thể thay đổi tag name so với định nghĩa ban đầu.
import styled from 'styled-components'
const StyledDiv = styled.div`
color: red;
font-size: 2rem;
`
export default function App() {
return (
// Thay đổi tag div => section
<StyledDiv as="section">Hello World!</StyledDiv>
);
}
Demo: https://codesandbox.io/s/styled-component-change-html-1fg2cl?file=/src/App.js
7. CSS Selector
Trong styled-components
có thể sử dụng những CSS selector cơ bản như > , + , ~ ...
và sử dụng Nesting như SCSS
import styled from 'styled-components'
const StyledDiv = styled.div`
color: blue;
/* div khi được hover */
&:hover { color: red; }
/* div nằm phía sau không trực tiếp của div */
& ~ & { background: tomato; }
/* div nằm phía sau trực tiếp của div */
& + & { background: lime; }
/* div có class là something */
&.something { background: orange; }
/* div có class .something nằm bên trong */
& .something { background: red; }
/* div nằm bên trong html nào đó có class .something-else */
.something-else & { background: cyan; }
`
export default function App() {
return (
<>
<StyledDiv>Hello world!</StyledDiv>
<StyledDiv>How ya doing?</StyledDiv>
<StyledDiv className="something">The sun is shining...</StyledDiv>
<div>Pretty nice day today.</div>
<StyledDiv>Don't you think?</StyledDiv>
<div className="something-else">
<StyledDiv>Splendid.</StyledDiv>
</div>
</>
)
}
Demo: https://codesandbox.io/s/styled-component-css-selector-x7g98s?file=/src/App.js
8. Responsive
Hoạt động tốt với responsive
import styled from 'styled-components'
const StyledTitle = styled.h1`
background: cyan;
color: black;
@media screen and (min-width: 768px) {
background: tomato;
}
`
export default function App() {
return <StyledTitle>Hello World!</StyledTitle>
}
Demo: https://codesandbox.io/s/styled-component-responsive-n77075?file=/src/App.js
9. Animations
import styled from 'styled-components'
import { keyframes } from 'styled-components'
// Tạo keyframes
const rotate = keyframes`
from { transform: rotate(0deg) }
to { transform: rotate(360deg) }
`
// áp dụng vào animation css
const Rotate = styled.div`
animation: ${rotate} 2s linear infinite;
`
export default function App() {
return <Rotate>Something</Rotate>
}
Demo: https://codesandbox.io/s/styled-component-animation-0ogv50?file=/src/App.js
10. With attribute
Kiểu 1: tạo ra button có type là submit
import styled from 'styled-components'
const StyledSubmitButton = styled.button.attrs({
type: 'submit'
})`
border: none;
padding: 10px;
color: black;
background: violet;
`
export default function App() {
return (
<>
<h1>Hello World</h1>
<StyledSubmitButton>Submit Button</StyledSubmitButton>
</>
)
}
Demo 1: https://codesandbox.io/s/styled-component-attribute1-lsy7yb?file=/src/App.js
Kiểu 2: tạo ra common button, sau đó tạo submit button kế thừa từ button này
import styled from 'styled-components'
const StyledButton = styled.button`
border: none;
padding: 10px;
color: black;
`
const StyledSubmitButton = styled(StyledButton).attrs({
type: 'submit'
})`
background: violet;
`
export default function App() {
return (
<>
<StyledButton>Normal Button</StyledButton>
<StyledSubmitButton>Submit Button</StyledSubmitButton>
</>
)
}
Demo 2: https://codesandbox.io/p/devbox/sad-euler-8pettq?file=%2Fsrc%2FApp.jsx
kiểu 3: attrs
nhận vào function
import styled from 'styled-components'
const StyledButton = styled.button.attrs(props => ({
type: props.type || 'button'
}))`
border: none;
padding: 10px;
color: black;
background: violet;
`
export default function App() {
return (
<>
<StyledButton>Normal Button</StyledButton>
<StyledButton type='submit'>Submit Button</StyledButton>
</>
)
}
Demo 3: https://codesandbox.io/s/styled-component-attribute3-hxs2nl?file=/src/App.js
11. Global style
Tạo ra global styles áp dụng cho toàn bộ dự án
import { createGlobalStyle } from 'styled-components'
const GlobalStyle = createGlobalStyle`
h1 { color: red; }
`
export default function App() {
return (
<>
<GlobalStyle />
<h1>Hello World</h1>
</>
)
}
Demo: https://codesandbox.io/s/styled-component-global-style-8jyog9?file=/src/App.js
12. Styled Theme
Tạo ra theme config để dùng chung
import styled, { ThemeProvider } from 'styled-components'
const styledTheme = {
warning: {
background: '#ffc107',
text: '#000'
},
danger: {
background: '#dc3545',
text: '#fff'
}
}
const StyledWarningButton = styled.button`
color: ${(props) => props.theme.warning.text};
background: ${(props) => props.theme.warning.background};
`
const StyledDangerButton = styled.button`
color: ${(props) => props.theme.danger.text};
background: ${(props) => props.theme.danger.background};
`
export default function App() {
return (
<ThemeProvider theme={styledTheme}>
<StyledWarningButton>Warning Button</StyledWarningButton>
<StyledDangerButton>Danger Button</StyledDangerButton>
</ThemeProvider>
);
}
Demo: https://codesandbox.io/s/styled-component-config-theme-n3ey3k?file=/src/App.js:0-836
All rights reserved