티스토리 뷰

npm 설치

npm install --save styled-components

 

import

import styled from 'styled-components'

 

vscode 익스텐션 설치

  • vscode-styled-components (코드 컬러 색상)
  • styled-components-snippets (코드 스니펫)

 

파일분리

스타일 컴포넌트 코드와 리액트 컴포넌트 코드가 한 파일에 같이 있어서 길어진다면 파일 분리를 할 수도 있다.

// Components.styled.js
import styled from 'styled-components';

export StyledDiv = styled.div`
  background-color: red;
`
// Components.js
import * S from './Components.styled.js';

...

const Components = () => {
  return <S.StyledDiv>hi</S.StyledDiv>
};

 

이렇게 사용할 수 도 있다.

// Components.js
import { StyledDiv } from './Components.styled.js';

...

const Components = () => {
  return <StyledDiv>hi</StyledDiv>
};

그런데 리액트 컴포넌트와 헷갈릴 수도 있을 것 같아서 전자가 더 나은 방법 같다.

 

Styled Components 사용하기

html 태그 스타일해서 사용하기

// const 변수명 = styled.htmlTag``

const StyledButton = styled.button`
  color: white;
  background-color: black;
`
...

<StyledButton>button</StyledButton>

또는

// const 변수명 = styled('htmlTag')``

const StyledButton = styled('button')`
  color: white;
  background-color: black;
`
...
<StyledButton>button</StyledButton>

 

위 방법은 라이브러리로 가져온 컴포넌트 스타일링을 할 때도 사용 가능하다.

import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import styled from 'styled-components';

const StyledDatePicker = styled(DatePicker)`
  width: 100%;
  padding: 10px;
  background-color: #00000000;
  border: none;
  color: ${({ theme }) => theme.colors.text};
  font-size: 18px;
  font-weight: 400;
  cursor: pointer;

  &:focus {
    outline: none;
  }
`;

const Calendar = ({ firstShow, setFirstShow, secondShow, setSecondShow }) => {
  return (
    <>
      <StyledDatePicker
        selected={startDate}
        onChange={(date) => setStartDate(date)}
        onFocus={() => {
          setFirstShow(true);
          setSecondShow(false);
        }}
        selectsStart
        startDate={startDate}
        endDate={endDate}
        minDate={new Date()}
        open={firstShow}
        disabledKeyboardNavigation
        dateFormat='yy년 M월 d일'
      />
    </>
  );
};

export default Calendar;

 

가상선택자도 Sass처럼 사용하면 된다.

const StyledButton = styled.button`
  color: white;
  background-color: black;
  &:hover {
    background-color: red;
  }
`

 

Nesting

Sass처럼 네스팅도 가능하고 리액트 네이티브에서도 사용할 수 있다. 굳이 불필요하게 모든 태그를 다 스타일드 컴포넌트화 할 필요는 없다.

import styled from 'styled-components';

const Main = styled.main`
  background-color: red;

  .title {
    font-weight: 700;
  }
  .content {
    font-size: 10px;
  }
`;

const Component = () => {
  return (
    <Main>
      <div>
        <h1 className='title'>hi</h1>
        <p className='content'>I'm bong!</p>
      </div>
    </Main>
  );
};

export default Component;

 

스타일드 컴포넌트를 자식요소로 넣어서 스타일링 하고 싶다면 스타일드 컴포넌트를 변수처럼 사용하면 된다.

import styled from 'styled-components';

const Card = styled.div`
  color: blue;
`
const Main = styled.main`
  background-color: red;
  
  .title {
    font-weight: 700;
  }
  .content {
    font-size: 10px;
  }
  
  ${Card} {
    background-color: yellow;
  }
`;


const Component = () => {
  return (
    <Main>
      <div>
        <h1 className='title'>hi</h1>
        <p className='content'>I'm bong!</p>
      </div>
      <Card />
    </Main>
  );
};

export default Component;

 

스타일드 컴포넌트에서는 props를 이용해서 스타일링을 해줄 수 있는데 props를 이용하려는 태그가 스타일드 컴포넌트여야 사용할 수 있는 것 같다. 이런식으로 스타일드 컴포넌트를 선언하고 그 컴포넌트에 props를 넘겨주면 props를 이용해서 스타일링 해줄 수 있다.

props는 ${(props)=>props.설정한프롭스} 이런식으로 props를 사용할 수 있다. props.selected는 구조분해 할 수 있고 왜인지 모르겠지만 에러가 발생한다면 ()로 감싸주면 해결이 됐다.

import styled from 'styled-components';

const Card = styled.div`
  color: blue;
`
const Main = styled.main`
  background-color: red;
  
  .title {
    font-weight: 700;
  }
  .content {
    font-size: 10px;
  }
  
  ${Card} {
    background-color:${({selected})=>(selected ? 'black' : 'white')};
  }
`;


const Component = ({selected}) => {
  return (
    <Main>
      <div>
        <h1 className='title'>hi</h1>
        <p className='content'>I'm bong!</p>
      </div>
      <Card selected={selected}/>
    </Main>
  );
};

export default Component;

 

