이제 나에게는 필수적인 라이브러리가 된 styled-components에 대한 개요, 설치하는 방법과 기본적인 활용법 등을 소개하고자 한다.
백엔드 개발자의 대표적인 고충이 DB와 관련한 작업들이라면, 프론트엔드 개발자들의 고충은 아마도 마크업, UI 개발, 퍼블리싱이라고 불리는 HTML과 CSS 작업일 것이다.(마크업, UI 개발, 퍼블리싱은 HTML, CSS 개발이라는 공통분모가 있어 비슷하지만 각각 약간 개념이 다른 것 같다.)
그중 CSS 작업은 매우 고통스러운 일이 될 수도 있다.
왜냐하면 CSS는 구조화하기 어렵고, 변수를 선언하여 쓰기 어렵고, 프로젝트가 커지다 보면 class명이 겹쳐서 스타일이 꼬이는 등 예상치 못한 문제가 튀어나올 가능성이 매우 크기 때문이다.
그래서 SCSS와 같은 좀 더 발전된 형태로 CSS를 개발할 수 있는 포맷이 나오긴 했지만 그럼에도 불구하고 프로그래밍 언어보다는 다루기가 까다롭다.
그에 비해 styled-components는 거의 완전한 css in javascript로서 거의 모든 마크업을 프로그래밍 언어로 통제할 수 있다. 즉 특정 스타일에 매개변수를 선언할 수 있고, 그 매개변수가 바뀔 때마다 스타일이 바뀌도록 설정할 수 있다. 정확히는 매개변수라기보다 React의 props 개념이라고 보면 된다.
또한 styled-components는 class명을 신경 쓰지 않아도 된다. 각각의 컴포넌트마다, 그리고 매개변수에 따라 바뀌는 스타일마다 알아서 겹치지 않도록 class명이 부여가 된다.
따라서 javascript에 능숙하고 기본적인 CSS 스타일링 문법을 안다면 별다른 무리 없이 스타일링을 할 수 있으며 업무 효율로 올라간다.
게다가 전통적인 방식인
<div class="box">
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
</div>
위와 같은 방식으로 html을 작성할 때마다 class명을 부여하는 것이 아니라
<Box>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
</Box>
이처럼 html 태그처럼 쓰면 해당 컴포넌트에 스타일링 된대로 화면이 렌더링 된다.(물론 저 방식은 React나 Vue의 컴포넌트 적용 방법이며, styled-components 또한 결국 React의 컴포넌트이기 때문에 같은 방식으로 작성하여 적용하게 된다.)
styled-components에 대한 자세한 내용은 공식 문서를 참고 바란다.
여러 기능이 많겠지만 본 포스트에서는 기본적인 사용법 및 실무에서 자주 쓰는 매개변수(props) 활용 사례, 상속 사례를 소개하고자 한다.
기본 사용법
// style.ts 파일
import styled from 'styled-components';
const Box = styled.div`
margin: 24px;
`;
const ItemBox = styled.div`
display: flex;
align-items: center;
margin-top: 24px;
&:first-child {
margin-top: 0;
}
`;
export { Box, ItemBox };
// index.tsx 파일
import { Box, ItemBox } from './style.ts';
...
// 컴포넌트 내부
<Box>
<ItemBox>
<p>...</p>
</ItemBox>
<ItemBox>
<p>...</p>
</ItemBox>
<ItemBox>
<p>...</p>
</ItemBox>
<ItemBox>
<p>...</p>
</ItemBox>
</Box>
매개변수(props) 활용법
// style.ts 파일
import styled, { css } from 'styled-components';
interface iItemBoxProps {
backgroundColor?: string;
}
const Box = styled.div`
margin: 24px;
`;
const ItemBox = styled.div<iItemBoxProps>`
display: flex;
align-items: center;
margin-top: 24px;
${({backgroundColor}) => {
if (backgroundColor) {
return css`
background-color: ${backgroundColor};
`
}
}}
&:first-child {
margin-top: 0;
}
`;
export { Box, ItemBox };
// index.tsx 파일
import { Box, ItemBox } from './style.ts';
...
// 컴포넌트 내부
<Box>
<ItemBox backgroundColor="red">
<p>...</p>
</ItemBox>
<ItemBox>
<p>...</p>
</ItemBox>
<ItemBox>
<p>...</p>
</ItemBox>
<ItemBox>
<p>...</p>
</ItemBox>
</Box>
위와 같이 props를 활용하여 매개변수처럼 사용이 가능하며, props의 값도 상태 관리를 통해 유저의 인터랙션에 따라 실시간으로 바뀌게 할 수 있다.
상속 사용법
// style.ts 파일
import styled, { css } from 'styled-components';
interface iItemBoxProps {
backgroundColor?: string;
}
const Box = styled.div`
margin: 24px;
`;
const ItemBox = styled.div<iItemBoxProps>`
display: flex;
align-items: center;
margin-top: 24px;
${({backgroundColor}) => {
if (backgroundColor) {
return css`
background-color: ${backgroundColor};
`
}
}}
&:first-child {
margin-top: 0;
}
`;
const BorderItemBox = styled(ItemBox)`
box-sizing: border-box;
border: 1px solid red;
`
export { Box, ItemBox, BorderItemBox };
// index.tsx 파일
import { Box, ItemBox } from './style.ts';
...
// 컴포넌트 내부
<Box>
<ItemBox backgroundColor="red">
<p>...</p>
</ItemBox>
<BorderItemBox>
<p>...</p>
</BorderItemBox>
<ItemBox>
<p>...</p>
</ItemBox>
<ItemBox>
<p>...</p>
</ItemBox>
</Box>
이처럼 BorderItemBox는 나머지 스타일은 모두 ItemBox와 같은데 border값만 주고 싶다 했을 때 쓰는 방법이다. 스타일이 거의 같을 경우 불필요하게 다시 선언할 필요 없이 이렇게 작성하면 된다.
props를 활용하는 방법이나 상속을 받는 방법이나 부분적으로 스타일을 바꿔준다는 점에서 비슷하지만, 용도가 조금 다르다.
props를 활용하는 방법은 컴포넌트 내에서 state 변경에 따른 동적으로 스타일을 바꿔줄 때 사용한다.(예: 사용자에 의해 선택된 아이템)
상속하는 방법은 state보다는 특정 스타일에서 파생적으로 발생하는 스타일을 정의할 때 쓴다고 생각하면 된다.
'개발 > FrontEnd' 카테고리의 다른 글
Next.js에서 Firebase Remote Config(원격 구성) 수정하기 (0) | 2021.12.22 |
---|---|
Next.js + TypeScript + ESlint + Prettier 세팅(4) (0) | 2021.07.14 |
Next.js + TypeScript + ESlint + Prettier 세팅(3) (0) | 2021.07.13 |
Next.js + TypeScript + ESlint + Prettier 세팅(2) (0) | 2021.07.06 |
Next.js + TypeScript + ESlint + Prettier 세팅(1) (0) | 2021.07.05 |