styled-components

Styled Components

logo

이번 포스트는 Styled Compnents 에 대해서 알아보려고 합니다.

Styled Compnents는 나온지는 조금 되었고, 존재는 알았으나 따로 사용해보지 않았다가
theme provider를 사용해야할 계기가 있어 사용하게 되었습니다.

styled-components는 CSS-in-JS 라이브러리 입니다.

  • CSS-in-JS : 자바스크립트 파일 안에서 CSS를 작성하는 형태

이 라이브러리의 큰 장점은 JS or JSX파일 안에 CSS를 작성하기 때문에 따로 css파일을 작성하지 않는것이 장점입니다.
그리고 스타일을 입력할 떄 Tagged 템플릿 리터럴을 사용합니다.

사용법 및 실행하기

1
$ npm install styled-components --save-dev

styled-components를 설치 한 후

예제 컴포넌트를 만들어봅니다.

./exampleComponent.js (styled-components 적용 전)

1
2
3
4
5
6
7
8
9
import React from 'react';
const exampleComponent = () => (
<div>
<button>일반 버튼</button>
<button>테두리 버튼</button>
</div>
);

export default exampleComponent;

위의 컴포넌트는 styled-components 적용전의 컴포넌트 입니다.
이 컴포넌트에 styled-components를 적용시키면

./exampleComponent.js (styled-components 적용 후)

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
32
33
34
35
36
37
38
39
40
41
42
43
44
import React from 'react';
import styled, { css } from 'styled-components';
const buttonComponent = () => (
<Box color="black">
<BasicButton>일반 버튼</BasicButton>
<BasicButton edge={true}>테두리 버튼</BasicButton>
</Box>
);

const Box = styled.div`
/* props 로 값을 직접 전달할 수 있습니다. */
background: ${props => props.color || 'blue'};
padding: 10px;
display: flex;
`;

const BasicButton = styled.button`
margin: 0 1em;
padding: 13px;
min-width: 80px;

/* sass 처럼 & 사용 가능 */
&:hover {
background: rgba(255, 255, 255, 0.9);
}

/* edge 값이 true 일 때 특정 스타일을 부여해줍니다. */
${props =>
props.edge &&
css`
background: none;
border: 2px solid white;
color: white;
&:hover {
background: white;
color: black;
}
`};
& + button {
margin-left: 1rem;
}
`;

export default buttonComponent;

보시는바와 같이

div는 Box 변수에 button은 Button 변수에 스타일링을 하여 담아 주고 있습니다.
여기서 특이한점은 css를 props를 사용하여 특정 값일때 스타일을 변경 할 수 있다는 것입니다.

createGlobalStyle

만약 global 하게 css 설정값이 필요하다면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import styled, { createGlobalStyle } from 'styled-components';
const GlobalStyle = createGlobalStyle`
body {
padding: 0;
margin: 0;
}
`;

const exampleComponent = () => (
<GlobalStyle>
<Box color="black">
<BasicButton>일반 버튼</BasicButton>
<BasicButton edge={true}>테두리 버튼</BasicButton>
</Box>
);

---- 아래 코드 생략 ----

createGlobalStyle 메서드를 import 하고 GlobalStyle 변수에 global css를 정의 한 후
랜더링 부분에 추가하게되면 global한 css가 추가되게 됩니다.

withComponent (상속)

withComponent 메서드는 기존에 만들어놓은 style-component를 상속받아 새로운 component를 만듭니다.

1
const LinkButton = BasicButton.widthComponent('a');

기존에 만들었던 Button styleCompnent를 a 태그에 적용하게됩니다.
이렇게 되면 Button에 적용되어있던 style까지 전부 상속받게됩니다.

상속받은 styleCompnent에서 스타일을 추가하고 싶다면

1
2
3
4
5
const LinkButton = styled(BasicButton.widthComponent('a'))`
or
const linkButton = BasicButton.widthComponent('a').extend`
color: blue;
`;

위와같이 styled or extend 메서드를 이용하여 적용해 주시면 됩니다.

이외의 기본 기능들은 공식홈페이지 문서를 참고하시면 됩니다.

마지막으로

ThemeProvider

ThemeProvider를 사용해

./theme.js

1
2
3
4
5
6
7
8
const theme = {
color: {
default: '#fff',
primary: '#547fbb',
warning: '#D72E3D'
}
}
export default theme;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React, { Component } from 'react';
import styled, { ThemeProvider } from 'styled-components';
import theme from './theme';

class App extends Component {
render() {
return (
<ThemeProvider theme={theme}>
<BasicButton {...props}>
{children}
</BasicButton>
</ThemeProvider>
);
}
}

const BasicButton = styled.button`
color: ${props => { props.theme.color.default }}
`

테마에 따른 값을 변경하여 줄 수 있습니다.

styled components를 사용했던 이유는 theme 기능이 있기 때문에 사용해보게 되었는데,

개인적인 의견으로는
막상 사용해보니 css 코드에서 props 에 따라 값을 변경하고 하는것이 신선하였고,
SASS설치나 Webpack 설정을 하지않는다는 점과
사용해보지는 않았지만 styled-components로 작성된 css코드를 React Native에 바로 적용가능 하다고 하는 점,
( React Native에서 사용하면 기존에 사용하던 Text, View 등등 React Native 컴포넌트대신 styeld component 사용가능 )
마지막으로는 css를 위한 className이 따로 필요없다는 점이 가장 큰 장점이였던것 같습니다.

단점으로는
코드를 작성하고 theme를 사용하려고 해보니 오히려
${props => { props.theme.color.default }}
위와 같은 식으로 작성하는게 많아지다보면 더 복잡해지는 코드가 되는 느낌이 들었기 때문에
개안적으로는 아마 실제 프로젝트에선 굳이 사용하지는 않을것같다 라는 느낌을 받았고,
아마도.. css, sass, scss, postcss 등을 사용할 것 같습니다.

그러나 만약 webpack이나 sass 등을 모르고 styled-components도 모르는 상황이라면
styled-components가 접근하기에 훨씬 유용할것이라고 생각하고,
필자가 그 상황이라면 styled-components를 사용할 것 같습니다.


Comments: