Styled Component

Styled Component

Styled Component

  • CSS 작업할 때 SASS, Webpack에 시간을 엄청 소비한 적
  • CSS 파일, 클래스명을 만들면서 왔다갔다 한 적
  • 리액트 네이티브 앱, 리액트 웹 어플리케이션이 있는데 CSS 코드를 공유하고 싶었던 적
이런 적이 있었을 것이다.
따라서,
  • SASS 코드를 SASS 설치 없이 사용
  • CSS 파일 없이 CSS 작업 및, 클래스없이 사용
  • 리액트 네이티브 앱과 공유
이렇게 할 수 있도록 한 게 Styled Components다.

In the past

class  Buttons  extends  Component {
 render() {
  return (
   <Button  danger  />
   <Button>
  )
 }
}

const Button = ({  danger  }) => {
 <button  className={danger ? "button button-danger" : "button button-success"}
>
  Test
 </button>
}

export default Buttons;
.button {
 border: 1px  solid  white;
}

.button:active,
.button:focus {
 outline: nonel;
}

.button-success {
 background-color: green;
}

.button-danger {
 background-color: red;
}

Styled Components

import  styled  from  'styled-components';

class  Buttons  extends  Component {
 render() {
  return (
   <Button  danger  />
   <Button>
  )
 }
}

// style뒤에 button은 element 요소
const Button = styled.button`
border: 1px solid white; // css 속성 추가
&:active,
&:focus {
outline: none;
}
`;

export default Buttons;
만약에 버튼들을 컨테이너로 감싸고 싶다면…

class  Buttons  extends  Component {
 render() {
  return (
   <Container>
    <Button  danger  />
    <Button>
   </Container>
  )
 }
}

const Container = styled.div`
 width: 100%;
 height: 100%;
 background-color: yellow'
`;

const Button = styled.button`
 border: 1px solid white;
 &:active,
 &:focus {
  outline: none;
 }
 // props를 넘겨주어 기존에 button-success, button-danger처럼 보이게 할 수 있다.
 background-color: ${props  =>  props.danger ? "red" : "green"}
`;

injectGlobal and Extend

injectGlobal

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

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

Extend

버튼을 Anchor, Link로 사용하고 싶은 경우
render() {
 return (
  <Button>Hello</Button>
  <Anchor  href="www.naver.com">Go to naver</Anchor>
 )
}

// 버튼에 쓰였던 css를 상속받아 추가할 수 있다.
const  Anchor = Button.withComponent("a").extend`
 text-decoration: none;
`;

Animations

<Button  time={2}>Hello</Button>

const  Button = styled.button`
 ...
 ${props  => {
  if (props.danger) {
   return  `animation: ${rotation}  ${props.time}s linear infinite`;
  }
 }}
`;

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

Extra Attributes and Mixins

Set Attributes

// attribute 추가
const  Input = styled.input.attr({
 required:  true
})`
 border-radius: 5px;
`;

class  Container  extends  Component {
 render() {
  return (
   <Input  placeholder="hello"  />
  )
 }
}

Mixin

mixin: css 그룹(여러 곳에서 사용하고 싶기 때문에)
import  styled, { css } from  'styled-components';

// css block(다른 곳에서도 사용해야 할 속성등)
// 다른 파일에 추가하면 다른 컴포넌트에서도 사용 가능하다.
const  awesomeCard = css`
 padding: 10px;
 border-radius: 50px;
`;

const  Input = styled.button`
 ...

 ${awesomeCard}; // 추가해준다.
`;

Theming

모든 컴포넌트(레벨)에 적용할 수 있다.
// theme.js
const  theme = {
 mainColor:  "#3498db",
 dangerColor:  "#e74c3d",
 successColor:  "#2eee71"
};

export  default  theme;

// App.js
import  styled, { ThemeProvicer } from  'styled-components';

const  Card = styled.div`
 background-color: red;
`;

const  Button = styled.button`
 background-color: ${props  =>  props.theme.successColor}
`;

return(
 <ThemeProvider  theme={theme}>
  <Container>
   <Form  />
  </Container>
 </ThemeProvider>
)

const  Form = () => {<Card><Button>Test</Button></Card>}

Nesting

const  Container = styled.div`
 ...
 // Container안의 Card 자식들 모두 아래의 속성 적용
 ${Card} {
  background-color: blue;
 }
 ${Card}:last-child {
  background-color: grey;
 }
`;

CSS on React Native

현재 프로젝트 안에 styled-native 폴더가 새로 생김
yarn global upgrade exp
react-native는 아직 공부 전이라서 여기까지만 정리

참고

styled-components

댓글

가장 많이 본 글