Emotion, CSS-in-JS λΌμ΄λΈλ¬λ¦¬ - 컀μ€ν°λ§μ΄μ§ κ°λ₯ν ν λ§μ μ€νμΌ μμ€ν ꡬμΆ
νλ μΉ μ ν리μΌμ΄μ μ μ¬μ©μ κ°κ°μΈμ μ·¨ν₯κ³Ό νκ²½μ λ§μΆ λ§μΆ€ν UIλ₯Ό μ 곡νλ κ²μ΄ μ€μν κ²½μλ ₯μΌλ‘ μμ©ν©λλ€. νΉν 리μ‘νΈ μ»΄ν¬λνΈλ₯Ό νμ©ν κ°λ°μμλ ν λ§μ μ€νμΌ μμ€ν μ μ μ°νκ² κ΅¬μ±νμ¬, μ¬μ©μκ° λμ μΌλ‘ μΈν°νμ΄μ€μ μμ, ν°νΈ, λ μ΄μμ λ±μ λ³κ²½ν μ μλλ‘ μ§μν μ μμ΅λλ€. μ΄λ² ν¬μ€ν μμλ CSS-in-JS κΈ°λ²μ μ€μ¬μΌλ‘ Styled Components, Emotion λ±μ λΌμ΄λΈλ¬λ¦¬λ₯Ό νμ©νμ¬ μ»€μ€ν°λ§μ΄μ§ κ°λ₯ν ν λ§μ μ€νμΌ μμ€ν μ ꡬμΆνλ λ°©λ²μ μμΈν μκ°νκ² μ΅λλ€.
νμκ° νμ μμ νλ‘μ νΈλ§λ€ μ΄λ° μμ€ν ꡬμΆμ λν΄μ κ°μ‘°νμ§λ§ λ²λ²μ΄ κΉμμ΅λλ€. μ΄μ λ λΉμ©μ΄μ£ . μ¬μ€ λΉμ©μ΄ λ λ€ κ±΄ μμ΅λλ€. μ κ° μ΄μ΄ μμλ νμΈμ§, κΈ°νμλ€μ΄ μ΄λ° λμμΈμ μ΅μνμ§ μμΌλ μ΄ν΄λ₯Ό λͺ» ν΄μ μ νλ κ±°μμ΅λλ€. κ°λ°μμ κΈ°νμλ μκ·Ήμ΄μ£ . γ
ν λ§μ μ€νμΌ μμ€ν μ νμμ±
κΈ°μ‘΄μ μ μ CSS νμΌλ‘ μ€νμΌμ κ΄λ¦¬νλ λ°©μμ νλ‘μ νΈκ° 컀μ§μλ‘ μ μ§λ³΄μκ° μ΄λ €μμ§κ³ , λ€μν μ¬μ©μ νκ²½μ λμνκΈ° μ΄λ ΅λ€λ λ¨μ μ κ°μ§κ³ μμ΅λλ€. μ΄μ λ°ν΄, CSS-in-JSλ μλ°μ€ν¬λ¦½νΈ μ½λ λ΄μμ μ€νμΌμ μ μν¨μΌλ‘μ¨ λμ μΈ μ€νμΌ λ³κ²½ λ° μ»΄ν¬λνΈ λ¨μμ μΊ‘μνλ₯Ό κ°λ₯νκ² ν©λλ€. μ΄λ₯Ό ν΅ν΄ λ€μκ³Ό κ°μ μ΄μ μ λ릴 μ μμ΅λλ€.
- λμ ν λ§ μ ν: μ¬μ©μ μ€μ , λ€ν¬ λͺ¨λ, κ³ λλΉ λͺ¨λ λ± λ€μν ν λ§λ₯Ό μμ½κ² μ μ©ν μ μμ΅λλ€.
- μ»΄ν¬λνΈ κΈ°λ° μ€νμΌ κ΄λ¦¬: κ° μ»΄ν¬λνΈμ μ μ©λλ μ€νμΌμ μΊ‘μννμ¬, μ½λ μ¬μ¬μ©μ±κ³Ό μ μ§λ³΄μμ±μ λμ λλ€.
- μ μ§λ³΄μμ νμ₯μ±: νλ‘μ νΈ κ·λͺ¨κ° 컀μ§λλΌλ μΌκ΄λ μ€νμΌ κ°μ΄λλΌμΈμ μ μ©ν μ μμΌλ©°, ν λ§ λ³κ²½μ΄ μ 체 μ ν리μΌμ΄μ μ μ¦κ° λ°μλ©λλ€.
CSS-in-JS λΌμ΄λΈλ¬λ¦¬: Styled Componentsμ Emotion
Styled Components
Styled Componentsλ 리μ‘νΈμμ κ°μ₯ λ리 μ¬μ©λλ CSS-in-JS λΌμ΄λΈλ¬λ¦¬ μ€ νλλ‘, μλ°μ€ν¬λ¦½νΈ νμΌ λ΄μμ CSSλ₯Ό μμ±νκ³ μ»΄ν¬λνΈμ μ§μ μ°κ²°ν μ μλ λ°©μμ λλ€. μ΄λ₯Ό ν΅ν΄ μ»΄ν¬λνΈ λ³λ‘ λ 립μ μΈ μ€νμΌμ μ μ©ν μ μμΌλ©°, λμ νλ‘νΌν°λ₯Ό κΈ°λ°μΌλ‘ μ€νμΌμ λ³νμν¬ μ μμ΅λλ€.
μλλ Styled Componentsλ₯Ό νμ©νμ¬ κΈ°λ³Έ ν λ§λ₯Ό μ μ©νκ³ , λ€ν¬ λͺ¨λμ λΌμ΄νΈ λͺ¨λλ₯Ό μ νν μ μλ μμ μ λλ€.
import React, { useState } from 'react';
import styled, { ThemeProvider } from 'styled-components';
// κΈ°λ³Έ ν
λ§ μ μ
const lightTheme = {
background: '#ffffff',
text: '#333333',
primary: '#1976d2',
};
const darkTheme = {
background: '#333333',
text: '#ffffff',
primary: '#90caf9',
};
const Container = styled.div`
background-color: ${(props) => props.theme.background};
color: ${(props) => props.theme.text};
min-height: 100vh;
padding: 20px;
transition: background-color 0.3s ease, color 0.3s ease;
`;
const Button = styled.button`
background-color: ${(props) => props.theme.primary};
border: none;
color: ${(props) => props.theme.text};
padding: 10px 20px;
font-size: 1rem;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
&:hover {
opacity: 0.8;
}
`;
const Title = styled.h2`
font-size: 2rem;
margin-bottom: 20px;
`;
const ThemedComponent = () => {
const [theme, setTheme] = useState(lightTheme);
const toggleTheme = () => {
setTheme(theme === lightTheme ? darkTheme : lightTheme);
};
return (
<ThemeProvider theme={theme}>
<Container>
<Title>컀μ€ν°λ§μ΄μ§ κ°λ₯ν ν
λ§μ μ€νμΌ μμ€ν
</Title>
<p>Styled Componentsλ₯Ό νμ©νμ¬ λ¦¬μ‘νΈ μ»΄ν¬λνΈμ ν
λ§λ₯Ό λμ μΌλ‘ λ³κ²½ν μ μμ΅λλ€.</p>
<Button onClick={toggleTheme}>ν
λ§ μ ν</Button>
</Container>
</ThemeProvider>
);
};
export default ThemedComponent;
μ μμ λ μ¬μ©μκ° λ²νΌ ν΄λ¦ μ λΌμ΄νΈ λͺ¨λμ λ€ν¬ λͺ¨λλ₯Ό μ νν μ μλλ‘ κ΅¬μ±λμ΄ μμ΅λλ€. ThemeProviderλ₯Ό ν΅ν΄ μ μμμ μ¬μ©ν ν λ§λ₯Ό μ€μ νκ³ , κ° μ»΄ν¬λνΈλ propsλ₯Ό ν΅ν΄ ν΄λΉ ν λ§ κ°μ λ°μ μ€νμΌμ λμ μΌλ‘ μ μ©ν©λλ€.
Emotion
Emotion μμ Styled Componentsμ μ μ¬ν λ°©μμΌλ‘ CSS-in-JSλ₯Ό ꡬνν μ μλ κ°λ ₯ν λΌμ΄λΈλ¬λ¦¬μ λλ€. Emotionμ λΉ λ₯Έ λ λλ§ μ±λ₯κ³Ό μ μ°ν APIλ₯Ό μ 곡νμ¬, 볡μ‘ν μ λλ©μ΄μ μ΄λ λμ μ€νμΌλ§μλ ν¨κ³Όμ μΌλ‘ λμν μ μμ΅λλ€.
μλλ Emotionμ νμ©νμ¬ ν λ§ μ ν κΈ°λ₯μ ꡬννλ μμ μ λλ€.
/** @jsxImportSource @emotion/react */
import React, { useState } from 'react';
import { css, ThemeProvider } from '@emotion/react';
const lightTheme = {
background: '#ffffff',
text: '#333333',
primary: '#1976d2',
};
const darkTheme = {
background: '#333333',
text: '#ffffff',
primary: '#90caf9',
};
const containerStyle = (theme) => css`
background-color: ${theme.background};
color: ${theme.text};
min-height: 100vh;
padding: 20px;
transition: background-color 0.3s ease, color 0.3s ease;
`;
const buttonStyle = (theme) => css`
background-color: ${theme.primary};
border: none;
color: ${theme.text};
padding: 10px 20px;
font-size: 1rem;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
&:hover {
opacity: 0.8;
}
`;
const ThemedEmotionComponent = () => {
const [theme, setTheme] = useState(lightTheme);
const toggleTheme = () => {
setTheme(theme === lightTheme ? darkTheme : lightTheme);
};
return (
<ThemeProvider theme={theme}>
<div css={(theme) => containerStyle(theme)}>
<h2 css={{ fontSize: '2rem', marginBottom: '20px' }}>
Emotionμ νμ©ν ν
λ§ μ ν μμ
</h2>
<p>Emotionμ μ¬μ©νλ©΄ μ€νμΌ μ μκ° λ³΄λ€ κ°κ²°νλ©°, νΌν¬λ¨Όμ€ μΈ‘λ©΄μμλ μ°μν κ²°κ³Όλ₯Ό μ»μ μ μμ΅λλ€.</p>
<button css={(theme) => buttonStyle(theme)} onClick={toggleTheme}>
ν
λ§ μ ν
</button>
</div>
</ThemeProvider>
);
};
export default ThemedEmotionComponent;
Emotionμ JSX λ΄μμ css ν¨μλ₯Ό νμ©νμ¬ μ€νμΌμ μ μνκ³ , ThemeProviderλ₯Ό ν΅ν΄ μ μ ν λ§ κ°μ μ λ¬λ°μ΅λλ€. μ΄μ κ°μ΄ Styled Componentsμ μ μ¬ν λ°©μμΌλ‘ λμνλ©΄μλ, νΌν¬λ¨Όμ€ μ΅μ νμ κ°μ μ 보μ λλ€.
μ¬μ©μ λ§μΆ€ν UI ꡬν μ λ΅
ν λ§μ μ€νμΌ μμ€ν ꡬμΆμ λ¨μν μμκ³Ό ν°νΈλ§ λ³κ²½νλ κ²μ΄ μλλλ€. μ¬μ©μκ° μ νΈνλ μΈν°νμ΄μ€λ₯Ό μ 곡νκΈ° μν΄ λ€μκ³Ό κ°μ μΆκ° μ λ΅μ κ³ λ €ν μ μμ΅λλ€.
- λ€μν ν
λ§ μ΅μ
μ 곡
- λ€ν¬ λͺ¨λ, λΌμ΄νΈ λͺ¨λ μΈμλ μμ νλ νΈ, ν°νΈ μ€νμΌ, λ μ΄μμ μ΅μ λ± λ€μν ν λ§ μ΅μ μ μ 곡νλ©΄ μ¬μ©μ λ§μΆ€ν κ²½νμ κ·Ήλνν μ μμ΅λλ€.
- μ¬μ©μ νλ‘ν μ€μ μ΄λ λ‘컬 μ€ν 리μ§μ ν λ§ μ€μ μ μ μ₯νμ¬, λ€μ μ μ μμλ μΌκ΄λ UIλ₯Ό μ 곡ν μ μμ΅λλ€.
- μ€μκ° ν
λ§ λ³κ²½ μ μ©
- 리μ‘νΈμ μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬(Redux, Context API λ±)λ₯Ό νμ©νμ¬ μ ν리μΌμ΄μ μ 체μ κ±ΈμΉ ν λ§ λ³κ²½μ μ€μκ°μΌλ‘ λ°μν μ μμ΅λλ€.
- μ λλ©μ΄μ ν¨κ³Όλ₯Ό λν΄ λΆλλ¬μ΄ μ ν ν¨κ³Όλ₯Ό μ μ©νλ©΄, μ¬μ©μ κ²½νμ νμΈ΅ μ κ·Έλ μ΄λν μ μμ΅λλ€.
- μ¬μ©μ νΌλλ°± λ°μ
- A/B ν μ€νΈλ μ¬μ©μ μ€λ¬Έμ‘°μ¬λ₯Ό ν΅ν΄ μ΄λ€ ν λ§ μ΅μ μ΄ κ°μ₯ μ νΈλλμ§ νμ νκ³ , μ΄λ₯Ό κΈ°λ°μΌλ‘ ν λ§ μμ€ν μ μ§μμ μΌλ‘ κ°μ ν μ μμ΅λλ€.
- μ κ·Όμ± μΈ‘λ©΄μμλ μμ λλΉ, ν°νΈ ν¬κΈ° λ±μ μ€μ μ μ¬μ©μ κ°κ°μΈμ μꡬμ λ§κ² μ‘°μ ν μ μλλ‘ ν΄μΌ ν©λλ€.
- λͺ¨λνμ μ¬μ¬μ©μ± κ°ν
- ν λ§μ μ€νμΌμ λ³λμ λͺ¨λλ‘ λΆλ¦¬νμ¬, νλ‘μ νΈ κ·λͺ¨κ° 컀μ§λλΌλ μ μ§λ³΄μμ νμ₯μ±μ΄ μ©μ΄νλλ‘ μ€κ³ν©λλ€.
- μ»΄ν¬λνΈ λ¨μλ‘ μ€νμΌμ μΊ‘μνν¨μΌλ‘μ¨, λ€λ₯Έ νλ‘μ νΈλ ν λ΄μμ μ¬μ¬μ© κ°λ₯ν μ½λ λ² μ΄μ€λ₯Ό ꡬμΆν μ μμ΅λλ€.
μ€μ νλ‘μ νΈ μ μ© μ¬λ‘
λκ·λͺ¨ μΉ μ ν리μΌμ΄μ μμλ λ€μν ν λ§μ μ€νμΌ μ΅μ μ μ 곡νμ¬, μ¬μ©μμκ² κ°λ³νλ κ²½νμ μ μ¬νλ κ²μ΄ νμμ μ λλ€. μλ₯Ό λ€μ΄, μ μμκ±°λ μ¬μ΄νΈμμλ μ¬μ©μ μ·¨ν₯μ λ§λ μμκ³Ό λ μ΄μμ, ν°νΈ λ±μ μ νν μ μλλ‘ μ§μνμ¬ λΈλλ μμ΄λ΄ν°ν°μ μ¬μ©μ νΈμμ±μ λμμ λ§μ‘±μν¬ μ μμ΅λλ€. λν, SaaS μ νμμλ κΈ°μ κ³ κ°λ§λ€ κ³ μ ν CI/BIλ₯Ό λ°μν λ§μΆ€ν μΈν°νμ΄μ€λ₯Ό μ 곡ν¨μΌλ‘μ¨, κ³ κ° λ§μ‘±λμ μλΉμ€ μ λ’°λλ₯Ό λμΌ μ μμ΅λλ€.
νλ‘μ νΈ μ΄κΈ° λ¨κ³λΆν° ν λ§ μμ€ν μ λμ νλ©΄, ν₯ν λμμΈ λ³κ²½μ΄λ νμ₯ μμλ μ½λ μμ λ²μλ₯Ό μ΅μνν μ μμ΅λλ€. μ΄λ₯Ό μν΄ κ°λ°μμ λμμ΄λ κ°μ νμ μ ν΅ν΄, 곡ν΅μ λμμΈ μμ€ν κ³Ό μ€νμΌ κ°μ΄λλΌμΈμ λ§λ ¨νλ κ²μ΄ μ€μν©λλ€. μ΄λ¬ν μμ€ν μ μ μ§λ³΄μμ μ§μμ μΈ μ λ°μ΄νΈμλ ν° λμμ΄ λλ©°, μ¬μ©μμκ² μΌκ΄λ κ²½νμ μ 곡νλ λ° κΈ°μ¬ν©λλ€.
κ²°λ‘
컀μ€ν°λ§μ΄μ§ κ°λ₯ν ν λ§μ μ€νμΌ μμ€ν ꡬμΆμ 리μ‘νΈ μ ν리μΌμ΄μ κ°λ°μμ λ§€μ° μ€μν μμμ λλ€. CSS-in-JS κΈ°λ²μ νμ©νμ¬ Styled Components, Emotion λ±μ λΌμ΄λΈλ¬λ¦¬λ‘ ν λ§λ₯Ό λμ μΌλ‘ μ ννκ³ , μ¬μ©μ λ§μΆ€ν UIλ₯Ό μ 곡ν¨μΌλ‘μ¨, κ°λ°μλ λ³΄λ€ μ μ°νκ³ νμ₯ κ°λ₯ν μμ€ν μ ꡬμΆν μ μμ΅λλ€. μ΄λ¬ν μ κ·Ό λ°©μμ μ¬μ©μ κ²½ν κ°μ μ λ¬Όλ‘ , νλ‘μ νΈ μ μ§λ³΄μμ λμμΈ λ³κ²½μ λ°λ₯Έ λΉμ© μ κ°μλ ν° ν¨κ³Όλ₯Ό λ°νν©λλ€.
μμΌλ‘λ λ€μν μ¬μ©μ μꡬλ₯Ό λ°μνμ¬, μ€μκ° ν λ§ λ³κ²½, λ€ν¬ λͺ¨λ λ° κ³ λλΉ λͺ¨λ μ§μ, κ·Έλ¦¬κ³ μ¬μ©μ νΌλλ°±μ λ°μν UI κ°μ μμ μ μ§μμ μΌλ‘ μ§ννμκΈΈ κΆμ₯λ립λλ€. μ΄λ₯Ό ν΅ν΄ μΉ μ ν리μΌμ΄μ μ λ³΄λ€ μΉκ·Όνκ³ μ κ·Όμ± λμ μΈν°νμ΄μ€λ₯Ό μ 곡ν μ μμΌλ©°, μ¬μ©μ λ§μ‘±λλ₯Ό κ·Ήλνν μ μμ κ²μ λλ€.
리μ‘νΈμ CSS-in-JS λΌμ΄λΈλ¬λ¦¬λ₯Ό νμ©ν ν λ§ μμ€ν ꡬμΆμ νλ μΉ κ°λ°μμ νμμ μΈ κΈ°μ λ‘ μ리 μ‘κ³ μμΌλ©°, μ΄λ₯Ό λ§μ€ν°νλ κ²μ κ°λ°μλ‘μ ν° κ²½μλ ₯μ κ°μΆλ λ° λμμ΄ λ κ²μ λλ€.
λκΈ