인터페이스 완성도 개선은(는) 무엇을 하나요?
이 스킬은 더 정교한 인터페이스를 위해 누적되는 작은 디자인-엔지니어링 디테일에 사용하세요.
출처: 커뮤니티 PR #1659 (linus707 님 기여)에서 발췌.
사용 시기
- 사용자가 UI가 어색하다, 평범하다, 제너릭하다, 답답하다, 덜컹거린다, 미완성 같다고 말할 때
- 컨트롤, 카드, 리스트, 대시보드, 네비게이션, 폼, 툴바를 구축 중일 때
- 컴포넌트에 호버, 활성, 포커스, 진입, 종료, 로딩, 빈 상태가 필요할 때
- 프론트엔드 리뷰에서 구체적인 before/after 권장 사항이 필요할 때
핵심 원리
동심원 반경 (Concentric Radius)
서로 가까이 중첩된 라운드 표면의 경우:
외부 반경 = 내부 반경 + 패딩
패딩이 큰 경우에는 레이어를 별도의 표면으로 취급하고 수식을 강제로 적용하지 마세요. 목표는 '공식 숭배'가 아닌 광학적 일관성입니다.
시각적 정렬 (Optical Alignment)
기하학적 중앙 정렬이 항상 시각적 중앙 정렬은 아닙니다. 아이콘 버튼, 재생 삼각형, 화살표, 별, 비대칭 아이콘은 종종 약간의 오프셋이 필요합니다. 가능하면 SVG를 수정하고, 그렇지 않으면 픽셀 단위의 마진이나 패딩 조정으로 해결하세요.
그림자와 테두리
분리와 포커스 링에는 테두리를 사용하세요. 카드, 버튼, 드롭다운, 팝오버에 깊이가 필요할 때는 레이어드 그림자를 사용하세요. 그림자는 투명하고 배경에 관계없이 동작할 수 있을 만큼 미묘해야 합니다.
텍스트 줄바꿈
- 제목과 짧은 타이틀에는
text-wrap: balance를 사용하세요. - 짧거나 중간 길이의 본문 텍스트, 캡션, 설명, 리스트 항목에는
text-wrap: pretty를 사용하세요. - 긴 산문, 코드, 미리 서식이 지정된 콘텐츠에는 둘 다 피하세요.
- 카운터, 타이머, 가격, 테이블 등 업데이트되는 숫자에는
font-variant-numeric: tabular-nums를 사용하세요.
폰트 스무딩
macOS에서 프로젝트가 아직 안티앨리어스 폰트 스무딩을 적용하지 않은 경우 루트 레이아웃에 적용하세요:
html {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
이미지 아웃라인
이미지의 가장자리가 표면에 흐릿해지지 않도록 미묘한 내부 아웃라인이 필요한 경우가 많습니다.
img {
outline: 1px solid rgba(0, 0, 0, 0.1);
outline-offset: -1px;
}
@media (prefers-color-scheme: dark) {
img {
outline-color: rgba(255, 255, 255, 0.1);
}
}
중립적인 검은색 또는 흰색 알파 아웃라인을 사용하세요. 이미지 아웃라인을 브랜드 팔레트로 색조를 입히지 마세요.
모션
사용자가 중간에 의도를 바꾸더라도 리타겟할 수 있으므로 상호작용 상태 변경에는 CSS 전환을 사용하세요. 단계별 일회성 진입 또는 로딩 시퀀스에는 키프레임을 예약하세요.
적절한 모션 기본값:
- 진입: 불투명도, 약간의
translateY, 필요시 블러를 결합합니다. - 종료: 진입보다 짧고 조용하게, 보통 150ms.
- 누름: 촉각 버튼에는
scale(0.96), 움직임이 방해가 될 때 비활성화할 방법을 제공하세요. - 아이콘 교체: 즉시 표시/숨기기 토글 대신 불투명도, 스케일, 블러로 크로스페이드 합니다.
전환 범위
transition: all을 절대 사용하지 마세요. 변경된 속성을 구체적으로 지정하세요:
.button {
transition-property: transform, background-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease-out;
}
will-change는 transform, opacity, filter와 같은 컴포지터 친화적 속성의 첫 프레임 버벅거림에만 사용하세요. will-change: all은 절대 사용하지 마세요.
히트 영역
상호작용 컨트롤은 최소 40x40px, 가능하면 레이아웃이 허용하는 경우 44x44px의 히트 영역을 가져야 합니다. 보이는 아이콘이 더 작은 경우 가상 요소로 확장하되, 확장된 히트 영역이 서로 겹치지 않도록 하세요.
리뷰 출력
UI 폴리싱 패스를 검토할 때는 before/after 행으로 구체적인 변경 사항을 보고하세요:
| 원리 | Before | After |
|---|---|---|
| 동심원 반경 | 부모와 자식에 동일한 반경 | 부모 반경이 패딩을 고려함 |
| 표 형식 숫자 | 숫자가 바뀔 때 카운터가 흔들림 | 카운터가 tabular-nums 사용 |
| 전환 범위 | transition: all | 명시적 전환 속성 |
스니펫만 봐서는 명확하지 않은 경우 파일 경로와 속성을 포함하세요. 확인했지만 변경하지 않은 원리는 생략하세요.
체크리스트
- 중첩된 라운드 요소가 광학적으로 일관됨
- 아이콘이 시각적으로 중앙 정렬됨
- 버튼, 카드, 팝오버가 올바른 이유로 테두리나 그림자를 사용함
- 제목과 짧은 텍스트가 어색하게 줄바꿈되지 않음
- 동적 숫자가 표 형식 숫자(tabular numerals)를 사용함
- 필요한 곳에 이미지가 중립적인 아웃라인을 가짐
- 진입 및 종료 애니메이션이 분리되고, 미묘하며, 적절히 중단 가능함
- 버튼이 과장된 모션 없이 촉각적인 활성 상태를 가짐
-
transition: all과will-change: all이 없음 - 작은 컨트롤도 여전히 사용 가능한 히트 영역을 가짐