emotion
에서 타이포그래피와 컬러같은 디자인시스템 변수들을 어떻게 정의하는 게 좋을까GlobalStyles
는 애플리케이션 전역에 영향을 미치는 스타일을 정의할 때 사용됨. 이를 통해 특정 HTML 요소(예: body
, h1
, p
)의 기본 스타일을 지정하거나, 리셋 스타일(CSS Reset)을 적용할 수 있다. GlobalStyles
는 한 번 설정하면 애플리케이션 전체에서 적용되며, 주로 전역적인 리셋이나 기본 레이아웃을 설정하는 데 적합하다.
여기에 css 변수로서 디자인 토큰을 정의하면 IDE의 자동완성 도움을 받기가 어려웠다.
예시
import { Global, css } from '@emotion/react';
const globalStyles = css({
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
':root' : {
'--display-bold24': `700 24px 'Pretendard-Variable'`,
'--display-bold16': `700 16px 'Pretendard-Variable'`,
'--text-strong': '#888888',
'--text-bold': '#666666',
},
})
export function GlobalStyles(){
return(
<Global styles={globalStyles} />
)
}
styles/Variables.ts 파일에 객체로 정의해서 Variables.typography.font_bold_24
과 같은 형태로 자동완성의 도움을 도움을 받으면서 활용하는 방법도 있다. 무난한 방법이나 버튼 하나만 눌러서 라이트/다크 모드를 전환하게 하는 데에는 썩 좋은 방법은 아닐수도 있겠다.
export const Variables = {
colors: {
primary: '#fe4902',
surface_default: '#F8F8F8',
surface_strong: '#434343',
// ...
},
typography: {
font_medium_20: '500 20px "Pretendard-Variable", sans-serif',
font_medium_16: '500 16px "Pretendard-Variable", sans-serif',
font_bold_72: '700 72px "Pretendard-Variable", sans-serif',
font_bold_56: '700 56px "Pretendard-Variable", sans-serif',
// ...
},
shadow: {
shadow_floating: '0px 4px 8px #00000040'
}
};
import { Variables } from '../styles/Variables';
import { css } from '@emotion/react';
const startButtonStyle = css({
font: Variables.typography.font_bold_24,
color: Variables.colors.text_white,
backgroundColor: Variables.colors.surface_point,
padding: '24px 48px',
borderRadius: 32,
':hover': {
opacity: 0.8
}
});
Theme
는 Emotion의 ThemeProvider
를 통해 구성되며, 디자인 시스템의 일관성을 유지하는 데 유용하다. Theme
에 정의된 값은 컴포넌트에서 사용할 수 있으며, 주로 색상, 타이포그래피, 간격, 그림자 등 일관된 디자인 요소를 제공하는 데 사용된다. Theme
를 사용하면 디자인 시스템을 재사용 가능하고 유지 관리하기 쉽게 만들 수 있다.
단, 타입스크립트 환경에서는 emotion에서 theme을 사용하기 위해서는 emotion.d.ts라는 별도의 type 정의 파일을 만들어야 한다.
예시
// theme.ts
const theme = {
colors: {
primary: '#3498db',
secondary: '#2ecc71',
text: '#333',
},
typography: {
fontSizeLarge: '2rem',
fontWeightBold: 700,
},
};
export default theme;
// emotion.d.ts
import '@emotion/react'
import {theme} from './theme'
type ThemeTpye = typeof theme
declare module '@emotion/react' {
export interface Theme extends ThemeTpye {}
}
// ThemeProvider 사용
import { ThemeProvider } from '@emotion/react'
const theme = {
colors: {
primary: 'hotpink'
}
}
render(
<ThemeProvider theme={theme}>
<div css={theme => ({ color: theme.colors.primary })}>some other text</div>
</ThemeProvider>
)