Intro
Tailwind로 스타일링을 해오던 중, CSS-in-JS로 구현하면 어떤 차이가 있을지 궁금해졌습니다. 그러던 중 관련 아티클을 접하게 되었고, 읽으면서 새롭게 알게 된 개념과 인사이트를 정리해 보았습니다. 이번 글에서는 단순한 코드 변환을 넘어, 두 방식이 코드를 구조화하는 방식과 개발 흐름에 주는 영향을 함께 살펴보겠습니다.
1. CSS 변수 기본 개념
CSS 변수는 특정 요소와 그 하위 요소에서만 유효한 스코프를 가집니다. 변수는 --
로 시작하며, CSS 속성 값 어디서든 사용할 수 있습니다.
<style>
p {
--highlight-color: yellow;
}
em {
background: var(--highlight-color);
}
</style>
<p>This <em>emphasized</em> text works!</p>
<h1>This <em>won't work</em></h1>
전역에서 사용하려면 html
이나 :root
에 선언하여 모든 요소에서 접근 가능하게 합니다.
:root {
--color-red: hsl(0deg, 80%, 50%);
}
2. React에서의 활용
React에서는 CSS 변수를 직접 사용할 수도 있고, ThemeProvider
를 통해 스타일 토큰을 관리할 수도 있습니다.
ThemeProvider 방식
컴포넌트에 타입 지원과 구조화를 제공하지만, 값 변경을 위해선 React 렌더링이 필요합니다.
<ThemeProvider theme={{ colors: { primary: 'rebeccapurple' }}}>
<Button>Click</Button>
</ThemeProvider>
const Button = styled.button`
background: ${(props) => props.theme.colors.primary};
`;
CSS 변수 방식
전역 스타일에서 변수로 정의하면, CSS 내 어디서든 var(--변수명)
으로 접근할 수 있습니다. 값 변경 시 전체 UI에 즉시 반영됩니다.
const GlobalStyles = createGlobalStyle`
html {
--color-primary: rebeccapurple;
}
`;
const Button = styled.button`
background: var(--color-primary);
`;
CSS 변수는 JS로 읽고 변경도 가능합니다.
getComputedStyle(document.documentElement)
.getPropertyValue('--color-primary');
document.documentElement.style.setProperty(
'--color-primary', 'hsl(245deg, 100%, 60%)'
);
3. 반응형 설계 – 입력 방식 기준
전통적인 max-width
기반 미디어 쿼리 대신, 입력 방식에 따라 스타일을 변경하면 UX 정확도가 높아집니다.
html { --min-tap-target-height: 32px; }
@media (pointer: coarse) {
html { --min-tap-target-height: 48px; }
}
button, input { min-height: var(--min-tap-target-height); }
pointer: coarse
→ 손가락 위주의 터치 입력
pointer: fine
→ 마우스나 펜과 같이 정밀한 입력
4. 다크모드 적용
다크모드는 CSS 변수 값만 바꿔 전체 UI 색상을 변경할 수 있습니다.
html {
--color-text: black;
--color-background: white;
}
@media (prefers-color-scheme: dark) {
html {
--color-text: white;
--color-background: black;
}
}
prefers-color-scheme
미디어 쿼리를 사용하면, 사용자 시스템 설정에 맞춰 자동 적용됩니다.
5. 읽고 나서 배운 점
- CSS 변수 스코프의 중요성:
- 선언된 위치와 계층 구조에 따라 변수의 적용 범위가 결정된다는 것을 알았습니다.
- 입력 방식 기반 반응형 설계:
- 화면 크기가 아닌 입력 장치 특성에 맞춘 디자인이 더 정확한 UX를 제공할 수 있다는 사실을 알았습니다.
- ThemeProvider와 CSS 변수 비교:
- ThemeProvider는 타입·구조 관리에 강점, CSS 변수는 선언과 변경이 간결하며 전역 적용이 쉽습니다.
6. 적용 아이디어
- 입력 방식 기반 반응형을 설계해보기
- 언제 어느 방식이 좋을지 좋은 UX를 고민해봐야겠습니다.
- JS 이벤트 기반 실시간 테마 변경해보기
7. 참고 링크
- https://velog.io/@cookie004/css-variables-for-react-devs
- https://css-for-js.dev/