현재 오즈코딩스쿨 강의를 통해 프론트엔드를 학습하고 있습니다.
본 포스트는 해당 강의에 대한 내용 정리를 목적으로 합니다.

Styled-Components는 React에서 CSS를 JavaScript 안에서 작성할 수 있도록 도와주는 라이브러리이다.
CSS를 별도 파일이 아닌 JS 코드 내부에서 작성하며, 컴포넌트 단위로 스타일을 관리할 수 있다는 점이 특징이다.
CSS-in-JS 방식이다.
스타일을 .css 파일이 아닌 JavaScript 파일 내부에서 정의한다.
컴포넌트 단위 스타일링이다.
스타일이 각 컴포넌트에 독립적으로 적용되므로, 클래스 이름 충돌을 방지할 수 있다.
동적 스타일 적용이 가능하다.
props를 활용하여 조건에 따라 스타일을 변경할 수 있다.
설치하기 : 터미널에서 다음 명령어를 입력하여 Styled-Components를 설치한다.
npm install styled-components
사용 준비 (import) : 사용할 파일 상단에 styled-components를 불러온다.
import styled from "styled-components"
📌 tip : 스타일 자동완성이 안되면 vscode-styled-components 설치
styled 컴포넌트 만들기 : HTML 태그 이름을 함수처럼 사용하여 스타일이 적용된 컴포넌트를 생성한다.
const Title = styled.h1`
font-size: 2rem;
color: navy;
`;
const Button = styled.button`
background-color: tomato;
color: white;
padding: 10px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
`;
컴포넌트에서 사용하기 : 위에서 만든 styled 컴포넌트를 일반 컴포넌트처럼 사용하면 된다.
function App() {
return (
<div>
<Title>Styled-Components 예제</Title>
<Button>클릭</Button>
</div>
);
}
props로 동적 스타일링하기 : props를 이용해 조건에 따라 스타일을 다르게 적용할 수 있다.
const Button = styled.button`
background-color: ${props => props.primary ? 'blue' : 'gray'};
color: white;
padding: 10px;
border-radius: 5px;
`;
function App() {
return (
<>
<Button primary>Primary 버튼</Button>
<Button>기본 버튼</Button>
</>
);
}
글로벌 스타일 적용 (선택 사항) : 앱 전체에 공통 스타일을 적용하고 싶을 땐 createGlobalStyle을 사용한다
import { createGlobalStyle } from 'styled-components';
const GlobalStyle = createGlobalStyle`
body {
margin: 0;
font-family: 'Noto Sans KR', sans-serif;
background-color: #f9f9f9;
}
`;
function App() {
return (
<>
<GlobalStyle />
<Title>글로벌 스타일 적용</Title>
</>
);
}

StyledButton.js (컴포넌트 분리)
// StyledButton.js
import styled from 'styled-components';
const StyledButton = styled.button`
background-color: tomato;
color: white;
padding: 10px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
`;
export default StyledButton;
App.js (불러와서 재사용)
import React from 'react';
import StyledButton from './StyledButton';
function App() {
return (
<div>
<StyledButton>버튼 1</StyledButton>
<StyledButton>버튼 2</StyledButton>
</div>
);
}
위처럼 StyledButton을 다른 파일로 분리하여, 원하는 컴포넌트에서 불러와서 재사용할 수 있다.

