본문으로 건너뛰기
yceffort
PostsSeriesTagsAbout🧪 Research
EN

Tweaks

theme
accent palette
film grain
minimal mode
BACK TO INDEX
◆ ESSAY
--min
--year
KOoriginal

mailMail icongithubtwitter
yceffort
•
© 2026
•
https://yceffort.kr
BACK TO INDEX
◆ ESSAY

styled-components로 스타일 적용하는법

avatar
yceffort
2020-10-07 · 3분
3min
2020year
KOoriginal
reactcss

먼저 styled components를 쓰는 방법을 간단하게 살펴보자.

Table of Contents

  • Create
  • Usage
  • Internal
  • Extend
  • Compose
  • Prop Style

Create

import styled from 'styled-components'

const Button = styled.button`
  display: inline-block;
  padding: 6px 12px;
  font-size: 16px;
  font-family: Arial, sans-serif;
  line-height: 1.5;
  color: white;
  background-color: #6c757d;
  border: none;
  border-radius: 4px;
  :not(:disabled) {
    cursor: pointer;
  }
  :hover {
    background-color: #5a6268;
  }
`

styled 컴포넌트를 임포트하고, button과 함께 사용하여 백틱 두개 사이에서 스타일을 적용하였다. button 대신에 h1 p 등의 HTML elements를 사용할 수 있으며, 스타일에는 유효한 모든 CSS 문법이 가능하다.

Usage

이렇게 만든 styled component는 리액트 컴포넌트와 마찬가지로 JSX 문법을 이용하여 사용할 수 있다.

const App = () => {
  return (
    <Button onClick={() => alert('clicked!')} type="button">
      Button
    </Button>
  )
}

Internal

이렇게 해서 만들어진 button을 한번 살펴보자.

https://codesandbox.io/embed/sweet-forest-1eix4?fontsize=14&hidenavigation=1&theme=dark

<style data-styled="active" data-styled-version="5.2.0">
  .eWMwHd {
    display: inline-block;
    padding: 6px 12px;
    font-size: 16px;
    font-family: Arial, sans-serif;
    line-height: 1.5;
    color: white;
    background-color: #6c757d;
    border: none;
    border-radius: 4px;
  }
  .eWMwHd:not(:disabled) {
    cursor: pointer;
  }
  .eWMwHd:hover {
    background-color: #5a6268;
  }
</style>
<button type="button" class="sc-dlnjPT eWMwHd">Button</button>

그렇다면 내부에서는 어떻게 작할까?

  1. styled components는 정의된 스타일을 기반으로 유니크한 클래스명을 만든다.
  2. HTML <head> 영역에 <style> 태그를 넣고, 여기에 1번에서 만든 유니크 클래스명과 연결되는 스타일을 넣어둔다.
  3. 1번과 2번을 바탕으로 렌더링한다.

Extend

기존에 존재하는 styled component를 바탕으로 디자인을 확장할 수 있다. 대신 .button이 아닌 .(확장할 컴포넌트명)을 사용한다.

const PrimaryButton = styled(Button)`
  background-color: #007bff;
  :hover {
    background-color: #0069d9;
  }
`
const App = () => {
  return (
    <PrimaryButton onClick={() => alert('clicked!')} type="button">
      Primary
    </Button>
  )
}

이와 유사하게, 리액트 컴포넌트를 확장할 수 도 있다.

const ButtonComponent = ({className}) => {
  return (
    <Button
      className={className}
      onClick={() => alert('clicked!')}
      type="button"
    >
      Primary
    </Button>
  )
}
const PrimaryButton = styled(ButtonComponent)`
  background-color: #007bff;
  :hover {
    background-color: #0069d9;
  }
`

한가지 다른 점은 className prop이 추가되었다는 것이다. 이 className은 앞서 언급했던 class와 동일하게 동작하며, 반드시 prop으로 넘겨주어야 한다. 그렇지 않으면 작동하지 않는다.

Compose

기존에 존재하는 스타일과 합성도 가능하다.

import styled, {css} from 'styled-components'
const blackFont = css`
  color: black;
`

const WarningButton = styled(Button)`
  background-color: #ffc107;
  :hover {
    background-color: #e0a800;
  }
  ${blackFont}
`

const App = () => {
  return (
    <WarningButton onClick={() => alert('clicked!')} type="button">
      Warning
    </WarningButton>
  )
}

Prop Style

prop을 받아서 스타일을 선택적으로 적용할 수도 있다.

import styled, {css} from 'styled-components'
const SuccessButton = styled(Button)`
  ${(props) =>
    props.$success
      ? css`
          background-color: #28a745;
          :hover {
            background-color: #218838;
          }
        `
      : ''}
`
const App = () => {
  return (
    <SuccessButton $success onClick={() => alert('clicked!')} type="button">
      Success
    </SuccessButton>
  )
}

여기에 필수는 아니지만 $ prefix를 붙였는데, 이는 다른 DOM, React 컴포넌트에서 사용하는 props와 명확히 구별하기 위함이다.

관련 글

  • #react#css#nextjs

    React의 <ViewTransition>: 브라우저 네이티브 애니메이션을 React답게

    View Transition API를 React가 감싸면 어떻게 되는가

    2026-03-02·27분
  • #framer-motion#performance#animation

    framer-motion 배너에서 프레임드랍 없애기: 두 번의 삽질과 이징 함수

    framer-motion으로 만든 배너가 열리는 0.6초 동안 홈 전체가 버벅였다. 원인을 코드로 추정하고, 실측으로 두 번 뒤집히고, 결국 이징 함수 하나로 리플로우를 없애기까지의 기록. 그리고 이 작업이 남긴 것들: 선언과 실행의 간극, 속성이 성능을 결정한다는 원칙, 메커니즘 보존, 계측기를 의심하는 순서, 같음을 곡선으로 증명하는 방법.

    2026-08-15·50분
  • #ai#essay#frontend

    프론트엔드는 어디서 왔고, 에이전트 이후 어디로 가는가

    층은 왜 쌓였고, 왜 서버로 돌아왔고, 에이전트 이후에도 스택이 남는 이유는 무엇인가. 그리고 스택이 이기는 것과 그 스택을 아는 사람의 가치는 왜 별개인가

    2026-07-22·34분
  • #react#react-server-components#memoization

    React cache() 딥다이브: 소스 코드로 읽는 요청 단위 메모이제이션

    React cache() 함수의 모든 이상한 규칙은 30여 줄짜리 구현에서 직접 따라 나온다. dispatcher, getCacheForType, WeakMap/Map 트리를 소스 레벨로 따라가며 요청 단위 메모이제이션의 동작을 끝까지 본다.

    2026-05-30·35분

새 글을 놓치고 싶지 않으시다면 RSS로 구독해 주세요.

RSS 구독 →

yceffort — 프론트엔드 엔지니어입니다. 발표·기술 자문·기고 문의는 이곳에서 받고 있습니다.

← Back to the blogIssue on GitHub →