ghlee.dev

my profile picture

oklch(100% 0% 90deg) == rgb(255 255 255)

2024. 1. 2.

어느 해외 개발자의 블로그를 웹 서핑하던 중, 블로그의 색감이 눈에 띄고 예뻐서 색상을 훔쳐가기 위해(?) 개발자 도구를 열어보았다. 어떤 RGB값 일까하고 찾아보니 예상하지 못한 낯선 값을 보고 갸우뚱했다.

CSS
:root {
  --pink: lab(63 59.32 -1.47);
}

lab()..?

보자마자 "모르는 CSS 스펙이 또 있구나" 하는 생각이 들었고 조금 검색해보니 CSS의 Level 4 스펙으로 나온 것을 알게 되었다. lab 이외에도 다양하게 정의된 색상 스펙이 있어서 이에 대한 내용을 더 찾아보기로 했다.

새로 나온 색상 스펙을 이해하려면 기존의 색상 표현 방법에 대해 알 필요가 있는데, 깊게 들어가지는 않으면서 프로그래머가 상식적으로 알면 좋을 범위에서 얘기해 보려고 한다.

참고로 이제부터 설명할 모든 색상 스펙은 2024년 기준으로 Chrome, Safari 등 대부분의 최신 브라우저에서 지원하고 있다.

색 영역

색 영역rgb()같은 색상 표현 방법이 표현할 수 있는 색상의 범위를 2D 영역으로 표현한 것으로 이는 종종 색 공간이라고도 불리는데 둘은 혼동되어 사용되지만 엄연히 다른 의미이다. 그러나 CSS 스펙을 간단히 이해하는데 둘의 차이가 크게 중요하지는 않으므로 여기서는 이에 대한 설명을 생략하겠다.

색 영역에는 다양한 색상 표준이 있는데 sRGBP3등이 색상 표준이다. 흔히 모니터나 노트북을 살 때 "디스플레이 색 재현율이 어쩌고∙∙∙" 하며 들어본 경험이 한번 쯤은 있을 것이다.

gamut

출처: 위키백과

색 영역에는 사람이 볼 수 있는 범위가 있다. 가장 바깥쪽 모양은 사람이 볼 수 있는 영역이고 안쪽의 삼각형 같은 모양은 sRGB가 표현하는 영역이다. 이처럼 우리가 실무에서 사용하는 색상 영역은 사람의 눈으로 볼 수 있는 영역 안쪽으로 한정되어 있다.

CSS Level 4 스펙에는 sRGB의 영역보다 큰 범위의 색상 표준이 새롭게 추가됐다. 표현할 수 있는 색상의 가짓 수가 많아졌다고 보면 된다.

또한 기존 색상 표현 방법이 가지고 있던 문제점을 상당 부분 해결한 표준이 있는데, 본 글 제목에 적혀있는 oklch이다. 지금부터 sRGB부터 시작해서 새로운 표준까지 차근차근 살펴보자.

RGB와 HEX

오늘날 우리에게 익숙한 색상 표현 방법은 RGBHEX이다. Chrome과 Safari에서 무려 버전 1부터 지원해온 고대 스펙이며 색 영역은 sRGB영역을 사용한다.

HEX는 16진수를 가리키는 말이다.

CSS
body {
  color: #252525;
  color: #252525ff;
 
  color: rgb(25, 25, 25);
  color: rgb(25 25 25);
 
  color: rgba(25, 25, 25, 0.1);
  color: rgba(25 25 25 0.1);
}

빨강(r), 녹색(g), 파랑(b)의 색상 값을 정수 0부터 255까지의 범위로 16진수 표현을 사용하거나 rgb() 함수를 이용하여 표현한다. 또한 필요시 알파(alpha)이라고 불리는 투명도를 추가로 넣어 사용한다.

rgb() 괄호의 값 사이에 쉼표는 새로운 CSS 스펙에서는 넣지 않아도 CSS 엔진이 처리해 준다.

HSL

두 번째로 익숙한 색상 표현 방법으로 HSL이 있다. 이 또한 브라우저에서 오래 전부터 지원해온 스펙이다. RGB 및 HEX와 마찬가지로 sRGB 색 영역을 사용한다.

CSS
body {
  color: hsl(53deg 100% 68%);
 
  color: hsla(53deg, 100%, 68%, 50%);
  color: hsla(53deg, 100%, 68%, 0.5);
 
  color: hsl(53 100% 68% / 50%);
  color: hsl(53 100% 68% / 0.5);
 
  color: hsl(none none 100%);
}

색조(hue), 채도(saturation)밝기(lightness)의 값을 각도(deg)퍼센트(%)로 표현한다. HSL의 색상 영역을 원형 혹은 원통의 색상 영역으로 표현하는데 거기서 색상을 가리키는 방향이 각도이다.

HSL에서는 각도가 가리키는 색상만 숙지하고 있다면 채도와 밝기의 퍼센트까지 조합하여 CSS 코드만 보고 색 추측이 용이하다. 기존 RGB에서는 빨간색과 초록색, 파란색의 상호작용을 생각했어야 하는데 HSL는 이를 알 필요가 없다.

sRGB의 한계

