Styled Components

박상준·2022년 8월 10일
0

React

목록 보기
3/6
post-thumbnail

기존 CSS 적용 방법

  1. global css
    ./style.css와 같이 모두에게 적용되는 css파일을 사용하는 방식
  2. direct 방식
    해당 html에 직접 style을 입력하는 방식
  3. module css
    각각의 파일에 module css를 생성하여 적용하는 방식. 현재로서는 가장 합리적으로 보이는?
    왜냐하면 className을 사용하면 render했을 때 클래스 이름을 랜덤으로 만들어 주기 때문에 겹치는 일이 생기지 않음.

하지만 styled-components가 등장하면 어떨까?!

doc
https://styled-components.com/docs

설치
npm i styled-components

기본 사용 방법

import styled from 'styled-components';

const Father = styled.div`
  display: flex;
`;
const BoxOne = styled.div`
  background-color: teal;
  width: 100px;
  height: 100px;
`;

const BoxTwo = styled.div`
  background-color: tomato;
  width: 100px;
  height: 100px;
`;

const Text = styled.h1`
  color: white;
`;

function App() {
  return (
    <Father>
      <BoxOne>
        <Text>HEllo</Text>
      </BoxOne>
      <BoxTwo></BoxTwo>
    </Father>
  );
}

export default App;

백틱 사이에 css를 넣어준다.

시멘틱 태그인 것처럼 사용할 수 있기 때문에 가독성이 훨씬 좋다. html구조를 알아보기 좋고, css스타일을 그대로 사용할 수 있어서 편리해보인다. 심지어 중복을 방지하기 위한 해결방법 또한 마련되어 있다. 이는 props를 통해 가능하다.

확장하기

props

const Box = styled.div`
  background-color: ${(props) => props.bgColor};
  width: 100px;
  height: 100px;
`;

${}를 사용하여 props를 받아온다.

Extending

const Box = styled.div`
  background-color: ${(props) => props.bgColor};
  width: 100px;
  height: 100px;
`;

const Circle = styled(Box)`
  //Box의 속성들을 기본적으로 가지고 있다.
  //추가로 아래와 같이 속성을 더해줄 수 있다.
  border-radius: 50px;
  
`;

만들어둔 styled를 사용하여 속성을 그대로 가져오고 추가할 내용만 더할 수 있다. awsome!

as

속성을 더 추가하진 않고 태그만 변경하고 싶을 때는 as를 사용한다.

import styled from 'styled-components';

const Father = styled.div`
  display: flex;
`;

const Btn = styled.button`
  background-color: tomato;
  color: white;
  border: 0;
  border-radius: 15px;
`;

function App() {
  return (
    <Father>
      <Btn>Log in</Btn>
      <Btn
        as="a"
href="https://github.com/iteach12/react_master"
        target="_blank"
      >
        Github
      </Btn>
    </Father>
  );
}

export default App;

attrs

html 속성을 바로 넣어주기 위해서 attrs를 사용한다.

const Input = styled.input.attrs({ required: true })`
  background-color: tomato;
`;

animation

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

const rotateAnimation = keyframes`
  0% {
    transform:rotate(0deg);
    border-radius:0px;
  }
  50% {
    transform:rotate(360deg);
    border-radius:100px;
  }

  100%{
    transform:rotate(0deg);
    border-radius:0px;
  }
`;

const Box = styled.div`
  background-color: tomato;
  width: 200px;
  height: 200px;
  animation: ${rotateAnimation} 0.2s linear infinite;
`;

html 태그 직접 사용하기

styled-components 안에 직접 html 태그를 사용할 수 있다. 모든 컴포넌트를 styled로 하지 않을테니. 일반 태그도 쉽게 삽입할 수 있다.

const Box = styled.div`
  background-color: tomato;
  width: 200px;
  height: 200px;
  animation: ${rotateAnimation} 1s linear infinite;
  display: flex;
  justify-content: center;
  align-items: center;
  span {
    font-size: 30px;
    transition: all ease-in 0.2s;
    &:hover {
      font-size: 45px;
    }
  }
`;

function App() {
  return (
    <Wrapper>
      <Box>
        <span>😚</span>
      </Box>
    </Wrapper>
  );
}

특히 &:hover와 같은 방식으로 가상선택자를 넣어줄 수도 있다. 여기서 &기호는 자기 자신을 의미한다.

span {
    &:hover {
      font-size: 45px;
    }
  }

span:hover {
    font-size: 45px;    
  }

위와 아래는 동일한 코드이다.

styled-components 안에 styled-components 넣고 타겟팅하기

styled-components안에 태그가 아닌 styled-components를 직접 넣을 수도 있다. 이 때는 태그 이름 대신 ${components이름}을 사용하면 된다.

const Emoji = styled.span`
  font-size: 30px;
  transition: all ease-in 0.2s;
`;

const Box = styled.div`
  background-color: tomato;
  width: 200px;
  height: 200px;
  animation: ${rotateAnimation} 1s linear infinite;
  display: flex;
  justify-content: center;
  align-items: center;
  ${Emoji} {
    &:hover {
      font-size: 45px;
    }
  }
`;

function App() {
  return (
    <Wrapper>
      <Box>
        <Emoji>😚</Emoji>
      </Box>
      <Emoji>😚</Emoji>
    </Wrapper>
  );
}

<Box> 바깥에 있는 <Emoji>는 hover가 적용되지 않는다. hover가 적용되는 <Emoji><Box>엘리먼트 안에 있는 <Emoji>뿐이다.

theme

lightMode, darkMode를 쉽게 변경할 때 사용하면 좋다. 물론, 다양한 theme을 적용하기 위한 것이겠으나. 그럴 일이 많을런지..?


//App.js
const Wrapper = styled.div`
  display: flex;
  width: 100vw;
  height: 100vh;
  justify-content: center;
  align-items: center;
  background-color:${(props) => props.theme.backgroundColor}
`;

//index.js
const darkTheme = {
  textColor:"whitesmoke",
  backgroundColor:"#111",
}
const lightTheme = {
  textColor:"#111",
  backgroundColor: "whitesmoke",
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(

  <React.StrictMode>
    <ThemeProvider theme={darkTheme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>
);

prop을 불러와서 사용하는 것과 동일하다. 단, darkTheme과 lightTheme을 가지고 다크모드 라이트모드를 구현한다면 두 객체의 구조가 동일해야 한다. 그래야 컴포넌트에서 변경할 일이 없다. 동일한 객체를 생성해두고 theme에 적용하는 것만으로 전체 컴포넌트를 관리한다.

profile
Just do it

0개의 댓글