02 — Gradients & Interpolation
한 줄 답: Gradient는 두 색 사이의 좌표 공간을 보간하는 함수이며, 어떤 색공간에서 보간하느냐가 결과를 절반 이상 결정한다.
linear-gradient(red, blue)가 중간에 회색이 끼는 건 sRGB 보간의 함정이고,linear-gradient(in oklch, red, blue)가 깨끗한 보라를 그리는 건 OKLCH 보간이 perceptually uniform하기 때문이다.
Why — 왜 gradient가 어렵나
CSS의 gradient는 표면적으로 단순하다 — 색 두 개와 방향만 주면 된다. 그런데 결과가 자주 어색하다.
/* 예시 1: 회색 중간이 끼는 그라데이션 */
background: linear-gradient(to right, red, blue);
/* 중간이 진흙색 (~#7f007f의 어두운 보라가 아니라, RGB 평균인 칙칙한 색) */
/* 예시 2: 회색 단계를 거치는 hue 변화 */
background: linear-gradient(to right, yellow, blue);
/* 중간이 *회색*. 사람 직관: 초록 → 청록을 거쳐야 하는데 sRGB 평균은 회색 */이유: sRGB 보간은 각 채널의 산술 평균을 낸다. 빨강 rgb(255 0 0) + 파랑 rgb(0 0 255)의 중간은 rgb(127 0 127) — 어두운 보라. 노랑 rgb(255 255 0) + 파랑 rgb(0 0 255)의 중간은 rgb(127 127 127) — 회색.
사람 눈은 지각적 보간을 기대한다 — 빨강에서 파랑으로 가려면 보라를 거치고, 노랑에서 파랑은 초록·청록을 거쳐야 한다. 이 기대를 만족하는 게 OKLCH 보간이다.
How — Gradient의 세 종류와 보간 색공간
Gradient 분류
| 종류 | 함수 | 용도 |
|---|---|---|
| Linear | linear-gradient(<angle>, ...) | 표면 채우기, 배경, 마스크 |
| Radial | radial-gradient(<shape> at <pos>, ...) | 글로우, 스포트라이트, 둥근 배경 |
| Conic | conic-gradient(from <angle> at <pos>, ...) | 색상환, 파이 차트, 도트 패턴, gradient border |
| Repeating | repeating-linear-gradient, repeating-radial-gradient, repeating-conic-gradient | 반복 패턴 (줄무늬, 격자) |
Interpolation method — in <colorspace>
CSS Images Level 4(2024)에서 도입. 어느 색공간에서 색을 보간할지 명시.
/* sRGB (기본, 잘 안 보임) */
background: linear-gradient(red, blue);
background: linear-gradient(in srgb, red, blue);
/* OKLCH (사실상 표준) */
background: linear-gradient(in oklch, red, blue);
/* hue 보간 방향 명시 */
background: linear-gradient(in oklch longer hue, red, blue);
background: linear-gradient(in oklch shorter hue, red, blue);
background: linear-gradient(in hsl decreasing hue, red, blue);지원하는 색공간:
srgb,srgb-linear,hsl,hwb,lab,lch,oklab,oklchxyz,xyz-d50,xyz-d65display-p3,rec2020,a98-rgb,prophoto-rgb
브라우저 지원: Chrome 111+ / Safari 16.2+ / Firefox 113+ (Baseline 2023).
What — 자주 쓰는 패턴
1) Linear Gradient — 각도와 stop
/* 각도 (12시=0deg, 시계방향) */
background: linear-gradient(135deg, #4a90e2, #f5a623);
/* 키워드 방향 */
background: linear-gradient(to bottom right, #4a90e2, #f5a623);
/* 다중 stop */
background: linear-gradient(
to right,
oklch(62% 0.21 254) 0%,
oklch(70% 0.18 200) 50%,
oklch(80% 0.15 145) 100%
);
/* hard stop (선명한 경계) */
background: linear-gradient(
to right,
red 0% 50%,
blue 50% 100%
);
/* OKLCH 보간 + multi-stop */
background: linear-gradient(
in oklch to right,
oklch(60% 0.2 25),
oklch(60% 0.2 145),
oklch(60% 0.2 265)
);
/* L=60 고정이라 *진짜로* 같은 밝기의 hue ramp */2) Radial Gradient — 모양·위치·크기
/* 기본 — 타원, 중심, 콘테이너 코너까지 */
background: radial-gradient(white, transparent);
/* 모양 + 위치 + 크기 */
background: radial-gradient(
circle 200px at top right,
oklch(80% 0.15 254 / 0.6),
transparent
);
/* 글로우 효과 패턴 */
.glow-bg {
background:
radial-gradient(circle at 20% 30%, oklch(70% 0.2 25 / 0.4), transparent 50%),
radial-gradient(circle at 80% 70%, oklch(70% 0.2 254 / 0.4), transparent 50%),
var(--surface);
}size 키워드: closest-side, closest-corner, farthest-side, farthest-corner (기본).
3) Conic Gradient — 각도 기반
/* 색상환 (color wheel) */
.color-wheel {
background: conic-gradient(
in oklch longer hue,
oklch(70% 0.2 0),
oklch(70% 0.2 360)
);
border-radius: 50%;
}
/* 파이 차트 */
.pie {
background: conic-gradient(
#4a90e2 0% 25%,
#f5a623 25% 60%,
#7ed321 60% 100%
);
border-radius: 50%;
}
/* gradient border (07장과 연결) */
.fancy-border {
background:
linear-gradient(white, white) padding-box,
conic-gradient(from 45deg, #4a90e2, #f5a623, #7ed321, #4a90e2) border-box;
border: 2px solid transparent;
}4) Repeating Gradient — 패턴
/* 스트라이프 */
background: repeating-linear-gradient(
45deg,
oklch(95% 0 0),
oklch(95% 0 0) 10px,
oklch(90% 0 0) 10px,
oklch(90% 0 0) 20px
);
/* 도트 패턴 */
background: repeating-radial-gradient(
circle at 0 0,
transparent 0 4px,
oklch(80% 0 0) 4px 5px
);5) currentColor + gradient — 테마 따라 자동 변화
.button {
color: oklch(62% 0.21 254);
background: linear-gradient(
in oklch,
color-mix(in oklch, currentColor 20%, transparent),
color-mix(in oklch, currentColor 5%, transparent)
);
}
/* color만 바꿔도 그라데이션 색이 함께 따라온다 */What-if — 잘못 쓰면
1) sRGB 보간의 진흙색
/* 나쁨 */
background: linear-gradient(red, lime);
/* 중간에 칙칙한 갈색이 낀다 */
/* 좋음 */
background: linear-gradient(in oklch, red, lime);
/* 중간이 깨끗한 노랑-주황 */2) transparent의 함정
/* 흑색이 슬쩍 끼는 페이드 */
background: linear-gradient(red, transparent);
/* transparent는 *검은색 0 알파*로 해석됨 → 중간이 어두워짐 */
/* 명시적 동일 색의 0 알파 */
background: linear-gradient(red, rgb(255 0 0 / 0));
/* 또는 */
background: linear-gradient(in oklch, red, oklch(63% 0.24 25 / 0));transparent는 spec상 rgba(0,0,0,0)이다. 페이드아웃 만들 때는 같은 색 + 알파 0을 명시해야 깔끔하다. OKLCH 보간을 쓰면 어느 정도 완화되지만, 명시적 동일색 페이드가 가장 안전.
3) Conic gradient의 시작 각도 혼동
/* 기본 시작은 12시 (0deg) */
background: conic-gradient(red, blue);
/* red가 12시 정 위치, blue가 그 직전 */
/* 6시에서 시작 */
background: conic-gradient(from 180deg, red, blue);from이 없으면 상단 정중앙이 시작. 파이 차트를 만들 때 *3시(=90deg)*에서 시작하고 싶으면 명시.
4) 성능 — 큰 면적 gradient + filter
/* 나쁨: 큰 그라데이션에 blur — paint 비용 폭증 */
.bg {
width: 100vw; height: 100vh;
background: linear-gradient(...);
filter: blur(40px);
}
/* 좋음: 작은 그라데이션을 scale로 크게 */
.bg {
width: 200px; height: 200px;
background: linear-gradient(...);
filter: blur(40px);
transform: scale(10);
transform-origin: 0 0;
}filter는 합성 단계에 GPU로 처리되지만, 입력 raster 크기에 비례한다. 작게 그리고 transform으로 키우는 게 사실상 표준 트릭.
5) Gradient를 폰트 컬러로 — background-clip: text
.gradient-text {
background: linear-gradient(in oklch, #4a90e2, #f5a623);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}text-shadow로는 그라데이션 텍스트가 불가능하다 (단색만). background-clip: text가 사실상 유일한 방법. 단, 복사·접근성은 color: transparent 때문에 손해를 본다 — forced-colors 모드에서 안 보일 수 있으니 @media (forced-colors: active)에서 color: CanvasText 처리 권장.
Insight — Gradient의 역사
“Photoshop 5.0(1998)에서 시작된 라디언트가 24년 만에 CSS의 1급 시민이 됐다”
1998년 Photoshop 5.0의 Gradient Tool이 디자인의 사실상 표준 효과가 됐다. CSS는 한참 늦었다 — linear-gradient가 CSS3 Images에서 표준화된 게 2011년, radial-gradient가 2012년, conic-gradient는 2018년(Chrome 69)에 처음 들어왔다.
흥미로운 반전: conic-gradient는 한동안 polyfill로 살았다. Lea Verou의 conic-gradient.js(2017)가 SVG로 conic을 흉내냈고, 그 폴리필을 보고 “이건 CSS 1급으로 만들어야 한다” 는 합의가 형성됐다. 사용자 폴리필이 표준을 끌어당긴 드문 사례다.
OKLCH 보간(in oklch)은 2024년이 분기점이다. Chrome·Safari·Firefox가 동시에 풀린 다음, Tailwind v4가 기본 gradient 보간을 OKLCH로 바꿨다. 그 영향으로 디자이너의 직관과 코드의 결과가 30년 만에 일치하기 시작했다.
또 하나의 반전: gradient는 렌더링 비용이 의외로 싸다. 큰 면적이라도 GPU로 한 번에 그려진다. 비싼 건 gradient + filter blur의 조합 — 큰 raster를 blur 통과시키는 게 문제지, gradient 자체가 아니다.
요약 + Mermaid
- Gradient는 3종류 — linear / radial / conic.
- 보간 색공간이 결과의 절반 —
in oklch가 사실상 표준. transparent페이드는 같은 색 + 알파 0으로 명시.background-clip: text로 그라데이션 텍스트 (text-shadow로는 불가능).- 큰 면적 gradient + blur는 작게 그리고 transform: scale로.
다음: 03-shadows — gradient가 표면의 색이라면 shadow는 표면의 깊이다.