+1

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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí