
μ λ μμ§ λ§μ νλ‘μ νΈμ μ°Έμ¬ν΄λ³΄μ§ μμμ§λ§, Reactλ₯Ό νμ©ν΄ μ€μ΅&μμ ν λλ©΄ λ°λμ μ¬μ©νλ λΌμ΄λΈλ¬λ¦¬κ° λͺ κ°μ§ μμμ΅λλ€. κ·Έ μ€ νλλ λνμ μΈ cSS-in-js λΌμ΄λΈλ¬λ¦¬μΈ styled-components μμ£ ..
styled-components λ₯Ό μ¬μ©ν κ²½μ°, css νμΌμ λ³λλ‘ λ§λ€μ§ μμλ λκΈ° λλ¬Έμ μμ μ΄ νΈλ¦¬ν΄μ§κ³ , λμμΈμ΄ μμ±λ μ»΄ν¬λνΈλ₯Ό μ¬λ¬ νμΌμμ νΈμΆν μ μκΈ° λλ¬Έμ μ¬μμ©μ±μ΄ λμμ§λ€λ μ₯μ μ΄ μμ΅λλ€. λλΆμ μ§κΈκΉμ§ μ§μ css νμΌμ μμ±ν΄ λ³Έ μ μ νλ²λ μμμ΅λλ€. π
νμ§λ§ νΉμ λΌμ΄λΈλ¬λ¦¬μ μμ‘΄μ μΈ κ°λ°μ΅κ΄μ λ€μ΄λ©΄ μλλ€κ³ μ΄λμ κ° λ€μλ κ±° κ°μμ... μ΄λ² κ°μΈ νλ‘μ νΈμμλ μ΅κ΄μ μΌλ‘ μ¬μ©νλ styled-components μμ΄ μ§ννλ κ²μΌλ‘ κ°μΈ λμ κ³Όμ λ₯Ό μ€μ νμ΅λλ€.
μ²μ λ€μλ μμ΄λμ΄λ μ¬ννμ΅λλ€. jsx μμ style μμ±μ μ΄μ©ν κ²½μ°, styled-components μ λ§μ°¬κ°μ§λ‘ css νμΌμ λ³λλ‘ λμ§ μκ³ λ ui μ»΄ν¬λνΈ λ₯Ό μ½κ² λμμΈ ν μ μμ΅λλ€. μ΄λ₯Ό inline-styling μ΄λΌκ³ νλ΅λλ€. π
// inline-styling
export const TestComponent = () => {
return (
<div style={{ width: "500px", height: "500px", backgroundColor: "red" }}>
<p> νλ³μ κΈΈμ΄κ° 500px μΈ λΉ¨κ° μμ </p>
</div>
);
};
μμ νμμ 보μμ λ, style μ κ°μΌλ‘ κ°μ²΄ννμ css μμ±μ΄ νμν κ²μ μ μ μμ΅λλ€.
μ΄ ννλ₯Ό μμκ²(?) λ§λ€μ΄λ³΄λ©΄ styled-components μ λΉμ·ν μ½λ νμμ΄ λμ¬ κ±° κ°λ€κ³ μκ°νμ΅λλ€.
#1 - styled-components μ¬μ©
import styled from 'styled-components'
export const UsingStyledComponents = () => {
return (
<RedBox>
<p> νλ³μ κΈΈμ΄κ° 500px μΈ λΉ¨κ° μμ </p>
</RedBox>
);
};
export const RedBox = styled.div`
height: 500px;
weight: 500px;
background-color: 'red';
`
#2 - style μμ± μ¬μ©
export const InlineStyling = () => {
return (
<div style={RedBox}>
<p> νλ³μ κΈΈμ΄κ° 500px μΈ λΉ¨κ° μμ </p>
</RedBox>
);
};
const RedBox: React.CSSProperties = {
width: "500px",
height: "500px",
backgroundColor: 'red'
};
μ₯μ₯(?) λ΄€μ λ, μΌν λΉμ·νκ² λ³΄μ΄μ§ μλμ????
μ μ κ²½μ°μ, μμ μμ±μ ν κ²½μ° μ§κΈκΉμ§ μμ±ν΄μλ μ½λλ€κ³Ό ν° μ΄μ§κ° μμ΄ μμ
ν μ μκ² λ€λ νμ μ΄ μκ²Όλ΅λλ€..
λ¬Όλ‘ , λ¨μν μ½λλ₯Ό λΉμ·νκ² μμ±ν μ μλ€λ μ₯μ λΏλ§ μλλΌ μΈλΆ λΌμ΄λΈλ¬λ¦¬μ λν μμ‘΄μ±μ νλ μ€μΌ μ μλ μΌμ΄κΈ°λ νμ£ . π
- type-script λ‘ μμ±ν κ²½μ°,
React.CSSPropertiestype μ style κ°μ²΄μ λΆμ¬ν μ μμ΅λλ€.- λλΆμ μλμμ±κΈ°λ₯μ νμ©ν μ μκΈ°λ νκ³ , μΌλ° κ°μ²΄μμ ꡬλ³μ΄ κ°λ₯νμ΅λλ€. π
맨 μ²μ κ³ λ―Όνλ κ²μ μ€νμΌ μ»΄ν¬λνΈμ props λ₯Ό μ λ¬νλ κ²½μ° μμ΅λλ€. styled-components λ₯Ό μ¬μ©ν κ²½μ°, λ€μκ³Ό κ°μ΄ λλΉμ λμ΄λ₯Ό μ λμ μΌλ‘ λ³κ²½ κ°λ₯ν box μ»΄ν¬λνΈλ₯Ό μμ±ν μ μμ΅λλ€.
import styled from 'styled-components';
import { ReactNode } from 'react';
type BoxProps = {
width?: string
height?: string
children: ReactNode
}
export const Box = ({ width = '100%', height = '100%', children }: BoxProps) => {
return (
<StyledBox width={width} height={height}>
{children}
</StyledBox>
)
}
type StyledBoxProps = {
width: string
height: string
}
const StyledBox = styled.div<StyledBoxProps>`
width: ${(props) => props.width};
height: ${(props) => props.height};
background-color: 'red';
`
νμ§λ§ μμμ μμ±νλλλ‘ style κ°μ²΄λ₯Ό μ μΈν κ²½μ°, props λ₯Ό μ λ¬ν λ°©λ²μ΄ μμ΅λλ€.
λͺ¨μμ΄ μ‘°κΈ μ μμλ€κ³ (?) μκ°νμ§λ§ μ λ λ€μμ λ°©λ²μΌλ‘ κ°μ κ²°κ³Όλ¬Όμ λ§λ€μ΄ λμ΅λλ€.!
import { ReactNode } from 'react';
type BoxProps = {
width?: string
height?: string
children: ReactNode
}
export const TestBox = ({ width = '100%', height = '100%', children }: BoxProps) => {
return <div style={{ ...StyleBox, width, height }}> {children}</div>
}
const StyleBox: CSSProperties = {
backgroundColor: 'red',
}
λ€λ₯Έ κ°λ°μμ μν΄ λμμΈμ΄ μ λμ μ΄μ΄μΌ νλ prop μ κ²½μ°, λ°λ‘ style μμ±μΌλ‘ κ½μκ±°μ£ (.?)
κ·Έ μΈ κ°λ€μ (μμ μν©μμ λ°°κ²½μμ) CSSProperties κ°μ²΄μ κ·Έ κ°μ μ§μ νλ, spread μ°μ°μλ₯Ό ν΅ν΄ style λ‘ μ λ¬νμ΅λλ€.
μμ£Ό μ¬μ©νλ μμ± κ°μ κ²½μ°μ λ³λλ‘ μμ±ν΄λμλ€κ°, νμν κ²½μ°μ λ€λ₯Έ μμ±κ³Ό μμ΄ μ¬μ©ν μ κ° μμμ΅λλ€. π
# ν¬κΈ° κ΄λ ¨ css μμ±
# μ¬μ© μμ
λμ΄μΌ 보면 κ°μ₯ 골μΉκ° μν λ 건 styled-components μGlobalStyles κΈ°λ₯μ μ΄λ¦¬λ κ²μ΄μμ΅λλ€. GlobalStyles λ₯Ό μ¬μ©ν κ²½μ°, ν΄λΉ νλ‘μ νΈμμ μ¬μ©λλ ν°νΈ μ€μ μ΄λ jsx νκ·Έμ λν΄ κΈ°λ³Έμ μΈ μ€νμΌμ μ μ©ν μ μμ΅λλ€.
μ μμ μΈ λμμΈ μ€μ μ΄ κΌ νμνλ μ΄μ μ€ νλλ (κ°μΈμ μΌλ‘..) νλ©΄μ ν¬κΈ°μ λ°λ₯Έ μ λμ μΈ font-size λ³κ²½μ΄μμ΅λλ€. μ΄μ κΉμ§λ GlobalStyles μ media-query μ€μ μ ν΅ν΄ ꡬνμ΄ κ°λ₯νμμ§μ..
import { createGlobalStyle } from 'styled-components'
import { GIANTS_BOLD, GIANTS_REGULAR } from './css-utils'
import { BORDER_RADIUS, BREAK_POINT, COLOR, FONT_SIZE } from './reference-tokens'
const GlobalStyles = createGlobalStyle`
html{
background-color: ${COLOR.grayScale[300]};
color: ${COLOR.grayScale[1500]};
// νλ©΄ λΉμ¨μ λ°λΌ ν°νΈ ν¬κΈ°
font-size: 62.5%;
@media screen and (max-width: ${BREAK_POINT.md}) {
font-size: 50%;
}
@media screen and (max-width: ${BREAK_POINT.sm}) {
font-size: 31.25%;
}
}
.
.
.
`
λΆλͺ λ°©λ²μ΄ μμμ κ² κ°μλ°,, μ΄μ λν λ²λ©μ΄λ μμ΄λμ΄λ μμμ΅λλ€..
μΌλ¨ μ΄λ² νλ‘μ νΈμμλ css νμΌ μμ±νμ¬ μ μ©νμ΅λλ€.γ γ γ μΆκ°μ μΌλ‘ κ° νμ΄μ§ μ λν λ°°κ²½ μμμ΄λ, κΈ°λ³Έ ν°νΈ μμ λ±μ CSSProperties κ°μ²΄λ‘ λ§λ€μ΄μ μμ μ μ©μ΄ λλλ‘ νμ΄μ.!
globalStyles.tsx
main.tsx
hover, active, focus λ± pseudo-selectors(κ°μ μ νμ) λ₯Ό μ΄μ©ν ν¨κ³Ό λΆμ¬λ νλ‘μ νΈμ μ μ©νμ§ λͺ»νμ΅λλ€. νΉν μ λ hover ν¨κ³Όλ₯Ό μ μμ£Ό μ¬μ©νλ νΈμΈλ°, μμ½λλΌκ΅¬μ π₯²
λ¬Όλ‘ μ°Ύμ보λ λΉμ·ν ν¨κ³Όλ₯Ό μ£ΌκΈ° μν λ°©λ²μ΄ μμ μλ 건 μλμμ΅λλ€.
onmouseover, onmouseleave μ΄λ²€νΈλ₯Ό κ°μ§νμ¬ νΈλ² ν¨κ³Όλ₯Ό μ£Όλ κ²μ΄ κ°λ₯ν©λλ€.
const App = () => {
const Hover: MouseEventHandler<HTMLDivElement> = (event) => {
// λ§μ°μ€κ° μ»΄ν¬λνΈ μμ μλ€λ©΄ νλμ
if (event.type === 'mouseover') (event.target as HTMLDivElement).style.backgroundColor = 'blue'
// λ§μ°μ€κ° μ»΄ν¬λνΈ λ°κΉ₯μ μλ€λ©΄ λΉ¨κ°μ
else (event.target as HTMLDivElement).style.backgroundColor = 'red'
}
return (
<CenterBox>
<div style={RedBox} onMouseOver={Hover} onMouseLeave={Hover}></div>
</CenterBox>
)
const RedBox: CSSProperties = {
width: '500px',
height: '500px',
backgroundColor: 'red',
transition: 'background-color 0.5s' // trasition μ€μ
}

νμ§λ§ μμ Hover()λ₯Ό 보면 μ μ μλ―, ui λμμΈκ³Ό κ΄λ ¨λ λ‘μ§μ μΌλ¨ λ€λ₯Έ ν¨μμ ν¨κ» μμ±ν΄μΌν¨μ΄ μ‘°κΈ κΊΌλ €μ‘κΈ° λλ¬Έμ μ΄λ² νλ‘μ νΈμμ μ¬μ©νμ§ μμμ΅λλ€.
( κ·Όλ°, μ΄ λ¬Έμ λ λ³λμ νμΌμ ν¨κ³Ό λ‘μ§μ λΆλ¦¬ μμ±ν, μΈμ€ν΄μ€λ₯Ό κ°μ Έμ€λ λ°©λ²μΌλ‘ ν΄κ²°κ°λ₯ ν κ² κ°λ€μ.. π²π‘ )
무μ보λ€λ styled-components λ₯Ό μ¬μ©ν κ²½μ°, μ½λμμ±μ΄ λ μ½κ³ μ§κ΄μ μΌλ‘ μμ±μ΄ κ°λ₯νλ©° μ»΄ν¬λνΈμ κΈ°λ₯ λ‘μ§κ³Ό μλ²½νκ² κ΅¬λΆλκΈ° λλ¬Έμ κ΅³μ΄ μ΄λ κ² ν¨κ³Όλ₯Ό λΆμ¬ν΄μΌ νλ μΆμ΅λλ€;;
// ν¨μ¬ μ§κ΄μ !!
const $RedBox = styled.div`
width: '500px';
height: '500px';
background-color: 'red';
transition: background-color 1s;
&:hover {
background-color: 'blue';
}
&:active {
// active ν¨κ³Ό
}
&:focus {
// focus ν¨κ³Ό
}
`
μ΄λ €μ΄ μ μ΄ λ§μ΄ μκΈ΄ νμ§λ§, κ²μκ³Ό κ³ λ―Όμ λ§μ΄ ν΄λ³΄λ styled-components μμ΄λ κΈ°λ₯ λ‘μ§, λ°μ΄ν° κ°μ²΄μ κ΅¬λΆ κ°λ₯νκ² ui λμμΈ μ½λλ₯Ό μμ±ν μ μμμ΅λλ€. (μλ μ§μ μ μμ,, κ·Έ ννμ κΈ°λ₯μ μ΅λν λΉμ·νκ² κ΅¬ννλ €κ³ λ Έλ ₯μ νλ κ² κ°μ΅λλ€.) κ·ΈλΌμλ μ¬λλ€μ΄ λ§μ΄ μ¬μ©νλ λΌμ΄λΈλ¬λ¦¬λ κ°ν μ κ°μ ...π... κ° νλ΄λ΄κΈ° μ΄λ €μΈλ§νΌ νλ₯ν developer-experience μ μ 곡νλ€λ μ¬μ€μ΄ μ€κ°νμ΅λλ€.π
κ·Έλ° μ΄μ λ‘ νμ νλ‘μ νΈλ₯Ό μ§νν λ, λ³λμ styling-library μμ΄ inline-styling λ°©μμΌλ‘ μ§ννμκ³ μ μνκΈ°λ νλ€ κ² κ°μ΅λλ€;; 컨벀μ μ΄λ μ½λν¨ν΄ λ±μ κ΅μ₯ν κΌΌκΌΌν ν΅μΌν΄μΌ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ κ² λ§νΌμ κ²½νμ ν μ μμ κ² κ°μμ,, κ·Έλ° κ³Όμ μμ λ°μνλ μκ°λΉμ©λ ν΄ κ±° κ°μ΅λλ€.