깊이
무엇이 무엇 위에 놓이는지 정한다. 면의 층과 그림자, 쌓임 순서 셋이 같은 이야기를 다른 수단으로 한다.
층
layer-* 는 컨테이너의 표면색만 정의한다. 글자나 아이콘 같은 개별 요소가 아니라 화면의 캔버스를 만든다.
떠 있는 면 —
layer-floating바깥부터 basement → default → floating. 안쪽으로 갈수록 위에 있다.
| 층 | 토큰 | 쓰는 곳 |
|---|---|---|
| 바닥 | --nui-layer-basement | 화면의 바닥. 앱이 쓰는 층이고 컴포넌트는 쓰지 않는다 |
| 기본 | --nui-layer-default | 카드 · 리스트 · 입력 컨트롤 표면. 대부분의 콘텐츠가 여기 놓인다 |
| 떠 있음 | --nui-layer-floating | 팝업 · Select 메뉴 · Datepicker 팝업 |
| 반전 | --nui-layer-inverse | 토스트 · 툴팁. 글자는 text-on-inverse |
| 딤 | --nui-layer-overlay | 모달 뒤를 덮는 어두운 면 |
surface-* 는 층이 아니다. 콘텐츠 위에 얹는 톤(강조면 · 구분면)이라 역할이 다르다. 혼용하면 어느 것이 위인지 알 수 없게 된다.라이트에서 같고 다크에서 갈리는 쌍이 있다.
control-bg 와 layer-floating 은 라이트에서 둘 다 gray-1 이라 헷갈려 써도 안 보이지만, 다크에서는 gray-2 와 gray-3 으로 갈린다. 그래서 자리로 정한다 — 입력 컨트롤 본체는 control-bg, 메뉴·팝업·달력은 layer-floating. 다크에서는 층이 올라갈수록 밝아진다.그림자
1
2
3
press
| 토큰 | 쓰는 곳 |
|---|---|
| --nui-shadow-1 | 낮게 뜸 — 카드, 인라인 드롭다운 |
| --nui-shadow-2 | 중간 — 팝오버, 메뉴, 달력 |
| --nui-shadow-3 | 최상단 — 모달, 토스트 |
| --nui-shadow-press | 눌렸을 때 — 아래로 내려간 느낌 |
| 토큰 | 값 | 비고 |
|---|---|---|
| --nui-shadow-1 | 0 0.75rem 1.75rem rgb(17 24 39 / 6%) | 카드·인라인 드롭다운 |
| --nui-shadow-2 | 0 1.125rem 2.5rem rgb(17 24 39 / 8%) | 팝오버·메뉴·달력 |
| --nui-shadow-3 | 0 1.125rem 3rem rgb(17 24 39 / 14%) | 모달·토스트 |
| --nui-shadow-ring-brand | 0 0 0 0.25rem var(--nui-color-brand-a4) | — |
| --nui-shadow-ring-error | 0 0 0 0.25rem var(--nui-color-danger-a4) | — |
| --nui-shadow-press | 0 0.5rem 1rem rgb(17 24 39 / 12%) | — |
| --nui-shadow-thumb | 0 0.125rem 0.375rem rgb(15 23 42 / 18%) | — |
| --nui-shadow-inset-soft | inset 0 1px 0 rgb(255 255 255 / 76%) | — |
| --nui-shadow-inset-inverse | inset 0 1px 0 rgb(255 255 255 / 8%) | — |
shadow-ring-* · shadow-thumb · shadow-inset-* 은 컴포넌트 내부 전용이다. 고도를 나타내지 않으므로 위 미리보기에 없다.포커스 링은 그림자가 아니다. 생김새가 비슷하지만 그림자는 높이를, 링은 상태를 나타낸다. 그래서
shadow-* 가 아니라 focus-ring-* 이다. 고르는 기준은 접근성 문서에 있다.쌓임 순서
z-index 를 직접 쓰지 않고 이 다섯 개 안에서 고른다. 값을 직접 쓰기 시작하면 숫자 경쟁이 벌어진다.
| 토큰 | 값 | 비고 |
|---|---|---|
| --nui-z-tooltip | 20 | 제자리 툴팁 — 자기 부모 안에서만 |
| --nui-z-overlay-layer | 1030 | — |
| --nui-z-portal-menu | 1031 | portal 로 body 에 붙는 드롭다운·달력 — 팝업(1030) 안에서도 보여야 한다 |
| --nui-z-toast | 1031 | 팝업보다 위 — 팝업 안에서 띄운 토스트도 보여야 한다 |
| --nui-z-tooltip-portal | 1032 | — |
| 토큰 | 왜 그 값인가 |
|---|---|
| --nui-z-tooltip | 제자리 툴팁 — 자기 부모 안에서만 떠 있으면 된다 |
| --nui-z-overlay-layer | 팝업과 그 딤 |
| --nui-z-portal-menu | 팝업보다 위. 팝업 안에서 연 셀렉트와 달력이 팝업에 가리면 안 된다 |
| --nui-z-toast | 팝업 안에서 띄운 토스트도 보여야 한다 |
| --nui-z-tooltip-portal | 가장 위. hasPortal 로 body 에 나간 툴팁이다. 지금 가리키고 있는 것의 설명이라 무엇에도 가리면 안 된다 |
팝업끼리는 나중에 연 것이 위다. 값을 나누지 않는다. Alert 이 열린 BottomSheet 위에 오는 것은 이 순서의 결과다. 반대로 Alert 위로 시트를 여는 것은 흐름 오류다.
body 로 나가는 것끼리는 서로를 죽이지 않는다. 팝업이 열리면 배경을 격리하려고
body 의 직계 자식을 전부 inert 처리한다. 토스트 · 툴팁 · 로딩 알림 컨테이너도 body 의 직계 자식이라, 표시가 없으면 z 는 팝업 위인데 눌리지도 읽히지도 않는 상태가 된다. 우리 컨테이너에는 data-nui-portal-root 가 붙어 격리에서 빠진다.겹친다고 값을 올리지 않는다. 새 값이 필요해 보이면 대개는 쌓임 맥락(stacking context)이 잘못 잡힌 것이다. 부모에
transform 이나 opacity 가 걸려 있으면 자식의 z-index 는 그 맥락 안에 갇힌다. 숫자를 키워도 소용없다.