props를 활용하면 하나의 컴포넌트를 여러 스타일로 재사용할 수 있다.
const StyledButton = styled.button`
background-color: ${props => props.primary ? 'blue' : 'gray'};
color: white;
padding: 10px 20px;
border-radius: 5px;
`;
function App() {
return (
<>
<StyledButton primary>Primary</StyledButton>
<StyledButton>Default</StyledButton>
</>
);
}
styled() 함수를 이용하면 기존 styled component를 확장(extend) 해서 새로운 스타일로 만들 수 있다.
const BaseButton = styled.button`
padding: 10px 15px;
border-radius: 5px;
`;
const DangerButton = styled(BaseButton)`
background-color: red;
color: white;
`;
const SuccessButton = styled(BaseButton)`
background-color: green;
color: white;
`;
function App() {
return (
<>
<DangerButton>삭제</DangerButton>
<SuccessButton>확인</SuccessButton>
</>
);
}
규모가 커질수록 공통 styled-components 디렉토리를 만들고, 자주 쓰는 버튼, 타이틀, 박스 등을 정의해놓고 프로젝트 전반에 재사용하는 것이 좋다.
예시 폴더 구조
src/
└─ components/
└─ styles/
├─ Button.js
├─ Title.js
└─ Card.js
props 사용하기 – 예시 코드Styled-Components에서는 props를 통해 동적으로 스타일을 변경할 수 있다.
import styled from 'styled-components';
const Button = styled.button`
background-color: ${props => props.primary ? 'royalblue' : 'gray'};
color: white;
padding: 10px 20px;
border-radius: 8px;
border: none;
cursor: pointer;
font-weight: bold;
&:hover {
opacity: 0.9;
}
`;
function App() {
return (
<div>
<Button primary>Primary 버튼</Button>
<Button>기본 버튼</Button>
</div>
);
}
export default App;
위 예시에서 primary라는 props를 기준으로 배경색이 동적으로 변경된다.
createGlobalStyle을 사용하면 HTML 전체에 적용되는 전역 스타일을 설정할 수 있다.
import React from 'react';
import styled, { createGlobalStyle } from 'styled-components';
const GlobalStyle = createGlobalStyle`
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Noto Sans KR', sans-serif;
background-color: #f5f5f5;
color: #333;
}
a {
text-decoration: none;
color: inherit;
}
`;
const Title = styled.h1`
font-size: 2rem;
margin: 20px;
`;
function App() {
return (
<>
<GlobalStyle />
<Title>전역 스타일 적용 예시</Title>
</>
);
}
export default App;
전역 스타일은 일반적으로 최상위 컴포넌트(App.js 등)에 한 번만 적용하면 된다.
Styled-Components는 내부적으로 Tagged Template Literals (태그드 템플릿 리터럴) 을 활용하여 CSS 코드를 처리한다. 이 덕분에 SCSS처럼 중첩, 변수 사용, mixin, 조건 처리 등의 문법을 자연스럽게 흉내낼 수 있다.
const Wrapper = styled.div`
padding: 20px;
h1 {
color: navy;
}
button {
background-color: gray;
&:hover {
background-color: black;
}
}
`;
이 중첩 문법은 마치 SCSS처럼 보이지만, 실제로는 CSS-in-JS 처리 과정에서 문자열을 JS 코드로 변환하기 때문에 가능한 기능이다.
스타일 충돌 방지
컴포넌트마다 고유한 클래스 이름이 자동으로 생성되므로, 클래스 이름 중복이나 충돌 문제가 발생하지 않는다.
컴포넌트 기반 스타일 관리
스타일과 로직이 같은 파일에 있어, 관련 코드가 한 곳에 모여 있어 유지보수가 용이하다.
동적 스타일 적용
props를 이용해 상황에 따라 스타일을 조건부로 변경할 수 있다.
CSS 문법 그대로 사용 가능
기존 CSS 문법을 그대로 사용할 수 있어 진입장벽이 낮다.
다크모드나 테마 기능 구현 용이
ThemeProvider를 활용해 전체 애플리케이션에 일관된 스타일 테마를 적용할 수 있다.
런타임 성능 저하 가능성
JS에서 CSS를 처리하므로, 대규모 프로젝트나 반복 렌더링이 많은 경우 성능이 저하될 수 있다.
빌드 파일 크기 증가
CSS가 JS로 번들링되기 때문에, 전체 번들 크기가 커질 수 있다.
자동 완성 지원이 부족한 경우가 있다
일반 CSS나 SCSS에 비해 코드 자동완성이나 문법 강조 기능이 부족할 수 있다.
학습 비용
Styled-Components만의 문법과 사용법이 있어, 초반에는 학습이 필요하다.
서버사이드 렌더링(SSR) 설정 필요
Next.js 등에서 사용할 때는 별도의 설정이 필요하며, 초기 로딩 시 스타일이 깜빡이는 문제(FOUC)가 발생할 수 있다.
CSS-in-JS는 말 그대로 CSS를 JavaScript 안에서 작성하는 개념이다. 기존에는 .css 파일에 스타일을 작성하고, HTML 혹은 React 컴포넌트에서 className으로 연결했지만, CSS-in-JS는 이 과정을 JavaScript 코드 안에서 모두 처리하는 방식이다.
CSS를 별도의 파일로 분리하지 않고, JavaScript 코드 내부에 포함하여 작성하는 방식이다.
컴포넌트 기반 구조에 최적화되어 있으며, 스타일도 로직처럼 취급할 수 있다는 장점이 있다.
대표적인 CSS-in-JS 라이브러리로는 Styled-Components, Emotion, JSS, Stitches 등이 있다.
| 구분 | 설명 |
|---|---|
| 정의 위치 | JS 파일 안에서 CSS 작성 |
| 스타일 적용 방법 | 컴포넌트에 직접 스타일을 연결 |
| 동적 스타일링 | props나 state 등을 활용한 조건부 스타일 적용 가능 |
| 스코프 관리 | 자동으로 고유한 클래스명을 생성해 충돌을 방지 |
const Title = styled.h1`
color: ${props => props.active ? 'green' : 'gray'};
font-size: 2rem;
`;
이처럼, 자바스크립트 문법 안에서 변수를 활용하거나 조건을 줄 수 있는 것이 CSS-in-JS의 핵심이다.
컴포넌트와 스타일을 함께 관리 가능
스타일 중복이나 충돌 방지
동적 스타일링이 용이
자바스크립트 기능(함수, 조건문 등)을 스타일에 활용 가능
성능 이슈 (특히 큰 프로젝트에서 렌더링 시)
코드 복잡도 증가 가능
브라우저 개발자 도구에서 클래스명이 직관적이지 않을 수 있음

