νλ‘ νΈμλ λμμΈ ν ν°κ³Ό κ·Έ μ΄μ μ μμλ³΄κ³ , μΉκ³Ό λͺ¨λ°μΌ μ± μ λ°μ κ±Έμ³ μΌκ΄μ±κ³Ό μ μ§λ³΄μμ±μ 보μ₯νλ ν¬λ‘μ€νλ«νΌ λμμΈ μμ€ν κ΅¬μΆ λ°©λ²μ νμν©λλ€.
νλ‘ νΈμλ λμμΈ ν ν°: ν¬λ‘μ€νλ«νΌ λμμΈ μμ€ν ꡬμΆνκΈ°
λμμμ΄ μ§ννλ νλ‘ νΈμλ κ°λ° νκ²½μμ μ¬λ¬ νλ«νΌκ³Ό μ ν리μΌμ΄μ μ κ±Έμ³ μΌκ΄μ±κ³Ό νμ₯μ±μ μ μ§νλ κ²μ μλΉν λμ μ΄ λ μ μμ΅λλ€. λμμΈ ν ν°μ λμμΈ κ²°μ μ λ¨μΌ μ§μ€ 곡κΈμ(single source of truth) μν μ νμ¬ μ§μ ν ν¬λ‘μ€νλ«νΌ λμμΈ μμ€ν μ κ°λ₯νκ² νλ κ°λ ₯ν μ루μ μ μ 곡ν©λλ€. μ΄ κΈμμλ λμμΈ ν ν°μ κ°λ κ³Ό μ΄μ , κ·Έλ¦¬κ³ ν¨κ³Όμ μΌλ‘ ꡬννλ λ°©λ²μ λν΄ μμΈν μμλ΄ λλ€.
λμμΈ ν ν°μ΄λ 무μμΈκ°?
λμμΈ ν ν°μ μμ, νμ΄ν¬κ·ΈλνΌ, κ°κ²©, ν¬κΈ°μ κ°μ λμμΈ μμ±μ μ μ₯νλ μ΄λ¦μ΄ μ§μ λ μν°ν°μ λλ€. λμμΈ ν ν°μ λμμΈ μμ€ν μ κΈ°λ³Έ κ°μΉλ₯Ό λνλ΄λ©°, μκ°μ μ€νμΌμ μ€μμμ κ΄λ¦¬νκ³ μ λ°μ΄νΈν μ μκ² ν΄μ€λλ€. μ½λμ μ§μ κ°μ νλμ½λ©νλ λμ λμμΈ ν ν°μ μ°Έμ‘°νμ¬ μΌκ΄μ±μ 보μ₯νκ³ ν₯ν μμ μ λ¨μνν©λλ€. λμμΈμ μν λ³μλΌκ³ μκ°ν μ μμ΅λλ€.
μμ:
// μ΄λ κ² νλ λμ :
button {
background-color: #007bff;
color: white;
font-size: 16px;
padding: 10px 20px;
}
// μ΄λ κ² μ¬μ©νμΈμ:
button {
background-color: {--color-primary};
color: {--color-text-light};
font-size: {--font-size-medium};
padding: {--spacing-medium};
}
λμμΈ ν ν° μ¬μ©μ μ΄μ
- μΌκ΄μ±: λͺ¨λ νλ«νΌκ³Ό μ ν리μΌμ΄μ μμ ν΅μΌλ μκ°μ κ²½νμ 보μ₯ν©λλ€.
- μ μ§λ³΄μμ±: μ½λλ₯Ό μ§μ μμ νμ§ μκ³ λ λμμΈ μ€νμΌμ μ½κ² μ λ°μ΄νΈν μ μμ΅λλ€.
- νμ₯μ±: μλ‘μ΄ νλ«νΌκ³Ό κΈ°λ₯μΌλ‘ λμμΈ μμ€ν μ νμ₯νλ κ³Όμ μ λ¨μνν©λλ€.
- ν λ§ μ μ©: μ΅μνμ λ Έλ ₯μΌλ‘ μ¬λ¬ ν λ§(μ: λΌμ΄νΈ, λ€ν¬, κ³ λλΉ)λ₯Ό μ§μν©λλ€.
- νμ : λμμ΄λμ κ°λ°μ κ°μ μν΅κ³Ό νμ μ μ΄μ§ν©λλ€.
- μ κ·Όμ±: μ κ·Όμ± μκ³ ν¬μ©μ μΈ μ¬μ©μ μΈν°νμ΄μ€λ₯Ό ꡬμΆνκΈ° μν κΈ°λ°μ μ 곡ν©λλ€.
ν¬λ‘μ€νλ«νΌ λμμΈ μμ€ν
ν¬λ‘μ€νλ«νΌ λμμΈ μμ€ν μ μΉ, iOS, Android, λ°μ€ν¬ν± μ ν리μΌμ΄μ μ ν¬ν¨ν λ€μν κΈ°κΈ°μ μ΄μ 체μ μμ μΌκ΄λ μ¬μ©μ κ²½νμ μ 곡νλ κ²μ λͺ©νλ‘ ν©λλ€. λμμΈ ν ν°μ λμμΈ κ²°μ μ νΉμ νλ«νΌκ³Ό κΈ°μ λ‘λΆν° μΆμννκΈ° λλ¬Έμ μ΄ λͺ©νλ₯Ό λ¬μ±νλ λ° λ§€μ° μ€μν©λλ€. μ΄λ¬ν μΆμνλ₯Ό ν΅ν΄ λμμΈ κ°μ ν λ² μ μν λ€μ λͺ¨λ μ ν리μΌμ΄μ μ μΌκ΄λκ² μ μ©ν μ μμ΅λλ€.
ν¬λ‘μ€νλ«νΌ κ°λ°μ κ³Όμ
μ¬λ¬ νλ«νΌμ μν κ°λ°μ λͺ κ°μ§ κ³Όμ λ₯Ό μ μν©λλ€:
- νλ«νΌλ³ μ½λ: κ° νλ«νΌμ μ체 μ½λλ² μ΄μ€μ μ€νμΌλ§ κΈ°μ (μ: μΉμ© CSS, iOSμ© Swift, Androidμ© Kotlin)μ΄ νμν©λλ€.
- μΌκ΄μ± μλ λμμΈ: ν΅μΌλ μ κ·Ό λ°©μ μμ΄λ μ¬λ¬ λ€λ₯Έ νλ«νΌμμ μκ°μ μΌκ΄μ±μ μ μ§νκΈ° μ΄λ ΅μ΅λλ€.
- κ°λ° μκ° μ¦κ°: λ³λμ μ½λλ² μ΄μ€λ₯Ό κ°λ°νκ³ μ μ§ κ΄λ¦¬νλ©΄ κ°λ° μκ°κ³Ό λΉμ©μ΄ μ¦κ°ν©λλ€.
- μ μ§λ³΄μ λΆλ΄: μ¬λ¬ νλ«νΌμ κ±Έμ³ λμμΈ μ€νμΌμ λκΈ°ν μνλ‘ μ μ§νλ €λ©΄ μλΉν λ Έλ ₯μ΄ νμν©λλ€.
λμμΈ ν ν°μ΄ μ΄λ¬ν κ³Όμ λ₯Ό ν΄κ²°νλ λ°©λ²
λμμΈ ν ν°μ μ¬λ¬ νλ«νΌμμ μ½κ² μ¬μ©ν μ μλ λμμΈ κ°μ μ€μ μ μ₯μλ₯Ό μ 곡ν¨μΌλ‘μ¨ μ΄λ¬ν κ³Όμ λ₯Ό ν΄κ²°ν©λλ€. νλμ½λ©λ κ° λμ λμμΈ ν ν°μ μ°Έμ‘°ν¨μΌλ‘μ¨, κΈ°λ° κΈ°μ μ κ΄κ³μμ΄ μ ν리μΌμ΄μ μ΄ μΌκ΄λ λμμΈ μΈμ΄λ₯Ό μ€μνλλ‘ λ³΄μ₯ν μ μμ΅λλ€.
λμμΈ ν ν° κ΅¬ννκΈ°
λμμΈ ν ν°μ ꡬννλ λ°λ λͺ κ°μ§ λ¨κ³κ° ν¬ν¨λ©λλ€:
- λμμΈ μμ€ν μ μ: μμ, νμ΄ν¬κ·ΈλνΌ, κ°κ²©, ν¬κΈ° λ± λμμΈ ν ν°μΌλ‘ κ΄λ¦¬νκ³ μ νλ ν΅μ¬ λμμΈ μμλ₯Ό μλ³ν©λλ€.
- ν ν° νμ μ ν: λμμΈ ν ν°μ μ μ₯ν νμμ μ νν©λλ€. μΌλ°μ μΈ νμμλ JSON, YAML, XMLμ΄ μμ΅λλ€.
- ν ν° μ μ μμ±: μ νν νμμΌλ‘ λμμΈ ν ν°μ μ μν©λλ€.
- μ€νμΌ λμ λ리 μ¬μ©: μ€νμΌ λμ λ리 λꡬλ₯Ό νμ©νμ¬ λμμΈ ν ν°μ νλ«νΌλ³ νμ(μ: CSS λ³μ, Swift μμ, Kotlin μμ)μΌλ‘ λ³νν©λλ€.
- μ½λλ² μ΄μ€μ ν΅ν©: μμ±λ νλ«νΌλ³ κ°μ μ½λλ² μ΄μ€μμ μ°Έμ‘°ν©λλ€.
- νλ‘μΈμ€ μλν: λ³κ²½ μ¬νμ΄ λ°μν λλ§λ€ λμμΈ ν ν°μ μμ±νκ³ μ λ°μ΄νΈνλ μλνλ λΉλ νλ‘μΈμ€λ₯Ό μ€μ ν©λλ€.
λ¨κ³λ³ μμ: JSONκ³Ό Style Dictionaryλ‘ λμμΈ ν ν° λ§λ€κΈ°
JSONκ³Ό Style Dictionaryλ₯Ό μ¬μ©νμ¬ λμμΈ ν ν°μ λ§λλ μμλ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€.
- λμμΈ ν ν°μ© JSON νμΌ μμ± (μ: `tokens.json`):
{
"color": {
"primary": {
"value": "#007bff",
"comment": "κΈ°λ³Έ λΈλλ μμ"
},
"secondary": {
"value": "#6c757d",
"comment": "보쑰 λΈλλ μμ"
},
"text": {
"light": {
"value": "#ffffff",
"comment": "λ°μ ν
μ€νΈ μμ"
},
"dark": {
"value": "#212529",
"comment": "μ΄λμ΄ ν
μ€νΈ μμ"
}
}
},
"font": {
"size": {
"small": {
"value": "12px",
"comment": "μμ κΈκΌ΄ ν¬κΈ°"
},
"medium": {
"value": "16px",
"comment": "μ€κ° κΈκΌ΄ ν¬κΈ°"
},
"large": {
"value": "20px",
"comment": "ν° κΈκΌ΄ ν¬κΈ°"
}
},
"family": {
"base": {
"value": "Arial, sans-serif",
"comment": "κΈ°λ³Έ κΈκΌ΄ κ³μ΄"
}
}
},
"spacing": {
"small": {
"value": "8px",
"comment": "μμ κ°κ²©"
},
"medium": {
"value": "16px",
"comment": "μ€κ° κ°κ²©"
},
"large": {
"value": "24px",
"comment": "ν° κ°κ²©"
}
}
}
- Style Dictionary μ€μΉ:
npm install -g style-dictionary
- Style Dictionary κ΅¬μ± νμΌ μμ± (μ: `config.json`):
{
"source": ["tokens.json"],
"platforms": {
"web": {
"transformGroup": "css",
"buildPath": "build/web/",
"files": [{
"destination": "variables.css",
"format": "css/variables"
}]
},
"ios": {
"transformGroup": "ios",
"buildPath": "build/ios/",
"files": [{
"destination": "StyleDictionaryColor.h",
"format": "ios/colors.h",
"className": "StyleDictionaryColor",
"type": "Color"
}, {
"destination": "StyleDictionarySize.h",
"format": "ios/sizes.h",
"className": "StyleDictionarySize",
"type": "Size"
}]
},
"android": {
"transformGroup": "android",
"buildPath": "build/android/",
"files": [{
"destination": "colors.xml",
"format": "android/colors"
}, {
"destination": "dimens.xml",
"format": "android/dimens"
}]
}
}
}
- Style Dictionary μ€ν:
style-dictionary build
μ΄ λͺ λ Ήμ΄λ `build` λλ ν°λ¦¬μ νλ«νΌλ³ νμΌμ μμ±ν©λλ€:
- μΉ: `build/web/variables.css` (CSS λ³μ)
- iOS: `build/ios/StyleDictionaryColor.h`, `build/ios/StyleDictionarySize.h` (Objective-C ν€λ νμΌ)
- Android: `build/android/colors.xml`, `build/android/dimens.xml` (XML 리μμ€ νμΌ)
- μ½λλ² μ΄μ€μ ν΅ν©:
μΉ (CSS):
@import "build/web/variables.css";
button {
background-color: var(--color-primary);
color: var(--color-text-light);
font-size: var(--font-size-medium);
padding: var(--spacing-medium);
}
iOS (Objective-C):
#import "StyleDictionaryColor.h" #import "StyleDictionarySize.h" UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; button.backgroundColor = [StyleDictionaryColor colorPrimary]; [button setTitleColor:[StyleDictionaryColor colorTextLight] forState:UIControlStateNormal]; button.titleLabel.font = [UIFont systemFontOfSize:[StyleDictionarySize fontSizeMedium]]; button.contentEdgeInsets = UIEdgeInsetsMake([StyleDictionarySize spacingMedium], [StyleDictionarySize spacingMedium], [StyleDictionarySize spacingMedium], [StyleDictionarySize spacingMedium]);
Android (XML):
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/color_primary"
android:textColor="@color/color_text_light"
android:textSize="@dimen/font_size_medium"
android:padding="@dimen/spacing_medium"/>
Style Dictionary λμ
Style Dictionaryκ° μΈκΈ° μλ μ νμ§μ΄μ§λ§, λμμΈ ν ν°μ κ΄λ¦¬νκ³ λ³ννλ λ° μ¬μ©ν μ μλ λ€λ₯Έ λꡬλ€λ μμ΅λλ€:
- Theo: Salesforceμμ λ§λ λμμΈ ν ν° λ³νκΈ°μ λλ€.
- Specify: Figma, Sketchμ κ°μ λμμΈ λꡬμ ν΅ν©λλ λμμΈ λ°μ΄ν° νλ«νΌμ λλ€.
- Superposition: κΈ°μ‘΄ μΉμ¬μ΄νΈμμ λμμΈ ν ν°μ μμ±νλ λꡬμ λλ€.
κ³ κΈ κ°λ
μλ§¨ν± ν ν°
μλ§¨ν± ν ν°μ νΉμ κ°μ΄ μλ λμμΈ μμμ λͺ©μ μ΄λ μλ―Έλ₯Ό λνλ΄λ λμμΈ ν ν°μ λλ€. μ΄λ λ λ€λ₯Έ μΆμν κ³μΈ΅μ μΆκ°νμ¬ λ ν° μ μ°μ±κ³Ό μ μμ±μ μ 곡ν©λλ€. μλ₯Ό λ€μ΄, κΈ°λ³Έ λΈλλ μμμ λν ν ν°μ μ μνλ λμ , κΈ°λ³Έ μ‘μ λ²νΌμ μμμ λν ν ν°μ μ μν μ μμ΅λλ€.
μμ:
// μ΄λ κ² νλ λμ :
"color": {
"primary": {
"value": "#007bff"
}
}
// μ΄λ κ² μ¬μ©νμΈμ:
"color": {
"button": {
"primary": {
"background": {
"value": "#007bff",
"comment": "κΈ°λ³Έ μ‘μ
λ²νΌμ λ°°κ²½μ"
}
}
}
}
λμμΈ ν ν°μ μ΄μ©ν ν λ§ μ μ©
λμμΈ ν ν°μ μ¬μ©νλ©΄ μ ν리μΌμ΄μ μμ μ¬λ¬ ν λ§λ₯Ό μ½κ² μ§μν μ μμ΅λλ€. κ° ν λ§μ λν΄ λ€λ₯Έ λμμΈ ν ν° κ° μΈνΈλ₯Ό λ§λ€μ΄ ν ν° νμΌμ κ΅μ²΄νλ κ²λ§μΌλ‘ κ°λ¨νκ² ν λ§λ₯Ό μ νν μ μμ΅λλ€.
μμ:
λΌμ΄νΈ ν λ§μ λ€ν¬ ν λ§λ₯Ό μν λ³λμ ν ν° νμΌμ λ§λλλ€:
- `tokens-light.json`
- `tokens-dark.json`
κ΅¬μ± νμΌμμ νμ¬ ν λ§μ λ°λΌ μ¬μ©ν ν ν° νμΌμ μ§μ ν©λλ€:
{
"source": ["tokens-light.json"], // λλ tokens-dark.json
"platforms": { ... }
}
μ κ·Όμ± κ³ λ €μ¬ν
λμμΈ ν ν°μ μ ν리μΌμ΄μ μ μ κ·Όμ±μ ν₯μμν€λ λ°μλ μν μ ν μ μμ΅λλ€. λͺ μλΉ, κΈκΌ΄ ν¬κΈ° λ° κΈ°ν μ κ·Όμ± κ΄λ ¨ μμ±μ λν ν ν°μ μ μν¨μΌλ‘μ¨ λμμΈμ΄ μ κ·Όμ± νμ€μ μΆ©μ‘±νλλ‘ λ³΄μ₯ν μ μμ΅λλ€.
μμ:
"color": {
"text": {
"onPrimary": {
"value": "#ffffff",
"comment": "κΈ°λ³Έ λ°°κ²½ μμ ν
μ€νΈ μμ",
"attributes": {
"contrastRatio": "4.5:1" // WCAG AA μ΅μ λͺ
μλΉ
}
}
}
}
λμμΈ ν ν° μ¬μ©μ μν λͺ¨λ² μ¬λ‘
- μκ² μμνκΈ°: κ°μ₯ μμ£Ό μ¬μ©λλ λμμΈ μμμ λν ν ν°λΆν° μ μλ₯Ό μμν©λλ€.
- μλ―Έ μλ μ΄λ¦ μ¬μ©: κ° ν ν°μ λͺ©μ μ λͺ ννκ² μ€λͺ νλ μ΄λ¦μ μ νν©λλ€.
- λ Όλ¦¬μ μΌλ‘ ν ν° κ·Έλ£Ήν: μ μ§λ³΄μμ±μ ν₯μμν€κΈ° μν΄ ν ν°μ μΉ΄ν κ³ λ¦¬μ νμ μΉ΄ν κ³ λ¦¬λ‘ κ΅¬μ±ν©λλ€.
- ν ν° λ¬Έμν: κ° ν ν°μ λν΄ λͺ©μ κ³Ό μ¬μ©λ²μ ν¬ν¨ν λͺ νν λ¬Έμλ₯Ό μ 곡ν©λλ€.
- νλ‘μΈμ€ μλν: λμμΈ ν ν°μ μμ±νκ³ μ λ°μ΄νΈνλ μλνλ λΉλ νλ‘μΈμ€λ₯Ό μ€μ ν©λλ€.
- μ² μ ν ν μ€νΈ: λͺ¨λ νλ«νΌκ³Ό κΈ°κΈ°μμ λμμΈ ν ν°μ ν μ€νΈνμ¬ μΌκ΄μ±μ 보μ₯ν©λλ€.
- λ²μ κ΄λ¦¬ μ¬μ©: λ²μ κ΄λ¦¬ μμ€ν μ μ¬μ©νμ¬ λμμΈ ν ν°μ λ³κ²½ μ¬νμ μΆμ ν©λλ€.
μ€μ μ¬μ© μ¬λ‘
λ§μ λκ·λͺ¨ μ‘°μ§λ€μ΄ λμμΈ ν ν°μ μ¬μ©νμ¬ λμμΈ μμ€ν μ μ±κ³΅μ μΌλ‘ ꡬννμ΅λλ€. λͺ κ°μ§ μ£Όλͺ©ν λ§ν μλ λ€μκ³Ό κ°μ΅λλ€:
- Salesforce Lightning Design System (SLDS): SLDSλ λͺ¨λ Salesforce μ νμμ μΌκ΄λ μ¬μ©μ κ²½νμ λ§λ€κΈ° μν΄ λμμΈ ν ν°μ κ΄λ²μνκ² μ¬μ©ν©λλ€.
- Google Material Design: Material Designμ Android, μΉ λ° κΈ°ν νλ«νΌμμ μκ°μ μ€νμΌμ κ΄λ¦¬νκΈ° μν΄ λμμΈ ν ν°μ μ¬μ©ν©λλ€.
- IBM Carbon Design System: Carbonμ IBMμ λ€μν μ ν ν¬νΈν΄λ¦¬μ€ μ λ°μ κ±Έμ³ μΌκ΄μ±μ 보μ₯νκΈ° μν΄ λμμΈ ν ν°μ νμ©ν©λλ€.
- Atlassian Design System: Atlassianμ λμμΈ μμ€ν μ Jira, Confluence λ° κΈ°ν Atlassian μ νμμ ν΅μΌλ κ²½νμ λ§λ€κΈ° μν΄ λμμΈ ν ν°μ νμ©ν©λλ€.
λμμΈ ν ν°μ λ―Έλ
λμμΈ ν ν°μ νλ‘ νΈμλ κ°λ° μΈκ³μμ μ μ λ μ€μν΄μ§κ³ μμ΅λλ€. μ ν리μΌμ΄μ μ΄ λμ± λ³΅μ‘ν΄μ§κ³ ν¬λ‘μ€νλ«νΌ κ°λ°μ΄ 보νΈνλ¨μ λ°λΌ, λμμΈ κ΄λ¦¬μ λν ν΅ν©λ μ κ·Ό λ°©μμ νμμ±μ κ³μν΄μ μ»€μ§ κ²μ λλ€. λμμΈ ν ν° κΈ°μ μ λ―Έλ λ°μ μλ λ€μμ΄ ν¬ν¨λ μ μμ΅λλ€:
- λμμΈ λꡬμμ ν₯μλ ν΅ν©: Figma, Sketchμ κ°μ λμμΈ λꡬμμ μνν ν΅ν©μ λμμΈμμ κ°λ°κΉμ§μ μν¬νλ‘μ°λ₯Ό λμ± κ°μνν κ²μ λλ€.
- λ μ§λ³΄λ λ³ν κΈ°λ₯: λ μ κ΅ν λ³ν κΈ°λ₯μ λ ν° μ μ°μ±κ³Ό μ¬μ©μ μ μλ₯Ό κ°λ₯νκ² ν κ²μ λλ€.
- νμ€ν: μ°μ νμ€μ λ±μ₯μ μνΈ μ΄μ©μ±μ μ΄μ§νκ³ λμμΈ ν ν° μ±ν κ³Όμ μ λ¨μνν κ²μ λλ€.
κ²°λ‘
νλ‘ νΈμλ λμμΈ ν ν°μ ν¬λ‘μ€νλ«νΌ λμμΈ μμ€ν μ ꡬμΆνκΈ° μν κ°λ ₯ν λꡬμ λλ€. λμμΈ κ²°μ μ λν λ¨μΌ μ§μ€ 곡κΈμμ μ 곡ν¨μΌλ‘μ¨ μΉ λ° λͺ¨λ°μΌ μ ν리μΌμ΄μ μ λ°μ κ±Έμ³ μΌκ΄μ±, μ μ§λ³΄μμ±, νμ₯μ±μ κ°λ₯νκ² ν©λλ€. μκ·λͺ¨ νλ‘μ νΈμμ μμ νλ λκ·λͺ¨ μν°νλΌμ΄μ¦ μ ν리μΌμ΄μ μμ μμ νλ , λμμΈ μν¬νλ‘μ°λ₯Ό κ°μ νκ³ λ μμ§λ ₯ μλ μ¬μ©μ κ²½νμ λ§λ€κΈ° μν΄ λμμΈ ν ν°μ μ±ννλ κ²μ κ³ λ €ν΄ λ³΄μμμ€. λμμΈ ν ν°μ μμ©νλ κ²μ λμμΈ μμ€ν μ λ―Έλμ λν ν¬μμ΄λ©°, λͺ¨λ νλ«νΌκ³Ό μ ν리μΌμ΄μ μμ μ μ κ°λ₯νκ³ νμ₯ κ°λ₯νλ©° μΌκ΄μ±μ μ μ§νλλ‘ λ³΄μ₯ν©λλ€.