sRGB가 나와서 프로그래밍에 이용될 때는 하드웨어 장치가 표현할 수 있는 색 영역이 sRGB 보다 넓지 않았다. 하지만 오늘날 판매되는 모니터와 노트북은 sRGB는 물론이고 P3 영역을 높은 비율로 지원하는 기기를 쉽게 볼 수 있다. 하드웨어와 운영체제는 이미 더 많은 색상을 보여줄 준비가 되어있는데 웹에서는 여전히 sRGB 영역에 머물러 있었다.

display

쿠팡에서 Dell사 모니터를 검색해보았다.

또한 RGBHSL에는 지각 균일성이 좋지 않다는 문제가 있다. 글로 이를 표현할 좋은 번역체를 찾지 못했는데 설명을 하자면 사람의 눈으로 봤을 때 색상의 변화가 균일한가를 나타내는 말이다.


예를 들어 색상 값이 20만큼 바뀌었을 때, 사람의 눈으로 보기에도 그 값만큼 바뀌었는지 체감할 수 있는가를 이야기하는 건데 이것을 실험해 보기 위한 예시는 아래와 같다.

background-color: hsl(30, 100%, 50%)
background-color: hsl(50, 100%, 50%)
background-color: hsl(230, 100%, 50%)
background-color: hsl(250, 100%, 50%)

CSS Color 5 스펙의 편집자인 Lea Verou의 글에서 좋은 예시가 있었다.

위와 아래 모두 동일하게 색조를 20deg 만큼 바꾸었다. 그러나 위의 색상은 주황색에서 노란색으로 바뀌어 보이는데 아래 색상은 둘 다 파란색으로 보인다.

값에 따라서 색상의 변화가 균일하다면 이러한 문제는 나오지 않는다.

lch와 oklch

lchoklch는 CSS Level 4 스펙에서 새로 정의된 색상 표현 방법이다.

위에서 설명한 색 표현 영역의 한계와 지각 균일성에 대해 해결하기 위해 나온 스펙이며 2024년 기준으로 대부분의 최신 브라우저에서 지원하고 있다.

CSS
body {
  color: lch(50% 24 241deg);
  color: lch(50 24 241deg);
  color: lch(50 24 241);
  color: lch(50% 24 241 / 50%);
  color: lch(50% 24 241 / 0.5);
 
  color: oklch(62% 0.1 233deg);
  color: oklch(62 0.1 233deg);
  color: oklch(62 0.1 233);
  color: oklch(62% 0.1 233 / 50%);
  color: oklch(62% 0.1 233 / 0.5);
}

밝기(lightness)채도(chroma), 색조(hue)의 값으로 구성되어있고 필요하다면 알파(alpha)값을 넣을 수 있다.

이 둘은 당연히 sRGB영역보다 많은 색을 표현할 수 있는데 CIE라고 하는 색 영역을 사용한다. CIE에 대해 자세히 알고 싶다면 검색엔진에 CIE 1931 color space로 검색해 보자. 요약해서 얘기하면 사람의 눈으로 볼 수 있다고 믿는 색 영역이라고 얘기할 수 있다.

lch에는 치명적인 결함이 하나 있는데 파란색이 균일하게 바뀌지 않는 문제가 있다. 이는 색영역에서 잘못된 보간법으로 생기는 문제인데 이를 보완한 보간법을 추가한 것이 oklch이다.

오늘날 색상 선택 도구에는 oklch가 포함되어 있으니 이를 사용하면 된다.

color picker

Mac OS의 Color Picker 앱이다. 보다시피 oklch 표현을 지원한다.

지각 균일성이 좋다는 것은 색상 별 일관된 명암비를 줄 수 있다는 말이다. 이는 웹에서 접근성을 다룰 때 굉장히 유리하며 프로그래머가 재사용할 수 있는 코드 작성도 쉬워진다.

하드웨어가 지원하지 않는 색 영역을 표현할 경우 브라우저(CSS 엔진)에서 이에 근접한 색상으로 바꿔준다. 그러니 지원하는 색영역을 벗어난 범위여도 걱정할 필요가 없다.

딱히 단점이랄 게 없어 보이는 굉장히 좋은 스펙인데 아쉽게도 피그마 같은 디자인 툴에서 기본적으로 지원하지 않고 있다. 플러그인을 설치를 통해 사용할 수 있지만 기본적으로 지원하는 거와는 차이가 있으니 아쉬운 부분이다.

마치며

프론트엔드 엔지니어와 디자이너와의 합의가 필수이니 당장은 실무에서 사용하기 어려울 수 있다. 다만 하드웨어의 색재현은 날이 갈수록 좋아지고 웹도 언젠가는 sRGB를 벗어날 수도 있으니 알아둬서 나쁠 건 없어 보인다.

글에서 설명한 것 이외에도 oklch와 같은 CIE 영역을 공유하는 lab, oklab이 있으며, 기존 RGB 표현법을 사용하여 DCI-P3, Rec2020 같은 다양한 색 영역을 지원할 수 있는 color() 함수도 있다. 유저의 하드웨어가 해당 색영역을 지원하는지 확인할 수 있는 미디어 쿼리도 있다.

가능한 글을 짧게 쓰느라 많은 부분을 생략했다. 각 표현법의 그라데이션에서의 보간법 차이, CSS Level 5 등 탐구해 볼 것은 많으니 직접 찾아보는 게 좋을듯하다. 아쉽게도 한글로 된 글은 거의 없으니 영어로 검색해 보길 권장한다.

References