📢 어렵고 정석적인 개념 설명보다는 저같은 초보자도 이해하기 쉽게 정리하는 것을 원칙으로 포스팅하고 있습니다. 😄

[React] styled-components로 CSS-in-JS 방식의 스타일링하기

styled-components란?

styled-components란 리액트로 개발을 할 때 사용되는 CSS-in-JS 라이브러리로, CSS-in-JS자바스크립트 코드 안에서 CSS를 작성하는 방법을 말한다. 이 방식을 채택함으로써 컴포넌트 기반의 스타일링을 쉽게 구현할 수 있다.

 

우리가 일반적으로 CSS를 작성할 때, 클래스를 주고 해당 클래스에 스타일을 입혔다면 styled-components는 클래스가 아닌 컴포넌트에 직접 스타일을 작성해서 컴포넌트처럼 재사용할 수도 있다. 그 외에도 자바스크립트 코드로 작성되기 때문에 삼항연산자 등을 이용해서 동적으로 스타일을 변경하는 작업도 쉽게 할 수 있다는 장점이 있다.

컴포넌트를 사용하는 리액트 환경에서는 CSS-in-JS 스타일링 방식을 사용하는 게 효율적이고 적합하다고 생각한다.

 

사용 방법

기본적인 방법 (정적 스타일링)

const Title = styled.h1`
    font-size: 2rem;
    font-weight: 900;
    text-align: center;
`

const Wrapper = styled.div`
    width: 100%;
    padding: 1.5rem;
    background: #fff;
`

const App = () => {
    return (
        <Wrapper>
            <Title>This is Title</Title>
        </Wrapper>
    )
}

styled-components의 가장 기본적인 사용 방식은 위와 같다. 템플릿 리터럴(` `) 안에 스타일을 넣어준 후, HTML 태그를 사용하는 것처럼 위에 지정해 준 스타일 컴포넌트 이름을 넣어주면 된다. styled-components를 사용할 때는 반드시 스타일을 정의하는 부분과 컴포넌트를 선언하는 부분을 분리해야 한다!

 

Props로 가변적인 스타일링하기

const StyledButton = styled.button`
    border: none;
    padding: 1rem 1.5rem;
    font-size: 1.5rem;
    color: ${(props) => props.color};
    background: ${(props) => props.background};
`;

const Button = () => {
    return (
        <StyledButton color="red" background="#fff">버튼</StyledButton>
    )
}

StyledButton이라는 styled-components를 하나 만들어주었다. 이 버튼의 경우 배경색과 글자색은 정해진 것 없이 레이아웃에 따라 가변적으로 주려고 한다. 이때, props를 전달해서 사용하면 가변적인 스타일링이 가능하다.

 

// Button.js
const StyledButton = styled.button`
    border: none;
    padding: 1rem 1.5rem;
    font-size: 1.5rem;
    color: ${(props) => props.color};
    background: ${(props) => props.background || '#fff'};
`;

const Button = ({ ...props, title }) => {
    return <StyledButton {...props}>{title}</StyledButton>
}

// App.js
const App = () => {
    return (
        <div>
            <Button color="red" background="green" title="자세히 보기" />
            <Button color="red" title="이 버튼의 배경색은?" />
        </div>
    )
}

컴포넌트를 사용할 때, 전달하고자 하는 스타일의 props가 많을 수도 있다. 그럴 경우 {...props}를 사용해서 모든 props를 styled 컴포넌트로 넘길 수 있다. 위 코드에서는 Button 컴포넌트의 color="red" background="green" 부분을 {...props}로 전달하고 있다. 또한, {...props} 안에는 title도 들어가 있다. 하지만, 위 코드에서 title은 Button 컴포넌트의 innerText가 되는 부분이므로 {...props}가 아닌 {title}이라고 별도로 분리해주어야 한다. 따라서, 전달하는 props가 {...props, title}이 된다.

 

위 코드에서 두 번째 Button 컴포넌트의 배경색은 무엇일까? 정답은 '#fff'이다. background 스타일을 보면 props.background || '#fff'라고 되어있다. 이것은, props.background가 있으면 props.background를 적용하고 없다면 '#fff'를 적용하겠다는 뜻이다. (true || false라고 되어 있으면 앞부분에서 true가 나오는 순간 true를 출력하고 종료한다.)

 

css 함수를 이용한 스타일 그룹화하기

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

const flexCenter = styled.css`
    display: flex;
    justify-content: center;
    align-items: center;
`;

const Wrapper = style.div`
    ${flexCenter}
    padding: 1.5rem;
    background: #fff;
`

스타일을 그룹화하여 사용할 수도 있다. 위 코드를 보면 flexCenter는 css 함수로 스타일을 정의한 코드 블록이다.

flex 중앙 정렬의 경우에는 여기저기 많이 쓰이는 스타일이기 때문에 이렇게 따로 분리해서 필요한 곳마다 재사용할 수 있게 해 주었다. css 함수를 사용하면 여러 컴포넌트에서 공유할 수 있는 스타일 코드를 재사용할 수도 있고, 코드의 가독성도 높일 수 있어서 좋다.

 

가상 클래스, 가상 선택자도 가능

const styleButton = styled.button`
    font-size: 1.5rem;
    border: none;
    background: #fff;
    padding: 1rem;
    
    &:hover {
        background: green;
    }
    &::before {
        content: "";
        width: 100%;
    }
    &:last-child {
        display: none;
    }
`;

const Buttons = () => {
    return (
        <div>
            <styleButton>이건 보이는데</styleButton>
            <styleButton>이건 안 보일걸?</styleButton>
        </div>
    )
}

일반적인 CSS처럼 styled-components에서도 가상 클래스, 가상 선택자 등 모두 똑같이 적용할 수 있다.

해당 스타일 컴포넌트를 '&'로 한다는 점 외에 다른 점은 크게 없다. 위 코드에서는 &:last-child에 display: none를 했기 때문에 Button 컴포넌트 안에 마지막 styleButton 컴포넌트는 보이지 않을 것이다.

 

이외에도 styled-components는 다양한 기능들을 가지고 있다. 무엇보다도 컴포넌트를 사용하는 리액트 환경에서는 굳이 클래스 이름을 하나하나 지정할 필요 없이 styled-components 방식을 사용하면 더 편하게 작업할 수 있을 것 같다.

(css 파일을 굳이 만들어 줄 필요가 없으므로 폴더도 깔끔해지고, 무엇보다 클래스 이름 짓기가 너무 어려웠다..)

이 글에서는 모두 소개하지는 못했지만, 더 자세히 알고 싶다면 공식 문서에 들어가서 확인해 보자.

 

1. styled-components란 CSS-in-JS 방식으로 자바스크립트 안에 CSS를 넣는 것.
2. 스타일을 컴포넌트처럼 사용할 수도 있으며, props를 받아서 가변적인 스타일링도 가능
3. <Button color="blue">라면, ${(props) => props.color}로 받을 수 있음.