CDD는 Context-Driven Development의 약자로, 문맥 중심 개발 방식을 의미한다. 이는 일반적인 개발 방법론이라기보다는 문맥(Context)에 따라 유연하게 개발 방식을 선택하고 적용하자는 철학이나 접근 방식에 가깝다.
CDD는 고정된 프로세스를 따르기보다는, 현재 상황, 환경, 팀 구성, 요구사항 등에 따라 최적의 방법을 선택해서 개발을 진행하는 방식이다.
즉, "항상 이 방법이 최고야!"가 아니라,
→ “지금 우리 상황에는 어떤 방법이 가장 적합한가?”를 우선으로 고려한다.
모든 개발 환경은 다르다
프로젝트마다 요구사항, 제약, 사용 기술, 팀 역량 등이 다르므로 하나의 방식이 항상 정답이 될 수 없다.
문맥(Context)이 중요하다
개발 프로세스나 도구, 테스트 방식 등은 문맥에 따라 유동적으로 바뀔 수 있어야 한다.
유연성 + 실용성
이론보다는 실제 효과적인 결과를 우선시하며, 상황에 맞게 기존 방식도 과감히 바꾼다.
| 상황 | 적용 방식 (CDD 관점) |
|---|---|
| 스타트업 초기 | 빠른 피드백과 반복 배포 중심의 애자일 방식 |
| 대형 프로젝트 | 문서화와 테스트가 강화된 워터폴 방식 혼합 |
| 디자이너-개발자 협업 | 디자인 시스템과 컴포넌트 기반 개발 병행 |
| 테스트 여건 부족 | 자동화 테스트보다 수동 테스트 집중 |
상황에 맞는 최적의 전략 선택 가능
변화에 빠르게 대응 가능
불필요한 규칙/절차를 줄일 수 있음
실용주의적인 접근 방식
명확한 프로세스가 없어 팀마다 혼란이 생길 수 있음
경험이 부족한 경우 올바른 선택을 하기 어려움
표준화가 어렵고, 문서화가 소홀해질 수 있음