알아두면 좋은 내용
색상 보간 모드 — 왜 OKLCH가 중요한가
그라디언트의 품질은 두 색 사이를 어떤 색공간에서 보간하느냐에 크게 좌우됩니다. HEX·rgb()·hsl() 같은 기존 표기의 색으로 만든 CSS 그라디언트는 보간 방식을 따로 지정하지 않으면 sRGB 채널값을 직선으로 섞는데, 이 방식은 계산이 단순한 대신 사람이 느끼는 밝기·채도와 어긋납니다. CSS Color 4·CSS Images 4는 in oklch·in lab처럼 보간 색공간을 고르는 문법을 새로 정의했고, 이 도구의 "보간 모드 비교" 카드는 같은 stop을 네 가지 방식으로 동시에 그려 차이를 바로 보여 줍니다.
| 색공간 | 보간 방식 | 추천 용도 | 약점 |
|---|---|---|---|
| RGB | R·G·B 채널을 각각 직선 보간 | 같은 계열 색의 명도 변화 | 보색 사이가 탁한 회색으로 가라앉음 |
| HSL | 색상각은 짧은 쪽으로 회전, S·L은 직선 | 일러스트·팝한 무지개 톤 | HSL 명도가 지각 명도와 달라 중간이 튀게 밝아지기 쉬움 |
| OKLCH | 지각 균등 명도·채도·색상각을 따로 보간 | UI 배경·버튼 (도구 기본값) | 채도 높은 중간색이 sRGB 색역 밖으로 나가면 잘려 보임 |
| LAB | CIE Lab(D50) 좌표를 직선 보간 | 측색·인쇄 기준과 맞출 때 | 파랑 쪽이 보라·분홍빛으로 휘기 쉬움 |
HSL에서 색상각은 360°를 넘어 0°로 이어지는 원이라, 두 색 사이를 도는 방향이 둘입니다. 이 도구는 CSS 기본값과 같이 짧은 쪽(shorter hue)으로 돌고, OKLCH에서 한쪽이 무채색(채도 거의 0)이면 그 색의 색상각은 무시하고 다른 쪽 색상각을 그대로 씁니다. 흰색·회색에서 시작하는 그라디언트가 엉뚱한 색을 거쳐 가지 않도록 하는 처리입니다.
같은 두 색, 보간 방식별 50% 지점 색
아래 표는 이 도구가 쓰는 보간 함수로 두 색의 정중앙(50%)을 계산한 값입니다. 괄호 속 L은 OKLCH 명도(0~100)로, 사람 눈에 느껴지는 밝기에 가깝습니다. 양 끝의 L과 비교하면 어느 방식에서 중간이 어둡게 꺼지거나 튀게 밝아지는지 알 수 있습니다.
| 색 쌍 (양 끝 L) | RGB | HSL | OKLCH | LAB |
|---|---|---|---|---|
| 노랑 → 파랑 L 96.8 → 45.2 | #808080 L 60.0 | #00FF80 L 87.5 | #00CFBD L 76.8 | #C189AC L 69.6 |
| 빨강 → 초록 L 62.8 → 86.6 | #808000 L 58.1 | #FFFF00 L 96.8 | #F99500 L 75.8 | #C8AC00 L 74.6 |
| 로즈 → 청록 L 58.6 → 60.9 | #75577D L 50.2 | #6C12CA L 46.1 | #8F63D3 L 59.7 | #A46D7B L 59.7 |
| 흰색 → 파랑 L 100.0 → 45.2 | #8080FF L 66.1 | #DF9FDF L 78.4 | #74A3FF L 72.2 | #AF89FF L 71.5 |
| 검정 → 흰색 L 0.0 → 100.0 | #808080 L 60.0 | #808080 L 60.0 | #636363 L 50.0 | #777777 L 56.9 |
표에서 읽을 점은 세 가지입니다. 첫째, 노랑→파랑은 RGB 중간이 #808080 회색이라 채도가 완전히 사라지지만, OKLCH는 #00CFBD 청록 계열로 색을 유지합니다. 둘째, 빨강→초록은 HSL 중간이 #FFFF00(상대 휘도 0.93)이 되어 양 끝(빨강 0.21·초록 0.72)보다 밝게 튀어 띠가 생긴 것처럼 보입니다. 셋째, 검정→흰색은 RGB 중간 #808080의 명도는 L 60.0 — 한가운데(L 50)보다 밝게 치우치고, OKLCH는 중간이 L 50.0이라 명도가 고르게 변합니다.
* 값은 이 도구의 JS 보간(sRGB 색역 밖 성분은 채널별로 잘라냄) 기준입니다. 브라우저의 native 보간은 색역 밖 색을 채도부터 줄이는 방식으로 매핑할 수 있어, 채도가 아주 높은 쌍에서는 HEX 끝자리가 조금 다를 수 있습니다.
그라디언트 유형 6종과 코드 탭별 출력 차이
유형은 모양으로 고르면 됩니다. Linear는 헤더·버튼 배경처럼 한 방향으로 흐르는 면에, Radial은 스포트라이트·발광 효과에(circle은 정원, ellipse는 요소 비율을 따르는 타원), Conic은 도넛 차트·색상환·로딩 표시처럼 중심을 도는 색에 어울립니다. Mesh는 네 모서리 색이 번지듯 섞이는 배경이고, 반복 유형은 한 주기(5~100%, 기본 25%)를 되풀이해 줄무늬·동심원 패턴을 만듭니다.
문제는 같은 설정이라도 내보내는 곳마다 지원 범위가 다르다는 점입니다. 아래 표는 이 도구의 코드 생성 함수가 유형마다 실제로 무엇을 출력하는지 정리한 것입니다.
| 유형 | CSS·React | SVG 내보내기 | SwiftUI | Flutter |
|---|---|---|---|---|
| Linear | linear-gradient(각도) | 같은 각도의 linearGradient | LinearGradient | LinearGradient |
| Radial | radial-gradient(circle|ellipse at center) | radialGradient | RadialGradient (endRadius 200) | RadialGradient (radius 0.7) |
| Conic | conic-gradient(from 각도) | radial로 폴백 (SVG에 conic 없음) | AngularGradient (각도 −90° 보정) | SweepGradient |
| Mesh | radial-gradient 4겹 + 베이스 1겹 | radialGradient 4개 겹침 | MeshGradient (iOS 18+) | RadialGradient Stack (모서리 1개 예시) |
| Linear 반복 | repeating-linear-gradient | 주기만큼 stop을 이어 붙여 흉내 | LinearGradient (반복 미지원) | TileMode.repeated |
| Radial 반복 | repeating-radial-gradient | 주기만큼 stop을 이어 붙여 흉내 | RadialGradient (반복 미지원) | TileMode.repeated |
CSS 탭은 RGB 외 보간을 고르면 선언을 두 줄 냅니다. 먼저 보간색을 16개 stop으로 풀어 쓴 선언을 두고, 그 아래 in oklch 같은 native 선언을 둡니다. native 문법을 모르는 브라우저는 두 번째 줄을 통째로 무시하고 첫 줄을 쓰며, 지원하는 브라우저는 뒤의 선언으로 덮어씁니다. 도구 기본값(3색 · OKLCH · 135°)의 실제 출력은 다음과 같습니다.
/* 구형 브라우저 폴백 (보간색을 16개 stop으로 풀어 쓴 선언) */ background: linear-gradient(135deg, #E11D48 0.0%, #DB2D6F 6.7%, #D23D8F 13.3%, #C64BA9 20.0%, #B858BF 26.7%, #A865D0 33.3%, #9771DA 40.0%, #847CE0 46.7%, #7484DF 53.3%, #6786DC 60.0%, #5889D8 66.7%, #4A8CD2 73.3%, #3B8ECB 80.0%, #2C8FC4 86.7%, #1B90BB 93.3%, #0891B2 100.0%); background: linear-gradient(in oklch 135deg, #E11D48 0.0%, #7B82E0 50.0%, #0891B2 100.0%);
Tailwind 탭은 같은 native 선언을 arbitrary value로 바꾸며, 클래스 안에서는 공백을 쓸 수 없어 밑줄로 치환합니다. 여러 곳에서 재사용할 그라디언트는 테마에 등록해 두는 편이 관리가 쉽습니다.
/* 1회용 — 도구 Tailwind 탭 출력 그대로 */
<div class="bg-[linear-gradient(in_oklch_135deg,_#E11D48_0.0%,_#7B82E0_50.0%,_#0891B2_100.0%)]"></div>
/* v4 — CSS의 @theme에 등록 → class="bg-brand" · "bg-mesh" */
@theme {
--background-image-brand: linear-gradient(in oklch 135deg, #E11D48, #7B82E0, #0891B2);
--background-image-mesh:
radial-gradient(circle at 0% 0%, #E11D48 0%, transparent 70%),
radial-gradient(circle at 100% 0%, #FFB938 0%, transparent 70%),
radial-gradient(circle at 0% 100%, #0891B2 0%, transparent 70%),
radial-gradient(circle at 100% 100%, #7B82E0 0%, transparent 70%),
linear-gradient(#E11D48, #E11D48);
}
/* v3 이하 — tailwind.config.js → class="bg-brand" · "bg-mesh" */
theme: { extend: { backgroundImage: {
brand: 'linear-gradient(in oklch 135deg, #E11D48, #7B82E0, #0891B2)',
mesh: 'radial-gradient(circle at 0% 0%, #E11D48 0%, transparent 70%), radial-gradient(circle at 100% 0%, #FFB938 0%, transparent 70%), radial-gradient(circle at 0% 100%, #0891B2 0%, transparent 70%), radial-gradient(circle at 100% 100%, #7B82E0 0%, transparent 70%), linear-gradient(#E11D48, #E11D48)',
} } }그라디언트 위 텍스트 — 전 구간 최저 대비비로 판정하기
단색 배경은 대비비를 한 번만 재면 되지만, 그라디언트는 위치마다 배경색이 바뀝니다. 글자는 보통 한 가지 색이므로 가장 불리한 지점의 대비비가 곧 그 조합의 등급입니다. 분석·접근성 탭은 균등 12개 지점에 더해 모든 stop 위치와 인접 stop 사이의 25·50·75% 지점을 샘플링해 흰 글자·검은 글자의 최저값을 따로 구합니다. 좁은 구간에 stop이 몰린 그라디언트에서 균등 샘플만 쓰면 어두운 띠를 건너뛸 수 있기 때문입니다.
예를 들어 도구 기본값(#E11D48 → #7B82E0 → #0891B2, OKLCH)을 분석하면 흰 글자 최저 3.43:1, 검은 글자 최저 4.47:1이 나옵니다. 둘 다 일반 텍스트 기준 4.5:1에 못 미치고 큰 글자 기준 3:1만 넘으므로, 이 배경 위 본문은 검은 글자가 상대적으로 낫더라도 AA를 통과하지 못합니다. 가장 불리한 지점은 0% 위치의 #E11D48입니다.
기준을 휘도 하나로 바꿔 보면 색을 고르기가 쉬워집니다. WCAG 대비비는 (밝은 쪽 휘도 + 0.05) ÷ (어두운 쪽 휘도 + 0.05)이고 흰색의 휘도는 1, 검은색은 0이므로, 흰 글자가 4.5:1을 넘으려면 배경의 상대 휘도가 0.183 이하, 검은 글자는 0.175 이상이어야 합니다. 두 경계가 겹치므로 단색 배경은 흰색·검은색 중 하나로 반드시 통과하지만, 그라디언트가 이 경계를 가로질러 양쪽으로 넓게 퍼지면 어느 글자색도 전 구간을 통과하지 못합니다.
흔한 실수는 HSL 명도(L)로 이 경계를 가늠하는 것입니다. 아래 표처럼 HSL L이 같아도 색상에 따라 대비비가 몇 배씩 달라집니다(채도 80% 고정, 흰 글자 / 검은 글자 순).
| 색상 (H) | L 30% · 흰 / 검 | L 50% · 흰 / 검 | L 70% · 흰 / 검 |
|---|---|---|---|
| 빨강 (0°) | 9.74 / 2.15 | 4.64 / 4.51 | 2.79 / 7.50 |
| 노랑 (60°) | 3.66 / 5.72 | 1.34 / 15.66 | 1.20 / 17.42 |
| 초록 (120°) | 4.50 / 4.66 | 1.69 / 12.37 | 1.45 / 14.47 |
| 파랑 (220°) | 10.75 / 1.95 | 5.60 / 3.74 | 2.65 / 7.90 |
| 보라 (280°) | 10.80 / 1.94 | 5.50 / 3.81 | 2.90 / 7.23 |
* 굵은 숫자가 4.5:1 이상(AA 일반 텍스트 통과). 대비비는 소수 둘째 자리 내림 — 도구 표시와 같은 규칙입니다.
같은 L 30%라도 노랑은 흰 글자와 3.66:1에 그치지만 파랑은 10.75:1입니다. 노랑·초록 계열은 HSL 명도가 낮아도 실제로는 밝고, 파랑·보라 계열은 명도가 높아도 실제로는 어둡습니다. 그래서 글자를 올릴 그라디언트는 HSL 슬라이더보다 OKLCH 명도나 분석 탭의 수치를 기준으로 조정하는 것이 정확합니다.
linear-gradient(rgba(0,0,0,0.45), rgba(0,0,0,0.45)))를 한 겹 더 깔고, 오버레이까지 합친 색으로 다시 대비를 확인하세요. 색맹 시뮬레이션 탭에서 적색맹·녹색맹·청색맹으로 봤을 때 stop 사이 구분이 사라지는 조합이면, 색 차이 대신 명도 차이로 정보를 구분하도록 바꾸는 것이 좋습니다.자주 묻는 질문
RGB와 OKLCH 보간 — 실제로 어떻게 다른가요?
#808080 회색이 되는 것이 대표적입니다. OKLCH는 명도(L)·채도(C)·색상각(H)을 따로 보간하므로 같은 구간에서 청록 계열을 지나갑니다. 보간 색공간을 지정하는 native 문법(linear-gradient(in oklch, …))은 Chrome 111+·Safari 16.2+·Firefox 127+에서 지원되고, 이 도구의 CSS 코드는 보간색을 16개 stop으로 풀어 쓴 폴백 선언을 먼저 넣은 뒤 native 선언을 이어 붙여 구형 브라우저에서도 배경이 표시됩니다(React·Tailwind 코드는 native 문법만 출력).Tailwind에서 mesh gradient를 쓰려면?
bg-[…], 공백은 밑줄로 치환)를 그대로 붙여 넣고, 여러 곳에서 재사용할 때는 v4라면 CSS의 @theme에 --background-image-이름 변수로, v3 이하라면 tailwind.config.js의 theme.extend.backgroundImage에 등록한 뒤 bg-이름으로 씁니다. 등록 방법은 위 가이드의 코드 블록과 같고, mesh는 값 자리에 CSS 탭이 출력하는 radial-gradient 4겹 + 베이스 1겹 목록을 그대로 넣으면 됩니다(코드 블록의 bg-mesh가 도구 기본 mesh 예시).그라디언트 위에 텍스트 가독성을 어떻게 보장하나요?
Figma에서 conic gradient를 어떻게 쓰나요?
SwiftUI / Flutter에 적용하는 방법은?
MeshGradient를 지원하므로 mesh는 그 이상에서만 쓰고, 반복(repeating) 유형은 SwiftUI에 대응 기능이 없어 일반 Linear·Radial로 출력됩니다. Flutter는 표준 mesh 위젯이 없어 모서리마다 RadialGradient를 겹치는 Stack 예시를 주며(첫 모서리만 채워진 템플릿), 반복 유형은 TileMode.repeated로 옮깁니다. HEX 색은 SwiftUI에서 Color(hex:) 확장이 따로 필요하고, Flutter는 Color(0xFFxxxxxx)로 씁니다.노이즈(그레인) 효과는 어떻게 만들어지나요?
feTurbulence 필터(fractalNoise, baseFrequency 0.85, 옥타브 2)로 만든 노이즈 타일을 data URI로 인코딩해 그라디언트 위에 한 겹 더 까는 방식입니다. 노이즈 슬라이더 값은 노이즈 층의 불투명도로 바뀌는데, 100%일 때 불투명도 0.5가 상한이라 그라디언트가 완전히 덮이지는 않습니다. CSS·React 코드에는 이 노이즈 층이 background의 첫 번째 레이어로 함께 출력됩니다.WCAG 4.5:1을 전 구간에서 통과시키려면 색을 어떻게 골라야 하나요?
이미지에서 대표색 5개는 어떻게 뽑나요?
참고 자료
- W3C CSS Images Module Level 4(새 창)w3.org
- W3C CSS Color Module Level 4(새 창)w3.org
- W3C WCAG 2.2(새 창)w3.org
- MDN <color-interpolation-method>(새 창)developer.mozilla.org
- 계산 기준
- W3C CSS Images 4(그라디언트 문법)·CSS Color 4(oklch·lab 보간) · WCAG 2.2 대비 기준
- 오류 제보
- 결과가 다르면 contact@youtil.kr로 입력 조건을 알려 주세요. 평일 기준 1~3일 안에 답변합니다.