Get StartedFoundationsComponentsPatternsRulesDevelopAI & ToolsUpdates

Feedback

피드백은 사용자의 입력에 대한 즉각적인 반응이에요. 요소가 조작 가능하다는 사실과 입력이 전달됐다는 사실을 알려줘요.

사용자가 요소를 누르면 인터페이스는 그 입력이 전달됐음을 즉시 알려야 해요. 이 즉각적인 반응이 피드백이에요. State 가 정의한 pressed 상태를 사용자가 눈과 손으로 알아챌 수 있게 드러내는 역할을 해요.

Feedback Elements

피드백 요소전달 방식
Color눌린 동안 표면 색이 바뀌어요
Scale눌린 동안 요소가 정해진 거리만큼 작아져요
Haptic누른 순간 손끝에 진동이 전해져요

이 세 가지를 함께 사용해 눌림을 전달해요. 색은 누를 수 있는 요소 전반에 적용되는 기본 요소이고, 축소는 요소의 구조가 허락할 때 여기에 더해져요. Haptic은 팀에서 필요에 따라 정의해 사용해요.

Principles

피드백 요소를 함께 사용하기

한 번의 입력에서 여러 피드백 요소가 동작하면, 사용자는 이를 하나의 반응으로 인지해야 해요. 시작 시점이나 속도가 서로 다르면 반응이 둘로 나뉘어 읽히고, 요소가 잘못 동작하는 것처럼 느껴져요. 그래서 색 전환($duration.color-transition)과 축소($duration.pressed-scale)는 같은 $duration.d3(150ms)를 참조해요.

어떤 환경에서도 반응 남기기

축소는 OS의 동작 줄이기 설정이 켜져 있으면 일어나지 않고, Haptic은 기기에 따라 전달되지 않아요. 어떤 요소가 빠지더라도 눌렸다는 사실은 남아야 하므로, 설정의 영향을 받지 않는 색 전환을 기본으로 두고 나머지를 그 위에 더해요.

Color

색은 눌림을 알리는 가장 기본적인 방법이에요. 표면 색이 바뀌는 것만으로 사용자는 자신이 어디를 눌렀는지, 입력이 요소에 도달했는지 바로 알 수 있어요.

눌린 색은 토큰으로 정의해요

눌린 색은 새로 만들지 않고, 역할 기반 색상 체계 안에서 -pressed 가 붙은 짝 토큰을 사용해요. Action Button의 brandSolid는 기본 상태에서 $color.bg.brand-solid 를, 눌린 동안 $color.bg.brand-solid-pressed 를 써요.

기본눌림 (pressed)LightDark

색은 표면에서만 바뀌어요

색 전환은 요소의 표면에서 일어나요. 그 위에 놓인 텍스트와 아이콘의 색은 눌림에 반응하지 않아요. 표면과 글자 색이 함께 바뀌면 요소 전체가 다른 요소로 바뀐 것처럼 읽혀요. 그래서 전경용 pressed 토큰은 제공하지 않아요.

직접 만드는 요소에 적용할 때

  1. 기본 색에 대응하는 pressed 토큰 찾기 — 배경이 $color.bg.neutral-weak 라면 눌린 동안 $color.bg.neutral-weak-pressed 를 사용해요.
  2. 기본 상태에 배경색이 없는 경우 — ghost 버튼처럼 평소 배경이 없는 요소도 눌린 동안에는 $color.bg.transparent-pressed 표면이 생겨요. 알파 값이라 어떤 배경 위에서도 자연스럽게 겹쳐요. floating 레이어 위에서는 $color.bg.layer-floating-pressed 를 사용해요.
  3. 색을 쓰지 않는 경우인지 확인하기 — Switch나 탭처럼 색이 이미 상태(켜짐/선택)를 나타내는 요소는 눌림에 색을 쓰지 않고 축소만 사용해요. 아직 손을 떼지 않았는데 상태가 바뀐 것처럼 보이기 때문이에요.

Scale

누를 수 있는 요소는 눌린 동안 살짝 작아져요. 물리적인 버튼이 눌려 들어가는 감각을 빌려와, 손끝의 입력이 요소에 도달했음을 바로 알게 해요.

중요한 것은 모든 요소에서 눌린 느낌의 양이 같게 느껴지는 것이에요. 고정 배율(예: 0.98)은 요소가 클수록 실제로 움직이는 거리가 커져요.

요소 크기 (폭 × 높이)배율가로 축소세로 축소
80 × 520.981.6px1.04px
160 × 520.983.2px1.04px
343 × 52 (모바일 전체 폭)0.986.9px1.04px
720 × 52 (태블릿 전체 폭)0.9814.4px1.04px

그래서 눌렸을 때 요소가 정해진 거리만큼 줄어든다고 정의해요. 배율은 요소의 실제 크기에서 계산되는 결과예요.

계산 방식

basis = max(요소 높이, 요소 폭 ÷ 4, 24)
배율  = (basis - 2) ÷ basis
  • 기준 길이(basis)는 기본적으로 요소의 높이예요.
  • 요소 폭 ÷ 4 — 좌우로 긴 요소가 가로로 지나치게 많이 움직이지 않도록 보정해요.
  • 최소 24 — 아주 작은 요소의 축소 비율이 8.3%를 넘지 않도록 보장해요.

폭과 높이를 바꿔 보며 배율을 확인하고, 버튼을 눌러 보세요.

basis
48.0 (높이)
배율
0.958
가로 축소
5.0px
세로 축소
2.0px

Clay 컴포넌트의 축소

registry 컴포넌트는 Tailwind 유틸로 기본 크기에 맞춘 근사 배율을 사용해요. 일반 요소는 enabled:active:scale-[0.97], 작은 요소는 0.95 를 써요.

축소 규칙

  • 축소는 항상 요소의 정가운데를 기준으로 일어나요.
  • 축소는 자리를 바꾸지 않아요. 눌린 요소가 작아져도 주변 요소는 움직이지 않아요.
  • 문장 안의 링크 텍스트처럼 영역이 하나의 면으로 잡히지 않는 요소에는 적용하지 않아요.
  • 카드 안에 열기·좋아요·저장처럼 대등한 동작이 나란히 있으면 카드 전체가 아닌 눌린 타깃만 반응해요.
  • List Item처럼 배경이 화면 폭을 채우는 구조는 배경은 그대로 두고 콘텐츠만 줄여요(Content Scale).
  • 이미 축소하는 요소 안에 놓인 요소는 자신의 축소를 꺼요. 겹치면 배율이 곱해져 과도하게 작아져요.

다른 상태와 함께 있을 때

  • Selected — 누르면 축소돼요. 선택 색상은 그대로 유지돼요.
  • Loading — 축소하지 않아요. 이미 진행 중인 동작이 있어 추가 입력을 받지 않아요.
  • Disabled — 축소하지 않아요.

Accessibility

OS의 동작 줄이기(Reduce Motion) 설정이 켜져 있으면 배율은 항상 1 이 되어 축소가 일어나지 않아요. 이때는 색 변화가 눌림을 전달해요.

On this page