- Postmark의 기존 색상 팔레트는 색상별 체감 밝기가 들쭉날쭉하고 단계 간 대비율을 예측하기 어려워, WCAG 권장 대비를 매번 수동 확인해야 했음
- HSL/HSV는 RGB를 단순 변환한 모델이라 인간의 밝기·채도 지각을 반영하지 못하며, 단일 색상 선택에는 쓸 수 있어도 색상 시스템 구축에는 부적합함
- CIELAB와 LCh는 수치 변화가 체감 변화와 더 가깝도록 설계된 지각 균일 색공간이라, 같은 밝기 수준의 색상 스케일을 더 일관되게 만들 수 있음
- Accessible Palette는 LCh 기반으로 밝기, 대비율, Hue 보정, 기존 브랜드 색상 반영을 조정해 일관된 팔레트를 생성하는 앱임
- WCAG 2.1 대비율과 WCAG 3 Working Draft의 APCA를 함께 확인해야 현재 지침 준수와 향후 대비 알고리듬 변화에 모두 대응하기 쉬움
Postmark 색상 시스템의 문제
- 기존 Postmark 팔레트에는 두 가지 문제가 있었음
- 파랑과 빨강은 노랑과 초록보다 훨씬 어둡게 보이는 등 체감 밝기가 일관되지 않았음
- 색상 변형 간 대비율을 예측하기 어려워, 색상 쌍이 WCAG 권장 사항을 만족하는지 쉽게 알 수 없었음
- 색상 쌍을 고를 때마다 대비율을 수동으로 확인해야 했고, 실제로는 확인하지 않을 가능성도 컸음
- 원인은 HSL 색상 모델 자체의 한계와, 더 나은 대안을 디자인 도구가 충분히 지원하지 않는 상황에 있었음
HSL이 색상 시스템에 맞지 않는 이유
- RGB는 화면이 작동하는 방식을 반영하는 모델이며, 사람이 색을 고르기 쉬운 직관적 모델은 아님
- HSL과 HSV/HSB는 1970년대에 RGB를 사람이 생각하는 색상 방식에 가깝게 표현하려고 만든 대안임
- HSL은 Hue, Saturation, Lightness를 뜻함
- HSV/HSB는 Hue, Saturation, Value 또는 Brightness를 뜻함
- 당시에는 더 정교한 모델의 계산 비용이 컸기 때문에, HSL과 HSV는 계산 속도를 위해 지각적 정확성을 희생했음
- 결과적으로 HSL과 HSV는 RGB의 쉬운 수학적 변환일 뿐이며, 사람이 느끼는 밝기나 채도를 제대로 반영하지 못함
- 예를 들어 HSL에서 Saturation 100, Lightness 50으로 맞춘 색상 스케일은 모델상 같은 밝기지만, 실제로는 파랑
#00F가 노랑#FF0이나 시안#0FF보다 훨씬 어둡게 보임 - HSL에서는 완전 채도 색상이 RGB의 최대값에 매핑되고 Lightness 50의 Hue 원에 놓이며, Lightness 0과 100은 각각 검정과 흰색에 대응함
- 더 밝거나 어두운 변형은 흰색 또는 검정과 “섞이는” 방식으로 만들어짐
- 중앙 세로축은 Saturation 0인 중립색 또는 회색 범위임
CIELAB와 LCh
- HSL과 HSV가 정식화되던 시기에는 이미 더 나은 대안인 CIELAB 색공간이 존재했음
- International Commission on Illumination, 즉 CIE는 1976년에 CIELAB 또는 L*a* b* 색공간을 정의했음
- CIELAB는 수치 변화가 비슷한 체감 색상 변화에 대응하도록 설계된 지각 균일 색공간임
- RGB와 달리 보이는 색상의 전체 범위를 포괄하도록 설계됨
- Lightness인 L* 성분은 인간의 밝기 지각과 가깝게 맞춰짐
- CIELAB는 세 축으로 구성됨
- L* 값은 0에서 검정, 100에서 흰색을 정의함
- a* 축은 초록-빨강 반대색 축이며, 음수는 초록, 양수는 빨강 방향임
- b* 축은 파랑-노랑 반대색 축이며, 음수는 파랑, 양수는 노랑 방향임
- CIELCh, LCh, 또는 Lch(ab)는 CIELAB의 원통형 표현임
- a*와 b* 대신 Chroma와 Hue 각도를 사용함
- Lightness는 그대로 유지됨
- LCh의 Hue 각도는 HSL의 Hue와 비슷하지만 동일하지 않음
- HSL/HSV는 빨강, 초록, 파랑의 3가지 가산 원색을 H=0, 120, 240°에 둠
- LCh는 빨강, 노랑, 초록, 파랑을 h=0, 90, 180, 270°에 둠
- HCL 또는 LCh(uv)라는 유사 색공간도 있으며, LCh(ab)와 달리 Chroma가 0부터 100까지 균일한 스케일을 가짐
LCh에서 색상 스케일을 만드는 방식
- LCh는 HSL/HSV와 달리 원통 안에 맞지만 원통을 꽉 채우지는 않음
- Lightness, Chroma, Hue의 일부 조합은 존재할 수 없는 색상을 만듦
- 예를 들어 어둡고 채도 높은 노랑은 존재하지 않음
- Lightness 스케일에서 검정과 흰색에 가까워질수록 사람이 구분할 수 있는 색상 수는 줄어듦
- 실제 화면에는 보이는 색상 전체를 표시할 수 없음
- sRGB 색역은 일반적인 화면을 나타내며 LCh 색공간의 약 ⅓만 포함함
- CSS에서도 적어도 현재는 이 범위로 제한됨
- HSL에서 Saturation 100, Lightness 50인 색상 스케일을 LCh 기준으로 보면 노랑이 가장 밝고 파랑이 가장 어두움
- 초록은 파랑보다 거의 세 배 밝고, 빨강보다 약 두 배 밝음
- LCh에서 같은 Lightness 수준으로 스케일을 다시 만들면 색상별 밝기가 시각적으로 일관됨
- Chroma가 달라 일부 색상은 다른 색상보다 채도가 높을 수 있음
- 알림과 경고 색상은 기본 텍스트 색상보다 더 채도가 높기를 원할 수 있어, 색상 시스템에서는 이런 차이가 유용할 수 있음
- Chroma까지 더 일관되게 맞추면 제한된 sRGB 색공간 안에서도 부드러운 스케일을 만들 수 있음
디자인 도구의 한계와 Accessible Palette
- 현재 Figma, Sketch, Adobe XD는 CIELAB나 LCh를 지원하지 않음
- Figma에는 LCH color picker와 Chromatic 플러그인이 있지만, 유연한 색상 시스템을 만들기에는 충분하지 않았음
- 필요한 도구는 세 가지 조건을 만족해야 했음
- 색상 변형을 만들 때 밝기 일관성을 유지함
- 단계 간 대비율을 제어할 수 있음
- 기존 브랜드 색상을 수용할 만큼 유연함
- LCh 지원이 좋은 Chroma.js 라이브러리를 발견한 뒤, 코드로 새 팔레트를 생성하는 간단한 도구를 만들었음
- 내부 사용과 일부 지인 공유를 거친 뒤, 이 도구는 Accessible Palette 앱으로 공개됨
- Accessible Palette는 색상 레벨 전반에서 일관된 밝기와 예측 가능한 대비율을 갖는 색상 시스템을 만드는 앱임
Accessible Palette의 작동 방식
- 시작 색상을 조정하거나 기존 디자인의 색상을 붙여 넣으면, 도구가 해당 색상의 Chroma와 Hue를 사용해 여러 Lightness 단계의 스케일을 계산함
- Lightness는 완전히 사용자 지정할 수 있으며 밝은 팔레트와 어두운 팔레트 모두에 사용할 수 있음
- 기존 브랜드 색상을 포함하도록 세밀하게 조정할 수 있음
- Postmark에서는 기존 팔레트에서 가장 많이 쓰인 노랑
#FFDE00, 파랑#007DCC, 초록#4FC47F를 보존하려 했음 - 이 색상들의 Lightness 값 88.6, 75.2, 50.6을 각각 레벨 200, 400, 600의 밝기로 사용함
- 대비율은 Lightness에 따라 달라지며, 각 레벨에 대해 WCAG 2.1 권장 방식과 WCAG 3.0 Working Draft의 새 알고리듬을 모두 사용해 계산함
- 기본적으로 모든 색상의 대비는 흰색 배경을 기준으로 측정됨
- 원하는 색상 견본을 선택해 그 색상을 기준으로 대비율을 측정할 수 있음
- 레벨은 RGB 또는 CIELAB 색공간을 사용해 생성할 수 있음
- 경우에 따라 결과가 달라질 수 있어 실험해볼 가치가 있음
- Postmark 색상 체계에서는 CIELAB 사용이 밝은 빨강의 보라색 기운은 줄였지만, 파랑에서는 보라색 기운을 늘렸음
- 일부 색상은 범위 전체에서 Hue 보정이 필요할 수 있음
- 밝은 노랑은 어두워질수록 초록색 기운이 생김
- 이를 오렌지에 조금 더 가깝게 만들기 위해 음수 Hue 보정을 사용함
- 앱은 사용 중 URL을 업데이트해 변경 사항을 저장함
- 팀과 공유하거나 Figma 라이브러리와 CSS 색상 변수 파일에 추가해 이후 참조할 수 있음
- 예시 팔레트로는 새 Postmark color palette, Google’s Material Design, TailwindCSS 기반 팔레트가 있음
- 이 예시는 원본을 정확히 복제한 것이 아니라, 원래 색상과 밝기 단계에서 영감을 받은 대안임
대비율 계산과 WCAG
- Accessible Palette가 두 가지 대비율을 보여주는 이유는 WCAG 2.1 방식에 한계가 있기 때문임
- WCAG 2.1은 전경색의 휘도를 배경색의 휘도로 나누어 대비율을 계산함
- 이 공식은 선형 응답을 제공하지만, 사람은 밝은 색상 간 대비를 어두운 색상 간 대비보다 더 높게 지각함
- 실제 예시에서는 WCAG 2.1 권장 사항을 만족하는 샘플이 “불충분” 대비율로 표시된 샘플보다 읽기 어려울 수 있음
- W3C는 이 문제를 인지하고 있으며, Andrew Somers는 2019년에 공개 논의를 시작했음
- Andrew Somers가 제안한 새 작업 알고리듬은 WCAG 3 Working Draft의 일부가 되었고, APCA Contrast Calculator도 만들었음
- APCA는 Advanced Perceptual Contrast Algorithm의 약자이며, 지각적으로 더 정확하고 글꼴 크기와 굵기도 고려함
- Accessible Palette는 APCA를 사용하며, 읽을 수 있는 텍스트의 최소 권장 수준으로 점수 60을 사용함
- 이는 WCAG 2.1의 기존 4.5:1 대비율 권장과 유사한 기준임
- WCAG 2.1 대비율이 완전히 쓸모없는 것은 아님
- 중간 범위 색상에서는 여전히 꽤 정확함
- 다만 전체적으로는 새 알고리듬이 큰 개선임
- WCAG 3 방식은 아직 Working Draft라 시간이 지나며 바뀔 수 있음
- 현재 지침 준수와 향후 변화 대응을 모두 고려하려면 두 가이드라인을 함께 염두에 두고 색상 시스템을 만드는 편이 좋음