컴포넌트 명세

Component Spec

산출물

부품 하나가 어떤 값을 받고 어떤 상태를 갖고 언제 어떻게 동작하는지 글로 적어 둔 문서로, 시안이 보여 주지 못하는 경우를 채웁니다.

등장 배경

시안에는 대개 잘 풀린 경우 하나만 그려져 있습니다. 버튼에는 저장이라는 두 글자가 들어가 있고, 목록에는 문서가 다섯 개 있고, 입력창은 올바른 값이 채워진 상태입니다. 화면을 설명하기에는 그걸로 충분하지만 만들기에는 모자랍니다. 만드는 쪽은 글자가 열여덟 자일 때, 목록이 비었을 때, 값이 틀렸을 때를 다 정해야 합니다.

페이지덱에서 이 차이가 드러난 건 태오가 버튼을 구현하던 주였습니다. 시안을 열고 두 시간 만에 질문이 다섯 개 쌓였습니다. 글자가 길면 자르는지 버튼을 늘리는지, 비활성일 때 글자도 흐려지는지, 누른 뒤 응답을 기다리는 동안 무엇을 보여 주는지 같은 것들이었습니다. 민서는 회의 중이었고 답은 세 시간 뒤에 왔습니다.

태오는 기다리지 않고 다섯 개를 자기 판단으로 정했습니다. 다음 주 확인 자리에서 둘이 민서 생각과 달랐고 고치는 데 하루가 들었습니다.

문제는 결정이 내려지지 않는 데 있지 않았습니다. 결정은 언제나 내려집니다. 다만 명세가 없으면 구현하는 순간에 한 사람이 조용히 내리고, 그 판단은 코드 안에만 남습니다. 컴포넌트 명세는 그 판단을 미리 내려 글로 남겨 두는 자리입니다.

구성 항목

명세 한 장은 부품 하나를 다룹니다. 들어가는 항목은 여섯입니다.

  1. 쓰임과 쓰지 말아야 할 때. 이 부품이 무엇을 위한 것인지 한 줄, 그리고 쓰면 안 되는 상황을 함께 적습니다. 화면을 떠나는 이동에는 버튼 대신 링크를 쓴다는 문장이 여기 들어갑니다.
  2. 받는 값. 쓰는 쪽이 정할 수 있는 값을 목록으로 적고 기본값을 함께 둡니다. 성격은 배리언트로 나뉜 기본·보조·위험 중 하나, 크기는 대·중·소 중 하나, 아이콘은 있음과 없음, 너비는 내용에 맞춤과 꽉 참입니다.
  3. 상태별 모습. 평소·마우스 얹힘·누름·키보드 초점·비활성·대기 여섯 가지를 각각 적습니다. 대기 상태가 특히 자주 빠지는데, 없으면 사용자가 같은 버튼을 두 번 눌러 결제가 두 번 됩니다.
  4. 경계 조건. 글자가 길 때 자르는지 줄바꿈하는지, 좁은 화면에서 어떻게 접히는지, 값이 하나도 없을 때 무엇을 보여 주는지를 정합니다. 이 항목이 명세를 쓰는 진짜 이유에 가깝습니다.
  5. 접근성 규칙. 키보드 이동 순서에서 몇 번째인지, 화면 낭독기가 읽을 이름은 무엇인지, 글자와 배경의 밝기 차이는 얼마 이상인지를 적습니다. 접근성은 나중에 붙이면 부품을 다시 만들게 되는 항목이라 이 단계에서 정해 둡니다.
  6. 이름. 시안에서 부르는 이름과 코드에서 부르는 이름을 나란히 적습니다. 둘이 같으면 핸드오프, 곧 디자인을 개발에 넘기는 자리에서 무엇을 가리키는지 되묻는 일이 사라집니다.

여기 적는 색과 간격은 숫자가 아니라 디자인 토큰, 곧 값에 이름을 붙여 둔 단위로 씁니다. 배경을 #2F6BFF 로 적으면 색이 바뀌는 날 명세가 어긋나지만, 토큰 이름으로 적으면 값이 바뀌어도 문장은 맞습니다.

작성자와 독자

