그림자

그림자 (Shadow)

그림자는 실생활에서 물체 사이의 거리를 반영하는 물리적 현상에서 비롯돼요. 사용자 인터페이스(UI)에서는 요소 투영(projection)을 통해 이를 시뮬레이션해서, 요소 사이의 높이 거리와 레이어 위계를 사용자에게 알려 주는 경우가 많아요.

출처: 문서

본문

높이 (Height)

그림자는 서로 다른 레벨에 있는 두 표면에 의해 생겨나고, 그 강도는 두 표면 사이의 거리에 의해 결정돼요. 따라서 객체의 높이는 그림자에 직접 영향을 줘요. 객체가 바닥에서 멀수록 그림자는 더 크고 흐려져요. 우리는 시스템을 없음(none), 낮음(low), 중간(medium), 높음(high) 네 가지 UI 레벨로 나누고, 각 레벨을 서로 다른 높이에 분배하며 각기 다른 그림자 속성을 갖게 해요.

높이 레벨

Layer 0: 객체가 바닥에 가까우면 그림자가 객체 자체와 완전히 겹쳐요. UI에서는 이 레이어에 그림자 값을 정의하지 않아요. 예: 입력 상자(input boxes).

높이 레이어 0

Layer 1: 객체가 낮은 레벨에 나타날 때, 조작(호버, 클릭 등)하면 떠 있는 상태로 들어가요. 조작이 완료되거나 취소되면 호버 상태 피드백이 사라지고 객체는 원래 레벨로 돌아가요. 예: 카드 호버링.

높이 레이어 1

Layer 2: 객체가 중간 레벨에 나타날 때 확장되며 참조 레이어와의 관계를 따릅니다. 객체는 바닥에 있는 요소에서 열리고 그 레벨에 있는 요소의 움직임을 따라 이동해요. 예: 드롭다운 패널(dropdown panels).

높이 레이어 2

Layer 3: 객체가 높은 레벨에 나타날 때, 그 움직임은 다른 레벨과 독립적이에요. 예: 대화 상자(dialog boxes).

높이 레이어 3

광원 (Light Source)

그림자의 방향은 광원과 객체 사이의 상대적 위치에 의해 결정돼요. 광원의 높이가 일정하다고 가정하면, 광원과 객체 사이의 거리와 객체와 그림자 사이의 거리는 정비례해요. 광원이 멀수록 그림자는 객체에서 더 멀어져요. UI에서 그림자의 방향은 보통 X, Y 좌표로 표현돼요.

광원

그림자 값 (Shadow Values)

앞서 언급했듯이 그림자는 조명에 의해 생성돼요. 그 값에 영향을 주는 주요 요인은 객체의 높이와 광원의 위치예요.

  1. 높이에 따라 그림자의 색, 흐림, 면적이 달라져요. 바닥에서 더 먼 객체는 더 옅고 블러가 크며 면적이 큰 그림자를 만들고, 바닥에 더 가까운 객체는 더 어둡고 블러가 작으며 면적이 작은 그림자를 만들어요.
  2. 투영의 방향은 주로 광원과 객체의 상대적 위치에 의해 결정돼요.

Ant Design에서는 다양한 맥락에서 다른 그림자 방향을 사용해요.

  • 아래쪽 그림자(Downwards Shadow): 주로 컴포넌트 내부나 컴포넌트 자체에 사용되며 가장 흔한 사용 사례예요.
  • 위쪽 그림자(Upwards Shadow): 주로 하단 내비게이션이나 툴바 등에 적용돼요.
  • 왼쪽 그림자(Leftwards Shadow): 주로 오른쪽 사이드 내비게이션 바, 드로어 컴포넌트, 또는 고정 테이블 헤더에 사용돼요.
  • 오른쪽 그림자(Rightwards Shadow): 주로 왼쪽 사이드 내비게이션 바, 드로어 컴포넌트, 또는 고정 테이블 헤더에 사용돼요.

그림자는 현실 세계의 피드백을 시뮬레이션해요. 그림자를 더 사실적으로 만들기 위해, Ant Design은 버전 4.0에서 3레이어 그림자 표현 방식을 채택해 그림자를 더 부드럽고 사실적으로 만들었어요.

