# Radius 요소 모서리의 둥글기를 결정하는 5단계 스케일입니다. > 원본: `03_ASSET_GUIDE/foundations/radius.js` · 값: `03_ASSET_GUIDE/styles/tokens.css` (`--- Radius ---` 절) > status `stable` · specSource `measured` | 단계 | 역할 | 예시 | |---|---|---| | **Primitive** | 둥글기 값 스케일 `--atom-radius-r{n}` · `full` | `--atom-radius-r2` = `8px` | | **Semantic** | 없음 — 컴포넌트 크기별 짝짓기 규칙(아래 2절)으로 대신합니다 | Button `large` → `--atom-radius-r3` | > **원칙:** 기본은 `r2` 입니다. 크기가 유난히 크거나 작을 때만 위아래로 한 단계 움직입니다. > ATOM 에는 `radius.control` 같은 역할 이름이 없습니다. 원본에 없는 Semantic 토큰은 만들지 않습니다. --- ## 1. Primitive tokens `r1` 부터 `r4` 까지 4px 씩 올라가고, `full` 은 `9999px` 로 높이의 절반이 되도록 만듭니다. 라이트/다크에서 값이 같습니다. | Token | Value | 성격 | 저장소 내 사용 횟수 | |---|---|---|---| | `--atom-radius-r1` | 4px | 작은 컨트롤. 사각형에 가깝게 남는다 | 9 | | `--atom-radius-r2` | 8px | **기본값.** 대부분의 컴포넌트 | 19 | | `--atom-radius-r3` | 12px | 큰 컴포넌트, 팝오버·리스트박스 | 8 | | `--atom-radius-r4` | 16px | 다이얼로그, 디바이스 프레임 | 2 | | `--atom-radius-full` | 9999px | 원형·알약형 | 13 | `--atom-radius-r1` 은 `:focus-visible` 의 기본 outline radius 로도 쓰입니다(`base.css`). --- ## 2. Semantic tokens ATOM 은 둥글기에 역할 토큰을 두지 않습니다. 대신 **요소 크기와 짝짓는 규칙**이 그 역할을 합니다. ### 요소 크기와 짝짓기 둥글기는 요소의 **높이에 비례**해야 합니다. 같은 8px 이라도 32px 높이 버튼에서는 뚜렷하게 둥글고, 60px 높이 카드에서는 거의 각져 보입니다. 그래서 크기가 커지면 radius 도 한 단계 올립니다. 엘리먼트 CSS 도 이렇게 되어 있습니다. | 컴포넌트 | 크기 | Radius | |---|---|---| | Button | `xsmall` (32px) | `--atom-radius-full` | | Button | `small` · `medium` (38 · 47px) | `--atom-radius-r2` | | Button | `large` (54px) | `--atom-radius-r3` | | Text Input | `small` · `medium` (40 · 48px) | `--atom-radius-r2` | | Text Input | `large` (56px) | `--atom-radius-r3` | | Select trigger | `small` · `medium` | `--atom-radius-r2` | | Select trigger | `large` | `--atom-radius-r3` | | Select listbox | — | `--atom-radius-r3` | | Badge | 기본 | `--atom-radius-r1` | | Badge | `shape_pill` | `--atom-radius-full` | | Checkbox 컨트롤 | `small` · `medium` | `--atom-radius-r1` | | Radio 컨트롤 | 전부 | `--atom-radius-full` | | Search dialog | — | `--atom-radius-r4` | `xsmall` Button 만 `full` 을 씁니다. 32px 짜리 좁은 공간의 보조 액션을 알약 형태로 만들어 본문 버튼과 구분합니다. > [!WARNING] > **스케일 밖의 값이 한 곳 있습니다** > `styles/elements/checkbox.css` 의 `.atom-checkbox--size_large .atom-checkbox__control` 이 `border-radius: 5px` 를 직접 씁니다. > `r1`(4px)과 `r2`(8px) 사이 값이 필요했던 것으로 보이지만 토큰이 아닙니다. `r1` 로 되돌리거나 6px 토큰을 스케일에 추가할지 정해야 합니다. ### 규칙 1. **안쪽 요소는 한 단계 작은 radius** — 박스 안에 박스가 있을 때 안팎의 radius 가 같으면 안쪽 모서리가 바깥 곡선을 뚫고 나온 것처럼 보입니다. 안쪽에는 **바깥보다 한 단계 작은 토큰**을 씁니다. 예를 들어 Select 는 리스트박스가 `r3`, 그 안의 옵션 행이 `r2` 입니다. | 바깥 | 안쪽 | |---|---| | `--atom-radius-r4` (16px) | `--atom-radius-r3` (12px) | | `--atom-radius-r3` (12px) | `--atom-radius-r2` (8px) | | `--atom-radius-r2` (8px) | `--atom-radius-r1` (4px) | 2. **화면 폭에 따라 바꾸지 않습니다** — Codeit 은 모바일에서 한 단계 줄이고(desktop 16px → mobile 12px), Spectrum 은 반대로 늘립니다(desktop 4px → mobile 5px). ATOM 은 컴포넌트 `size` 가 이미 radius 를 바꾸므로, 브레이크포인트에서도 바꾸면 두 규칙이 충돌합니다. --- ## 3. Design tokens (JSON) [W3C Design Tokens (DTCG)](https://tr.designtokens.org/format/) 형식입니다. 경로는 `--atom-radius-*` 에서 접두어를 뗀 이름입니다. ```json { "radius": { "$type": "dimension", "r1": { "$value": "4px" }, "r2": { "$value": "8px" }, "r3": { "$value": "12px" }, "r4": { "$value": "16px" }, "full": { "$value": "9999px" } } } ``` --- ## 4. CSS 적용 ```css :root { --atom-radius-r1: 4px; --atom-radius-r2: 8px; --atom-radius-r3: 12px; --atom-radius-r4: 16px; --atom-radius-full: 9999px; } ``` ```css /* 크기가 올라가면 radius 도 한 단계 */ .atom-button { border-radius: var(--atom-radius-r2); } .atom-button--size_large { border-radius: var(--atom-radius-r3); } .atom-button--size_xsmall { border-radius: var(--atom-radius-full); } /* 중첩 — 안쪽은 바깥보다 한 단계 작게 */ .atom-select__listbox { border-radius: var(--atom-radius-r3); } .atom-select__option { border-radius: var(--atom-radius-r2); } ``` --- ## 5. 사용 가이드 ### 기본은 `r2`, 벗어날 이유가 있을 때만 바꿉니다 저장소에서 `r2` 가 19회로 가장 많이 쓰입니다. 새 컴포넌트를 만들 때는 `r2` 에서 시작하고, 크기가 유난히 크거나 작을 때만 위아래로 한 단계 움직입니다. - ✅ **Do** 판단이 서지 않으면 `--atom-radius-r2` 를 씁니다. - ❌ **Don't** 컴포넌트마다 새로운 둥글기를 고르지 않습니다. ### `full` 은 형태가 의미를 가질 때만 원형은 "아바타·라디오처럼 하나를 고르는 것", 알약형은 "태그·칩처럼 붙였다 떼는 것" 을 뜻합니다. 이런 의미가 없는 요소에는 쓰지 않습니다. - ✅ **Do** Radio · Avatar · Badge pill 처럼 형태가 의미를 갖는 곳에 씁니다. - ❌ **Don't** 일반 버튼이나 카드를 알약형으로 만들지 않습니다. ### 가로로 긴 요소에는 작은 radius 를 씁니다 폭이 높이의 3–4배를 넘는 배너·인라인 알림은 radius 가 크면 양 끝이 뭉개집니다. 길이가 길수록 한 단계 낮춥니다. - ✅ **Do** 배너처럼 납작한 박스는 `--atom-radius-r2` 이하로 둡니다. - ❌ **Don't** 높이 40px 짜리 가로 배너에 `r4`(16px) 를 쓰지 않습니다. ### 한 화면 안에서 둥글기를 섞지 않습니다 같은 위계의 요소들이 서로 다른 radius 를 가지면 정렬이 흐트러져 보입니다. 나란히 놓이는 카드·버튼은 같은 값을 씁니다. - ✅ **Do** 나란한 두 버튼은 같은 size 를 써서 radius 도 자동으로 맞춥니다. - ❌ **Don't** 한쪽만 `large` 로 두어 radius 가 어긋나게 만들지 않습니다. ### 잘리는 자식에는 `overflow: hidden` 을 함께 이미지나 배경을 가진 자식이 둥근 부모 밖으로 삐져나오지 않으려면 부모에 `overflow: hidden` 이 필요합니다. ### 접근성 - **포커스 링** — `:focus-visible` 의 outline 은 `--atom-radius-r1` 로 고정되어 있습니다(`base.css`). 요소의 radius 가 `r3` 이상이면 링과 모서리가 어긋나 보이므로, 큰 radius 를 쓰는 컴포넌트는 `outline-radius` 를 따로 맞춰야 합니다. - **형태만으로 상태를 구분하지 않습니다** — 선택된 항목을 radius 차이로만 표시하면 저시력 사용자가 알아채기 어렵습니다. 색·보더·아이콘을 함께 씁니다.