색상
색상 시스템은 역할별로 이름이 지정된 소수의 램프(ramp)로 구성되며, 실제로 렌더링되는 배경에 대해 검증됩니다. 대부분의 색상 버그는 시스템 버그입니다. 고립된 값 하나, 보기 좋다고 빌려온 토큰, 측정하지 않은 쌍이 문제를 만듭니다.
직접 측정하지 않은 대비 값을 보고하지 말고, 계산할 수 있는 색상을 추정하지 마십시오. 색상은 정확한 답이 존재하는 몇 안 되는 인터페이스 요소이므로, 정확한 답을 제시하십시오.
대비 요구사항은 hr-better-accessibility에 속합니다. 표면, 그림자 및 아이콘 색상은 이 스킬의 범위를 벗어납니다.
프로젝트의 색상 시스템을 따르십시오
프로젝트의 토큰과 표기법을 재사용하십시오. 하나의 값을 수정하기 위해 추가된 두 번째 표현 방식은 팔레트를 이해하기 어렵게 만듭니다. 일관된 16진수 시스템이 oklch()가 여기저기 섞인 16진수보다 낫습니다.
토큰이 생성되면, 토큰 파일 외부의 색상 리터럴에 대해 실패하는 린트 규칙 또는 가드 테스트로 이를 강제하고, 원시 값이 필요한 곳을 위한 짧은 허용 목록을 추가하십시오. 뒷받침할 검사 없이 "토큰을 사용하라"는 규칙을 작성하는 것은 시간이 지나면서 무시됩니다.
새로운 시스템의 경우, 그 숫자가 아래 설명된 램프 규칙과 일치하는 방식으로 작동하므로 oklch()가 가장 좋은 기본값입니다. 다른 곳에서는 색상 라이브러리가 프로젝트 자체 표기법으로 동일한 램프를 생성합니다(color-formats.md).
시스템은 개별 색상이 아닌 램프입니다
하나의 중립 램프, 하나의 강조 램프, 그리고 제품이 실제로 렌더링하는 상태 램프만 있으면 됩니다. 아무도 임포트하지 않는 warning 램프는 0픽셀을 위한 유지보수일 뿐입니다. 두 번째 강조 색상은 두 가지를 한눈에 구별해야 할 때만 필요합니다.
모든 단계에는 역할이 있습니다
램프는 눈으로 선택하는 그라데이션이 아닙니다. 각 단계는 역할(페이지 배경, 컴포넌트 호버, 테두리, 솔리드 채우기, 본문 텍스트)이 필요하기 때문에 존재합니다. 어떤 역할도 소비하지 않는 단계를 생성하지 마십시오. Tailwind의 50–950과 Radix의 1–12 규칙 모두 이러한 역할에 매핑됩니다(palette-structure.md).
기본 색상은 색조로, 의미론적 토큰은 역할로 이름을 지정하십시오
기본 색상(primitives)은 값(--blue-500)의 이름을 지정하며 컴포넌트에 직접 적용되지 않습니다. 의미론적 토큰(semantic tokens)은 역할(--color-text-secondary)의 이름을 지정하고 기본 색상을 가리키며, 컴포넌트가 참조하는 유일한 계층입니다.
이 구분이 테마 변경을 가능하게 합니다. 이 구분이 없으면 다크 모드는 모든 용도를 감사하여 어떤 것이 "강조색"을 의미하고 어떤 것이 단지 파란색을 원했는지 알아내야 합니다(token-naming.md).
토큰을 해당 역할에서만 사용하십시오
값이 오늘 올바르다고 해서 토큰을 빌려서 사용하지 마십시오. 구분선을 텍스트 색상으로 사용하는 것은 테두리가 더 밝아질 때까지는 괜찮지만, 그러면 텍스트도 함께 변합니다. 역할에 대한 토큰이 없으면 토큰을 추가하십시오.
램프 전체에서 색조를 유지하십시오
잘 구성된 램프를 정의하는 네 가지 속성:
- 단계는 의도적인 지각적 명도 진행을 따릅니다(palette-generation.md).
- 색조는 처음부터 끝까지 일정하게 유지됩니다.
- 선명도는 램프 중간에서 정점을 찍고 양쪽 끝에서 떨어집니다.
- 단계는 어두운 쪽보다 밝은 쪽에 더 조밀하게 위치합니다.
양쪽 끝은 색조를 전혀 담을 수 없는 순수한 검정색과 흰색 직전에서 멈춥니다. 눈대중으로 판단하지 말고 색상 라이브러리를 사용하십시오(palette-generation.md).
하나의 색상, 하나의 의미
인터페이스 전체에서 하나의 색상을 하나의 목적으로만 사용하고, 색조가 15° 이내인 것은 동일한 색상으로 취급하십시오. 강조색이 상호작용을 의미한다면, 정적 텍스트에 그 색조를 사용하면 사용자에게 클릭할 수 없는 것을 클릭하라고 알리는 것이며, 상호작용 요소를 중립적으로 렌더링하는 것도 마찬가지로 잘못된 정보를 줍니다. 색상은 결코 의미를 전달하는 유일한 수단이 아니며, 이는 hr-better-accessibility에서 다룹니다.
보기당 정확히 하나의 작업을 채우십시오
채워진 색상이 주요 강조를 나타낼 때, 하나의 주요 작업만이 이를 받고 나머지는 중립을 유지합니다. 색상은 레이블이 아닌 배경에 적용하십시오. 채워진 버튼은 멀리서도 주요 작업으로 읽히지만, 중립 버튼에 강조색 텍스트는 링크로 읽힙니다.
여러 개의 색상 배경은 서로 경쟁하는 동료가 아닌 별개의 상태나 범주를 나타낼 때는 괜찮습니다.
렌더링된 쌍을 측정한 다음 보고하십시오
전경색을 페이지 배경이 아닌 실제로 렌더링되는 배경에 대해 측정하십시오. 쌍이 실패하면 해당 쌍, 측정값 및 놓친 임계값을 보고하고 색상은 그대로 두십시오. 색상은 디자인 결정입니다. 요청받은 경우에만 변경하고 변경 후 다시 측정하십시오(contrast.md).
그라데이션의 보간 공간을 선택하십시오
공간은 올바름 설정이 아니라 외관입니다.
in oklab가 가장 좋은 기본값입니다: 밝기가 균일하고 색조에 놀라움이 없습니다.in oklch는 중간을 통과하는 대신 색조 바퀴를 따라 이동하여 선명함을 유지하고 중간 지점의 모든 색조를 휩씁니다. 두 색조 그라데이션이 중간에서 회색으로 변할 때 사용하십시오.- 기본 sRGB 는 중간점을 어둡게 하고 무디게 만듭니다. 별도로 지정하지 않으면 얻을 수 있는 것이기 때문에 대부분의 인터페이스가 이미 가지고 있는 방식입니다.
자세한 내용은 color-usage.md를 참조하십시오.
마치기 전에
| 실수 | 수정 방법 |
|---|---|
| 프로젝트에 토큰이 있는데 원시 값을 사용한 경우 | 역할 토큰을 재사용하거나 추가하고, 프로젝트 표기법을 사용하십시오 |
16진수 코드베이스에 고립된 oklch() 값 하나를 넣은 경우 | 마이그레이션이 범위 내에 있지 않다면 기존 표기법을 유지하십시오 |
--blue-500과 같은 기본 색상을 컴포넌트에서 직접 사용한 경우 | 의미론적 토큰이 이를 가리키도록 하십시오 |
외관(--color-blue-button) 또는 첫 사용 용도(--color-sidebar-gray)로 이름이 지정된 토큰 | 역할에 따라 이름을 지정하십시오: --color-accent-solid, --color-bg-surface |
--color-primary가 브랜드를 의미하고 --color-text-primary가 본문 텍스트를 의미하는 경우 | 브랜드에는 accent를 예약하고, primary는 "그룹에서 가장 눈에 띄는"을 의미하도록 하십시오 |
| 역할 밖에서 사용된 의미론적 토큰 (구분선을 텍스트로 사용) | 누락된 역할에 대한 토큰을 추가하고, 값으로 빌려쓰지 마십시오 |
| HSL 밝기만 변경하여 만든 램프 | 일정한 색조로 지각적 밝기에 맞춰 재구축하십시오 |
| 전체 범위에 걸쳐 균등하게 간격을 둔 램프 | 50과 100이 두 개의 표면으로 읽힐 때까지 밝은 쪽을 좁히십시오 |
| 색조 전체에 걸쳐 동일한 채도 값을 재사용한 경우 | 원시 값이 아닌 각 색조 고유 최대치의 비율을 맞추십시오 |
| 강조 색조와 충돌하는 상태 색조 | 파괴적(destructive)과 주요(primary)가 나란히 있을 때 구분되어 읽힐 때까지 이동하십시오 |
| 밝은 팔레트를 기계적으로 반전시켜 만든 다크 모드 | 반전을 시작점으로 삼은 후 선명도를 줄이고, 어두운 쪽을 넓히고 모든 쌍을 다시 확인하십시오 |
prefers-color-scheme이 일부 토큰을 설정하고 .dark 클래스가 다른 토큰을 설정하는 경우 | 하나의 전환 메커니즘을 선택하여 전체적으로 사용하십시오 |
| 색조를 변경하여 수정한 대비 | 대비가 반응하는 채널인 밝기를 변경하십시오 |
| sRGB 대체 색상 없이 P3 색상만 사용한 경우 | 먼저 sRGB 값을 선언한 다음 @media (color-gamut: p3) 내부에서 재정의하십시오 |
보고
심각도. HIGH는 콘텐츠를 읽을 수 없게 만들거나 잘못된 의미론적 색상을 할당합니다. MEDIUM은 눈에 띄는 테마, 토큰 또는 영역(gamut) 실패입니다. LOW는 고립된 미세 조정 문제입니다.
확인. 브라우저 없이: 토큰 값, 선언된 모든 색상의 영역(gamut), 두 테마 블록 모두 존재하는지 확인, 선언된 토큰 쌍에서 계산된 대비. 브라우저 사용 시: 텍스트 뒤에 실제로 렌더링되는 배경(불투명도 및 그 아래 이미지 포함)을 밝은 테마와 어두운 테마 모두에서 측정합니다. 실패한 쌍은 다시 칠하지 않고 보고합니다. 실행할 수 없었던 모든 검사는 확인되지 않음(Not verified)으로 보고하십시오.
형식. 각각이 위반하는 원칙 아래에서 발견 사항을 그룹화하고 심각도 순서로 정렬하며, 루트 원인당 하나의 행으로 나타나는 모든 위치를 나열하십시오:
| 심각도 | 위치 | 수정 전 | 수정 후 | 이유 |
|---|
위치는 path/to/file:line입니다. 이유는 원칙과 사용자 영향을 명시합니다.
HIGH가 남아 있으면 차단(Block)을, 그렇지 않으면 승인(Approve)을 보고하고 나머지는 테이블에 할 일로 남겨둡니다. 검사하지 않은 범위를 승인하지 마십시오. 보고할 사항이 없으면 "실행 가능한 색상 발견 사항 없음"을 명시하고 확인 상태를 보고하십시오.