이렇게 props를 이용해 배경화면 url도 넣을 수 있다.

 const DashboardContent = styled.div`
  background: url(${props => props.background}) no-repeat top center;
 `

 

inject global

css 초기화가 가능하다.

import styled, { injectGlobal } from 'styled-components'

injectGlobal`
  body {
    padding: 0;
    margin: 0;
  }
`

 

테마사용하기

디자이너와 협업해서 메인컬러, 서브컬러같은 공통적으로 사용해야하는 색상같은 경우 테마를 만들어서 사용할 수 있다.

// theme.js
const theme = {
  primaryColor: "#3498db",
  subColor: "#34495e"
}

export default theme;

 

아까 만든 theme을 import하고 themeProvider를 import하고 태그 전체를 감싸주면 된다. themeProvider는 항상 theme을 갖기 때문에 속성으로 넣어주면 된다.

import styled, { themeProvider } from 'styled-components'
import theme from './theme'

const App = () => {
  return (
    <themeProvider theme={theme}>
      <input />
      <button />
    </themeProvider>
  )
}

 

그리고 해당 속성을 가져다가 쓰면 된다. depth가 깊어도 theme은 전체 컴포넌트에서 적용 가능하다. App.js에서 넣어줬다면 하위 컴포넌트에서는 넣어주지 않아도 된다.

import styled, { themeProvider } from 'styled-components'
import theme from './theme'


const StyledButton = styled.button`
  color: white;
  background-color: ${props => props.theme.primaryColor};
`

const App = () => {
  return (
    <themeProvider theme={theme}>
      <input />
      <StyledButton>button</StyledButton>
    </themeProvider>
  )
}

 

css 속성 확장해서 재사용하기

다른 태그에 있던 스타일링을 가져다 태그를 변경해서 재사용할 수도 있다.

const StyledButton = styled.button`
  color: white;
  background-color: black;
  &:hover {
    background-color: red;
  }
  background-color: ${props => props.danger ? 'orange' : 'black'};
`

const StyledAnchor = StyledButton.withComponent('a').extend`
  text-decoration: none;
`
...
<StyledAnchor href="https://google.com">Google</StyledAnchor>

 

이미 만들어둔 스타일드 컴포넌트를 또 상속 받을 수도 있다.

const BasicText = styled.p`
    color: #000;
    font-size: 14px;
    margin: 10px;
    padding: 10px;
`;

const BoldText = styled(BasicText)`
    font-weight: 700;
`;

 

keyframes

import styled, { keyframes } from 'styled-components'

const rotation = keyframes`
  from{
    transform: rotate(0deg);
  }
  to{
    transform: rotate(360deg);
  }
`

const StyledButton = styled.button`
  color: white;
  background-color: black;
  &:hover {
    background-color: red;
  }
  background-color: ${props => props.danger ? 'orange' : 'black'};
  ${props => {
    if(props.danger) {
      return `animation ${rotation} 2s linear`
    }
  }
  }
`
...
<StyledButton danger>button</StyledButton>

 

또 props를 이용할 수도 있다.

import styled, { keyframes } from 'styled-components'

const rotation = keyframes`
  from{
    transform: rotate(0deg);
  }
  to{
    transform: rotate(360deg);
  }
`

const StyledButton = styled.button`
  color: white;
  background-color: black;
  &:hover {
    background-color: red;
  }
  background-color: ${props => props.danger ? 'orange' : 'black'};
  ${props => {
    if(props.danger) {
      return `animation ${rotation} {rotationTime}s linear`
    }
  }
  }
`
...
<StyledButton danger rotationTime={5}>button</StyledButton>

 

속성(Attributes) 넣어주기

attrs에 객체를 넣어주면 된다.

const StyledInput = styled.input.attrs({
  required: true
})`
  border-radius: 5px
`

이렇게하면 해당 컴포넌트 속성에 required가 들어간다. 그리고 그 뒤에 ``을 사용해서 스타일링을 해주면 된다.

 

mixin

mixin는 css 그룹이다. 자주 사용할 css 속성들을 묶어두고 사용할 수 있다. css를 import하고 mixin을 만들어서 ${}에 변수명을 넣어서 사용하면 된다.

import styled, { css } from 'styled-components'

const CssMixin = css`
  background-color: blue;
  color: white;
`

const StyledInput = styled.input.attrs({
  required: true
})`
  border-radius: 5px
  ${CssMixin}
`

 

반응형 브레이크 포인트도 mixin으로 사용할 수 있다.

// theme.js 와 같은 공통 파일에 넣으면 된다.
export const browserWidth = {
  xs: "549px",
  sm: "550px",
  md: "1023px",
};

export const reponsive = {
  sm: `screen and (max-width: ${browserWidth.xs})`,
  md: `screen and (min-width: ${browserWidth.sm}) and (max-width: ${browserWidth.md})`,
  lg: `screen and (max-width: ${browserWidth.md})`,
};

 

// 사용
const Div = styled.div`
  @media ${({ theme }) => theme.reponsive.sm} {
    flex-direction: column;
  }

  width: 100vw;
  height: 100vh;
  background: wheat;
  display: flex;
  align-items: center;
  justify-content: center;
`;
728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함