첫 줄은 디자이너가 쓰고 나머지는 구현하면서 함께 채웁니다. 민서가 부품을 만들며 쓰임과 받는 값과 상태를 적어 두면, 태오가 구현 중 부딪힌 경우가 4번 항목으로 들어갑니다. 질문 하나가 명세 한 줄이 되는 셈이라 문서는 만들어지기보다 자랍니다.

읽는 쪽은 셋입니다.

  1. 구현하는 개발자. 가장 많이 펴 보는 사람입니다. 명세가 답하지 못하는 질문은 그 자리에서 묻고, 답이 정해지면 명세에 적어 다음 사람의 질문 하나를 줄입니다.
  2. 확인하는 사람. 확인할 항목이 명세에서 그대로 나옵니다. 상태 여섯 개와 경계 조건 세 개가 적혀 있으면 확인할 것이 아홉 개고, 적혀 있지 않으면 무엇을 볼지부터 사람마다 달라집니다.
  3. 다른 디자이너. 같은 부품을 쓸 때 어디까지 바꿔도 되는지를 여기서 봅니다. 색과 간격의 일반 규칙은 스타일 가이드에 있고, 이 부품 하나에만 해당하는 규칙이 명세에 있습니다.

명세는 부품 옆에 붙어 삽니다. 부품을 모아 둔 컴포넌트 라이브러리에서 부품을 고르면 명세가 함께 열리고, 코드 쪽에서는 부품만 따로 띄워 보는 스토리북의 문서 칸이 같은 자리를 맡습니다. 떨어진 문서함에 두면 찾는 데 시간이 들고, 그러면 아무도 읽지 않습니다.

실무 용례

"이 버튼 명세에 대기 상태가 없어서 일단 제 판단으로 넣었어요. 맞나요?"

적혀 있지 않은 경우를 만나 스스로 정했으니 확인해 달라는 말입니다.

"명세부터 볼게요. 글자 길어지면 자르기로 돼 있네요."

구현 전에 정해진 답이 있는지 확인하는 순서입니다.

"확인 항목은 명세 기준으로 뽑았습니다."

무엇을 확인할지를 사람 감이 아니라 문서에서 가져왔다는 뜻입니다.

모달을 만들던 날 태오가 물었습니다. ESC 키로 닫히는지, 바깥을 눌렀을 때는 어떤지. 민서가 명세를 열었는데 두 줄 다 없었습니다. 둘은 그 자리에서 정했습니다. 저장하지 않은 내용이 있으면 되묻고 없으면 바로 닫기로 했고, 민서는 회의가 끝나기 전에 그 문장을 명세에 넣었습니다.

다음 달 다른 개발자가 설정 화면에 같은 모달을 쓸 때 이 질문은 나오지 않았습니다. 명세가 값어치를 하는 자리는 처음이 아니라 두 번째부터입니다. 처음에는 옆 사람에게 물으면 되지만, 두 번째 사람은 그 대화가 있었다는 사실조차 모릅니다.

흔한 오해

명세를 시안이 부실할 때 채우는 보완물로 읽는 경우가 많습니다. 시안이 꼼꼼하면 굳이 글로 적을 게 없어 보이니 그렇게 읽힙니다. 실제로 명세가 맡는 건 시안이 보여 줄 수 없는 것들입니다. 3초 뒤 사라지는 알림, 서버가 느릴 때 나타나는 대기 모습, 글자가 스물두 자로 늘어난 경우는 정지된 화면 한 장에 담기지 않습니다. 시안을 아무리 꼼꼼히 그려도 이 자리는 비고, 비어 있으면 구현하는 사람이 그때그때 메웁니다.

처음에 완성해 두어야 하는 문서라는 오해도 흔합니다. 명세라는 말이 개발 전에 확정하는 설계도처럼 들리기 때문입니다. 실제로는 구현 중 나온 질문이 한 줄씩 붙으며 자라는 쪽입니다. 처음부터 빠짐없이 쓰려 들면 아무도 부딪히지 않을 경우를 적느라 분량만 늘고, 현장에서 나온 질문은 빠진 채 남습니다. 그런 문서는 두 달이면 읽히지 않습니다.

같이 보면 좋은 페이지

마지막 업데이트 2026-09-16