그림자 값

일반적인 그림자 사용 디자인 표 (Common Shadow Usage Design Table)

Layer One:

Shadow Type Shadow Color (rgba) Direction (X, Y) Blur Spread
@shadow-1-up rgba(0, 0, 0, 0.16) 0px, -1px 2px -2px
@shadow-1-up rgba(0, 0, 0, 0.12) 0px, -3px 6px 0px
@shadow-1-up rgba(0, 0, 0, 0.09) 0px, -5px 12px 4px
@shadow-1-down rgba(0, 0, 0, 0.16) 0px, 1px 2px -2px
@shadow-1-down rgba(0, 0, 0, 0.12) 0px, 3px 6px 0px
@shadow-1-down rgba(0, 0, 0, 0.09) 0px, 5px 12px 4px
@shadow-1-left rgba(0, 0, 0, 0.16) -1px, 0px 2px -2px
@shadow-1-left rgba(0, 0, 0, 0.12) -3px, 0px 6px 0px
@shadow-1-left rgba(0, 0, 0, 0.09) -5px, 0px 12px 4px
@shadow-1-right rgba(0, 0, 0, 0.16) 1px, 0px 2px -2px
@shadow-1-right rgba(0, 0, 0, 0.12) 3px, 0px 6px 0px
@shadow-1-right rgba(0, 0, 0, 0.09) 5px, 0px 12px 4px

Layer Two:

Shadow Type Shadow Color (rgba) Direction (X, Y) Blur Spread
@shadow-2-up rgba(0, 0, 0, 0.12) 0px, -3px 6px -4px
@shadow-2-up rgba(0, 0, 0, 0.08) 0px, -6px 16px 0px
@shadow-2-up rgba(0, 0, 0, 0.05) 0px, -9px 28px 8px
@shadow-2-down rgba(0, 0, 0, 0.12) 0px, 3px 6px -4px
@shadow-2-down rgba(0, 0, 0, 0.08) 0px, 6px 16px 0px
@shadow-2-down rgba(0, 0, 0, 0.05) 0px, 9px 28px 8px
@shadow-2-left rgba(0, 0, 0, 0.12) -3px, 0px 6px -4px
@shadow-2-left rgba(0, 0, 0, 0.08) -6px, 0px 16px 0px
@shadow-2-left rgba(0, 0, 0, 0.05) -9px, 0px 28px 8px
@shadow-2-right rgba(0, 0, 0, 0.12) 3px, 0px 6px -4px
@shadow-2-right rgba(0, 0, 0, 0.08) 6px, 0px 16px 0px
@shadow-2-right rgba(0, 0, 0, 0.05) 9px, 0px 28px 8px

Layer Three:

Shadow Type Shadow Color (rgba) Direction (X, Y) Blur Spread
@shadow-3-up rgba(0, 0, 0, 0.08) 0px, -6px 16px -8px
@shadow-3-up rgba(0, 0, 0, 0.05) 0px, -9px 28px 0px
@shadow-3-up rgba(0, 0, 0, 0.03) 0px, -12px 48px 16px
@shadow-3-down rgba(0, 0, 0, 0.08) 0px, 6px 16px -8px
@shadow-3-down rgba(0, 0, 0, 0.05) 0px, 9px 28px 0px
@shadow-3-down rgba(0, 0, 0, 0.03) 0px, 12px 48px 16px
@shadow-3-left rgba(0, 0, 0, 0.08) -6px, 0px 16px -8px
@shadow-3-left rgba(0, 0, 0, 0.05) -9px, 0px 28px 0px
@shadow-3-left rgba(0, 0, 0, 0.03) -12px, 0px 48px 16px
@shadow-3-right rgba(0, 0, 0, 0.08) 6px, 0px 16px -8px
@shadow-3-right rgba(0, 0, 0, 0.05) 9px, 0px 28px 0px
@shadow-3-right rgba(0, 0, 0, 0.03) 12px, 0px 48px 16px

더 알아보기 (Learn more)