인기있는 라이브러리는 사용해보고 싶기 마련이다. 그래서 내맘대로 지지고 볶을 수 있는 내 포트폴리오 페이지에서 한번 찍먹(맛보기) 해보기로 했다.
자 그럼 이게 뭔지 알려면 공홈에서 확인해보는게 인지상정이다.
Visual primitives for the component age.
Use the best bits of ES6 and CSS to style your apps without stress
음 컴포넌트 단위를 위한 시각적 기본요소..뭔 말일까..좀 더 디테일한 설명이 필요하다. 공식 DOCS로 가보자. 아 여기 써있네.
styled-components is the result of wondering how we could enhance CSS for styling React component systems. By focusing on a single use case we managed to optimize the experience for developers as well as the output for end users.
일단은 react의 컴포넌트 시스템을 스타일링하기 위한 css에 대해 고민한 결과라고 한다.
그 외에 많은 설명이 있지만 요약하자면, css파일과 컴포넌트 파일이 분리되어서 생기는 귀찮은 부분을 해결했다는 말이 었다.
일단 체감이 안되니 경험으로 때워보기로 한다. 내 포트폴리오 사이트에 react portal을 이용하여 프로젝트의 설명을 띄우는 컴포넌트를 추가하려 한다. 지금까지 module.scss를 사용하던 나였기에 styled component를 경험해볼 좋은 기회라 생각하고 설치부터 했다.
이제 사용설명서를 좀 읽어보자.
스타일드 컴포넌트는 템플릿 리터럴을 이용하여 스타일 코드를 작성한다고 한다. 예시를 보자.
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
<Title>
Hello World!
</Title>
예시를 보니까 느낌이 확온다. 사용을 변수명으로 하니까 컴포넌트같고 또 스타일링을 받은 컴포넌트니까 스타일드 컴포넌트라는 느낌.
조금 더 분석해보자.
// 사용할 컴포넌트 태그이름, styled.태그명`스타일링`
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
<Title>
Hello World!
</Title>
사용할 태그를 스타일링하고 변수에 저장하면 스탕일링된 태그를 컴포넌트처럼 사용할 수 있게 된다. 그럼 다음 예시를 보자.
const Button = styled.button`
background: ${props => props.primary ? "palevioletred" : "white"};
color: ${props => props.primary ? "white" : "palevioletred"};
border: 2px solid palevioletred;
border-radius: 3px;
`;
render(
<div>
<Button>Normal</Button>
<Button primary>Primary</Button>
</div>
);
사용을 컴포넌트처럼 하니까 스타일드 컴포넌트의 props를 받아서 삼항조건 연산자를 return하는 함수로 사용할 수 있다. 원래 같았으면 className에 삼항조건연산자를 사용해서 두개의 클래스를 사용하는 방식으로 스타일 처리를 했을 텐데, css에서 props에 접근할 수 있다는게 매우 유용해 보인다. state나 상위컴포넌트에서 준 props를 기준으로 css에 변화를 줄 수 도 있다는 것 아닌가.. 이건 좀 쩐다.
내가 이 부분에 더 매력을 느낀이유는 module.scss를 사용하면 이런 조건에 따른 스타일 처리가 조금 귀찮기 때문이다. 예를 들어
import styles from '...module.scss'
const [state,setState]= useState(true);
<Component className={state?styles.A:styles.B}>...</Component>
이런 식으로 처리해 왔으니말이다.. styled-component를 사용하면 그냥 props로 전달해주기만 하면 되는 거니까 얼마나 편하게요~
다음 예시도 봐보자
const Button = styled.button`
display: inline-block;
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
`;
const TomatoButton = styled(Button)`
color: tomato;
border-color: tomato;
`;
기존에 스타일링한 컴포넌트를 상속받아서 스타일링을 수정할 수도 있다. 마치 클래스가 상속받아 오버라이딩하듯이 말이다.
일단 이정도 알아보고 내 포폴에 사용해보자.
const Article = styled.article`
position:fixed;
width:100%;
height:100%;
top:0;
left:0;
`
const CloseBtn = styled.button`
position:fixed;
top:18%;
right:15%;
width: 3%;
height: 3%;
padding: 0;
border: 0 ;
background-color: inherit;
cursor:pointer;
span{
border-radius:5px;
position:absolute;
width: 100%;
height: 3px;
display:inline-block;
background-color:black;
top:40%;
left:0;
&:nth-child(1){
transform: rotate(45deg);
}
&:nth-child(2){
transform: rotate(135deg);
}
};
`
section내부의 글이니까 semantic 하게 acticle태그를 사용해서 만들어주었다. 또 모달창이다 보니 닫기버튼이 있어야겠지 않겠는가? 가볍게 X버튼을 만들어 주었다. 하다보니 scss를 이용하던 습관이 나와서 이게 되나 하고 또 찾아봤다.
The preprocessor we use, stylis, supports scss-like syntax for automatically nesting styles.
css 전처리기와 같은 중첩구문도 지원한다고 하니 맘편하게 사용했다.
막상 만들고 나니 확 나왔다 확 사라지는게 좀 심심해서 애니메이션을 넣으려 했는데 생각해보니 keyframe을 사용하는 방법을 아직 모르네.. 공식 DOCS에서 찾아봤다.
const rotate = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`;
const Rotate = styled.div`
display: inline-block;
animation: ${rotate} 2s linear infinite;
padding: 2rem 1rem;
font-size: 1.2rem;
`;
스타일드 컴포넌트 만들듯이 키프레임도 만들어서 ${}를 이용해가지고 참조시키는 방식이었다.
const showModal = keyframes`
0%{
opacity:0
}
100%{
opacity:1
}
`
const Article = styled.article`
position:fixed;
width:100%;
height:100%;
top:0;
left:0;
animation: ${showModal} 1s both;
`
간단한 애니메이션으로 스르륵 나올 수 있게 보여주는 애니메이션을 넣어줬다. 나중에 더 이쁘게 꾸며야지.
이렇게 스타일드 컴포넌트로 컴포넌트를 만들고 npm run deploy로 사이트에 배포도 했다. 끝나다고 생각했을 때는 항상 뭐가 더 남아 있더라.
해당 컴포넌트들에 미디어 쿼리를 적용하지 않아서 모바일 뷰가 깨져버린 것이다. 다행히 배포 후 바로 발견해서 고치기 시작했다. 공식 DOCS에 미디어 쿼리 사용법이 나오지 않아서 구글링 했더니 역시 플로우형이 해결해 줬다.
const CloseBtn = styled.button`
position:fixed;
top:18%;
right:15%;
width: 3%;
height: 3%;
padding: 0;
border: 0 ;
background-color: inherit;
cursor:pointer;
span{
border-radius:5px;
position:absolute;
width: 100%;
height: 3px;
display:inline-block;
background-color:black;
top:40%;
left:0;
&:nth-child(1){
transform: rotate(45deg);
}
&:nth-child(2){
transform: rotate(135deg);
}
};
@media(max-width: 800px){
width: 5%;
top: 12%
}
`
이렇게 포트폴리오 사이트의 모달이 완성되었다.
어떤 도구던 장단이 있는 법이다. styled-component의 경우 다른 css 방법들 보다 상태에 따라 다른 스타일을 보여주기 편한 방식이란 것을 배운 것 같다. 하지만 styled-component만으로 스타일링을 하려고 하면 CBD방법론 처럼 기초가 되는 컴포넌트들을 잘 만들어 놓고 필요한 컴포넌트를 오버라이딩하는 방식으로 사용하지 않으면 jsx파일이 기~~~일어 질 것 같았다. 물론 컴포넌트 파일을 따로 분류 하면 되는 일이긴 하지만 말이다.
확실히 인기가 있는 라이브러리는 이유가 있었다. 어떤 라이브러리든지 그렇겠지만, 적절한 상황에서 사용하면 참 편리할 것 같다는 생각이 들었다.