Style Component

제동현·2023년 2월 6일
0

설치

npm i styled-components를 입력하여 설치한다.

Styled Component

import styled from "styled-components";

사용할때 반드시 import를 해주자

예를 들어 이런 코드가 있다고 해보자.

    <div style={{ display: "flex" }}>
      <div style={{ backgroundColor: "teal", width: 100, height: 100 }}></div>
      <div style={{ backgroundColor: "tomato", width: 100, height: 100 }}></div>
    </div>

이 코드를 Styled Component 로 정리해보자

다음 선언을 할땐

const Father=styled.div``;

styled뒤에 사용하고자하는 태그와 백틱 사이에 css코드를 넣는 형식으로 사용한다.

text에 css를 넣고 싶을땐 다음과 같이 하자

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

styled Component를 사용하면 다음과 같이 정리된다.

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.span`
  color: white;
`;

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

export default App;

<div> 투성이인 이세계에 구원이 있으랴

그런데 위의 코드에서 BoxOne과 BoxTwo는 background-color를 제외하고는 같은 코드다

이를 해결해보자

import styled from "styled-components";

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

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

function App() {
 return (
   <Father>
     <Box bgColor="teal" />
     <Box bgColor="tomato" />
   </Father>
 );
}

export default App;

BoxTwo를 없애고 Box로 통일 시켰다 그다음 컴포넌트에서 색을 따로 지정하고 styled.div 쪽 background-color에서 props로bgColor를 받게 했다.

또 이러한 사용법도 있다.

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

const Circle = styled(Box)`
border-radius:50px
`

위의 Box의 모든 내용을 들고와서 border-radius만 추가하는 형식이다

너무 좋아 이게 바로 styled component의 확장이다.

AS

ASS..가 아니라 As

컴포넌트의 태그를 바꾸고 싶은데 스타일은 바꾸고 싶지 않을때 어떤게 해야할까?

import styled from "styled-components";

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

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

const Link = styled(Btn) ``

function App() {
  return (
    <Father>
      <Btn>Log in</Btn>
    </Father>
  );
}

export default App;

여기 평범함(버튼)이 있다.
근데 다음에 만들 컴포넌트에선 styled를 사용하되 butten 태그를 사용 하고 싶지 않다.

<Btn as="a">Log in</Btn>

짜잔 as를 사용하면 스타일은 사용하면서도 내가 원하는 태그로 지정이 된다.

또 다른 트릭이 있는데 attrs를 이용한 트릭이다.

만약 우리가 <Input>이 쥰내 많이 필요한데 이 input에 required속성을 넣는다고 가정해보자

input마다 다 넣고 있을수는 없자나.

그래서 우리는 styled component를 이용해서 속성을 지정하는 방법을 배우겠다.

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

쥰내 쉽지?

다음은 animation이다.

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

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

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

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


function App() {
  return (
    <Wrapper>
      <Box />

    </Wrapper>
  );
}

export default App;

import로 styled 옆에 {keyframes}를 추가해주고

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

다음과 같이 한다.

gif를 딸만큼의 열정은 없어서 화면은 첨부하지 않겠다.

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

    <Wrapper>
      <Box>
        <span>😊</span>
      </Box>
    </Wrapper>

다음은 셀렉터에 대해서 알아보자

애니메이션 안에 이모지를 넣어봤다. 근데 이 이모지의 크기를 키우고 싶을때 ?

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

컴퍼넌트안에 span이란 target을 설정해서 따로 설정해줄수있따. 으메이징

근데 만약에 니가 span이라는 태그에 의존하고 싶지 않을때 우리는 다른 방법을 사용할 수 있다.

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

이렇게 만약 이렇게되면 return쪽 컴포넌트에서 as로 p를 지정하든 span을 지정하든 상관없다
이미 Emoji라는 컴포넌트가 타겟팅 되고있으니까

마지막으로

Theme에 대해서 배워보고자한다.

Theme라고하면 뭐 여러가지가 있겠지만 여기선 dark/light 모드다.

import React from "react";
import ReactDOM from "react-dom";
import { ThemeProvider } from "styled-components";
import App from "./App";

const darkTheme = {
  textColor: "whitesmoke",
  backgroundColor: "#111",
};

const lightTheme = {
  textColor: "#111",
  backgroundColor: "whitesmoke",
};

ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider theme={darkTheme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

index페이지에 다음과 같이 코드를 작성해준다.

ThemeProvider를 import해 준뒤 다크모드와 라이트모드를 선언해주고 글씨색과 배경색을 지정해 주었다.
App 을 감싸는 ThemeProvider 는 하나의 prop을 받는데 이게 darkTheme와 lightTheme다

다음 app.js로 넘어가서

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

const Title = styled.h1`
  color: ${(props) => props.theme.textColor};
`;

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

function App() {
  return <Wrapper>
    <Title>Hello</Title>
  </Wrapper>;
}

export default App;

앞서 index에서 설정한 theme는
(props)=>props.theme.textColor;{(props) => props.theme.textColor};{(props) => props.theme.backgroundColor};
처럼 컴포넌트로 전달할수도 있다.

0개의 댓글