상태
컨트롤이 어떤 상태일 때 무엇이 바뀌는지, 상태가 겹칠 때 어떻게 되는지 정한다. 색 자체의 목록은 색 문서에 있다.
상태에는 두 종류가 있다
누가 그 상태를 만드는지가 다르다. 이 구분이 겹침 규칙의 근거다.
| 상호작용 상태 | 옵션 상태 | |
|---|---|---|
| 만드는 주체 | 사용자 | 개발자 |
| 예 | hover · focus · active | disabled · readonly · error · checked |
| 언제 바뀌나 | 마우스·키보드 조작에 따라 즉시 | prop 을 주는 동안 계속 |
컨트롤을 두 부류로 나눈다
어느 쪽인지 정하면 색은 표에서 읽는다.
입력 컨트롤
타이핑하거나 목록에서 고르는 것이다.
Textfield · Textarea · Search · Password · Select · MultiSelect · Datepicker 계열.
| 상태 | 배경 | 테두리 | 글자 |
|---|---|---|---|
| default | control-bg | control-border | control-text |
| hover | 변화 없음 | control-border-hover | — |
| focus | — | focus-color + 링 | — |
| disabled | control-bg-disabled | control-border-disabled | control-text-disabled |
| readonly | control-bg-readonly | control-border-disabled | control-text-muted |
| error | control-bg | control-border-error | 변화 없음 · caret · 단위만 control-text-error |
| placeholder | — | — | control-text-placeholder |
선택 컨트롤
켜고 끄는 것이다.
Checkbox · Radio · Switch.
| 상태 | 배경 | 테두리 |
|---|---|---|
| default | control-bg | control-border |
| hover | 변화 없음 | control-accent |
| focus | — | focus-color + focus-ring-strong |
| checked | control-accent | control-accent |
| checked + error | control-accent-error | control-accent-error |
| checked + disabled | control-selection-disabled | control-selection-disabled |
| disabled | control-bg-subtle | control-border-disabled |
| readonly | control-bg-readonly | default 유지 |
상태가 겹칠 때
겹침에는 두 가지가 있다. 하나만 이기는 것과 함께 그리는 것이다.
하나만 이긴다
disabled > error > readonly셋은 CSS 상세도가 같아서 소스에 나중에 쓴 규칙이 이긴다. 파일 안에서 순서만 바꿔도 색이 조용히 뒤바뀐다. 우선순위를 :not() 으로 명시해 순서에 의존하지 않게 했다.
함께 그린다
| 조합 | 결과 | 왜 |
|---|---|---|
| checked + error | control-accent-error | 선택됐지만 잘못된 선택임을 함께 보인다 |
| hover + error | 테두리는 에러 색을 유지 | hover 로 덮으면 에러가 사라진 것처럼 보인다 |
| focus + error | 테두리 에러 색 + focus-ring-error | 고쳐야 할 자리로 이동했다는 것까지 알린다 |
| focus + readonly | 링을 그린다. 배경은 readonly 유지 | readonly 도 포커스를 받는다. 값을 읽을 수 있어야 한다 |
| hover + disabled | 아무것도 그리지 않는다 | 누를 수 없는 것에 반응을 주면 누를 수 있다고 오해한다 |
| hover + readonly | 테두리 변화 없음 | 바꿀 수 없는 값이다 |
disabled 와 readonly 중 무엇을 쓰나
| 뜻 | 예 | |
|---|---|---|
disabled | 지금은 안 되지만 조건이 맞으면 된다 | 필수 항목 미입력 시의 제출 버튼 |
readonly | 값은 보여주되 바꿀 수 없다 | 조회 전용 필드 |
영구적으로 쓸 수 없는 것은 애초에 렌더하지 않는다. disabled 로 남겨두면 사용자는 "어떻게 하면 활성화되지"를 찾는다.
면 전체가 반응할 때
목록 행, 패널 헤더, 아이콘 전용 버튼처럼 면이 통째로 반응하는 자리는 두 값으로 통일한다. hover 는 control-bg-hover, 누르는 순간은 control-bg-active. 둘 다 반투명이라 카드 위든 패널 위든 다크든 같은 진하기가 된다. 비활성은 배경을 바꾸지 않고 글자만 action-fg-disabled 로 바꾼다.
surface-neutral-soft · surface-neutral-subtle · control-bg-subtle · control-bg-readonly 를 hover 에 쓰지 않는다. 카드·구분 영역·읽기 전용처럼 정적인 면의 배경이다. verify:tokens 가 잡는다.hover 는 hover 가 있는 기기에서만 그린다. 터치 기기는 탭한 뒤에 hover 가 남아 버튼이 눌린 채로 보인다. 모든 hover 가 @media (hover: hover) 안에 있다.
색이 아닌 상태 표현
투명도로 표현하는 자리는 없다. 비활성 아이콘은 control-icon-disabled, 버튼의 hover·pressed 는 같은 색조의 다음 단계(action-*-hover · -active)다. 정부 가이드라인(KRDS)이 비활성에 투명도를 쓰지 말라고 해서 맞췄다. 비활성 글자는 대비 요구에서 빠지지만 2.0:1 아래로는 내려가지 않는다 — 회색이 배경에 녹으면 "비활성"이 아니라 "없음"으로 읽힌다.