Communitygithub.com

jakubkrehel/better-ui

프로젝트 UI를 세밀하게 다듬고 개선합니다. 동심원 테두리 반경, 광학 정렬, 표면 깊이, 상황에 맞는 아이콘, 히트 영역 등 다양한 요소를 다룹니다.

better-ui란 무엇인가요?

이 스킬은 UI 폴리싱의 핵심 원칙들을 상세히 정의하여, 개발자와 AI 에이전트가 일관된 고품질 인터페이스를 구축할 수 있도록 돕습니다. 특히 중첩된 요소의 테두리 반경 불일치, 광학적 정렬 오류, 애니메이션 값의 부정확한 사용 등 미묘하지만 전체적인 인상에 영향을 미치는 세부 사항들을 교정하는 데 중점을 둡니다. 모든 규칙은 구체적인 수치(예: `cubic-bezier(0.2, 0, 0, 1)`, `scale(0.96)`)를 포함하여 모호함 없이 적용할 수 있도록 기술되어 있으며, CSS, Tailwind, Framer Motion 등 다양한 환경에서 동작하는 레시피를 제공합니다. 또한, 인터럽트 가능한 전환, 분할된 엔트리 애니메이션, 테마 전환 시 트랜지션 억제 등 성능과 접근성을 고려한 실용적인 지침을 포함하고 있어, Claude Code, Cursor, Codex와 같은 AI 기반 코딩 도구가 UI 리뷰 및 자동 수정 작업을 수행할 때 매우 유용합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jakubkrehel/skills/tree/main/skills/better-ui

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

UI 폴리싱

폴리싱은 작은 세부 사항들이 쌓여 만들어집니다. 이 스킬은 어떤 세부 사항이 가치 있고 어떤 값을 가져야 하는지에 대한 기준을 제공합니다.

리뷰할 때는 인터페이스 속도를 늦추십시오. 10% 속도에서 어색하게 느껴지는 것이 정상 속도에서는 미묘하게 잘못된 것입니다.

프로젝트의 컴포넌트 라이브러리, 토큰 및 밀도를 유지하고, 아래 규칙이 정확한 상호작용을 명시하는 경우를 제외하고는 프로젝트의 모션 언어를 일치시키십시오.

아래의 모든 지속 시간, 곡선, 스케일 및 블러는 근사치가 아닌 특정 값입니다. cubic-bezier(0.2, 0, 0, 1)는 cubic-bezier(0.4, 0, 0.2, 1)이 아니며, 0.96은 0.95가 아닙니다. 적힌 그대로 사용하십시오.

텍스트 줄바꿈, 글꼴 렌더링, 표 형식 숫자 및 텍스트 간격은 better-typography에 속합니다. 히트 영역, 포커스, 키보드 지원, ARIA 및 축소 모션은 better-accessibility에 속합니다. 그룹화, 섹션 간격, 중단점 및 공간 RTL은 better-layout에 속합니다.

동심원 테두리 반경

바깥쪽 반경 = 안쪽 반경 + 패딩. 중첩된 요소의 반경 불일치는 인터페이스가 어색하게 느껴지게 만드는 가장 흔한 원인입니다. 반경, 그림자 및 윤곽선 레시피는 surfaces.md에 있습니다.

기하학적 정렬보다 광학 정렬

기하학적 중앙 정렬이 어색해 보일 때는 광학적으로 정렬하십시오. 아이콘이 있는 버튼, 재생 삼각형 및 비대칭 아이콘은 모두 수동 조정이 필요합니다.

입체감을 위한 그림자, 구조를 위한 테두리

테두리가 오직 깊이를 만들기 위해서만 존재하는 경우, 투명한 레이어 box-shadow 값을 선호하십시오. 구조나 상태(구분선, 분리선, 선택 또는 포커스 상태)를 전달하는 테두리는 유지하십시오.

인터럽트 가능한 애니메이션

상호작용 상태 변경에는 CSS 전환을 사용하십시오. 애니메이션 중간에 중단될 수 있기 때문입니다. 한 번 실행되는 단계별 시퀀스에는 키프레임을 사용하십시오.

엔트리 애니메이션 분할 및 지연

시퀀스가 계층 구조를 전달하는 드문 단계적 입장의 경우, 콘텐츠를 의미 있는 청크로 나누고 약 100ms 간격으로 지연시키십시오. 하나의 컨테이너에 애니메이션을 적용하는 것은 같은 비용으로 더 적은 효과를 냅니다. 빈도가 높은 상호작용에는 지연을 적용하지 마십시오. enter-exit.md를 참조하십시오.

미묘한 종료 애니메이션

전체 높이 대신 작은 고정 translateY를 사용하십시오. 종료 애니메이션은 입장 애니메이션보다 더 부드러워야 합니다. 두 방향 모두 ease-out을 사용하십시오.

상황에 맞는 아이콘 애니메이션

아이콘을 보이기/숨기기 전환 대신 opacity, scale 및 blur로 애니메이션 처리하십시오. 정확히 다음 값을 사용하십시오: scale 0.25에서 1, opacity 0에서 1, blur 4px에서 0px.

모션 라이브러리(package.json에 motion 또는 framer-motion이 있는 경우)를 사용하는 경우, 해당 패키지의 import 경로 또는 둘 다 존재하는 경우 인접한 import 경로와 일치시키십시오. transition: { type: "spring", duration: 0.3, bounce: 0 }를 사용하십시오. 바운스는 항상 0입니다.

모션 라이브러리가 없는 경우, 두 아이콘을 모두 DOM에 유지하고 하나는 절대 위치로 지정한 다음 cubic-bezier(0.2, 0, 0, 1)로 크로스페이드하십시오. 이렇게 하면 종속성 없이 입장 및 종료 애니메이션을 얻을 수 있습니다. 두 레시피 모두 icon-transitions.md에 있습니다.

이미지 윤곽선

일관된 깊이를 위해 이미지에 낮은 불투명도의 1px 윤곽선을 지정하십시오. 라이트 모드에서는 순수한 검정(oklch(0 0 0 / 0.1)), 다크 모드에서는 순수한 흰색(oklch(1 0 0 / 0.1))을 사용하십시오. 슬레이트나 아연 같은 검정에 가까운 색상이나 색조가 있는 중립색은 절대 사용하지 마십시오. 색조가 있는 윤곽선은 아래 표면의 색을 띠어 이미지 가장자리에 먼지처럼 보입니다.

누를 때 크기 조정

클릭 시 scale(0.96)은 버튼에 촉각적 피드백을 제공합니다. 항상 0.96입니다. 0.95 미만은 과장된 느낌을 줍니다. 모션이 방해가 될 수 있는 곳에서는 static prop을 추가하여 비활성화하십시오. CSS, Tailwind 및 Motion 레시피를 참조하십시오.

페이지 로드 시 애니메이션 건너뛰기

AnimatePresence에서 initial={false}를 사용하여 첫 번째 렌더링에서 엔트리 애니메이션이 실행되지 않도록 하십시오. 의도적인 페이지 입장 애니메이션이 그대로 유지되는지 확인하십시오.

테마 전환 시 트랜지션 억제

테마 전환은 거의 모든 요소의 색상, 배경, 테두리 및 그림자를 동시에 변경합니다. 이러한 속성의 모든 트랜지션이 함께 실행되면 전환이 부드럽게 전환되지 않고 번집니다. *,*::before,*::after{transition:none !important}를 주입하고, 리플로우를 강제로 발생시킨 다음, 다음 프레임에서 제거하십시오. 레시피를 참조하십시오.

변경되는 것만 전환

항상 정확한 속성을 지정하십시오: transition-property: scale, opacity. Tailwind의 transition-transform은 transform, translate, scale, rotate를 포함합니다.

will-change는 드물게 사용

GPU가 합성할 수 있는 transform, opacity 및 filter에만 사용하십시오. will-change: all은 절대 사용하지 마십시오. 첫 프레임에서 끊김이 관찰될 때 추가하고, 그 전에는 추가하지 마십시오. performance.md를 참조하십시오.

아이콘 선 두께를 텍스트 두께와 일치

텍스트 옆에 있는 아이콘은 텍스트의 광학적 두께를 전달해야 합니다. 일반(400) 텍스트 옆에는 1.5px 선, 반굵은(600) 텍스트 옆에는 2px 선을 사용하십시오. 아이콘 세트당 하나의 선 두께와 표면당 하나의 아이콘 라이브러리를 사용하십시오. 크기 조정 및 RTL 뒤집기는 icons.md에 있습니다.

상태별로 색상이 변경되는 하나의 SVG

아이콘은 currentColor를 사용하며, 별도의 에셋이 아닌 CSS 색상 및 불투명도로부터 호버, 선택 및 비활성화 상태를 가져옵니다. 윤곽선이 기본 변형이고, 채우기가 활성 상태를 표시합니다.

모션 절제

빈도가 높은 상호작용에는 즉각적인 피드백을 제공하거나, 불투명도 및 색상에 대해 150ms 이하의 전환을 사용하십시오. 사용자 정의 애니메이션은 트리거될 때마다 주의 비용을 청구합니다.

모든 애니메이션 상태 변경에는 정적 단서(색상, 아이콘 또는 레이블)도 함께 제공되어야 합니다. 모션은 결코 유일한 피드백 채널이 되어서는 안 됩니다.

마치기 전에

실수수정 방법
아이콘이 중앙에 있지 않아 보임패딩으로 광학적으로 조정하거나 SVG 수정
어색한 단계적 입장 또는 종료드문 입장은 지연; 종료는 미묘하게 유지
테마 전환이 전체 페이지를 크로스페이드전환 비활성화 후 리플로우 강제, 다음 프레임에서 복원
요소에 transition: all정확한 속성 지정
첫 프레임 애니메이션 끊김will-change: transform 추가 (드물게)
굵은 텍스트 옆에 가는 아이콘선 두께를 텍스트 두께와 일치

보고

심각도. HIGH는 상호작용을 깨뜨리거나, 모션을 사용할 수 없게 만들거나, 애니메이션이 실행되는 동안에만 상태 변경이 보이도록 합니다. MEDIUM은 표면, 아이콘 또는 모션에서 눈에 띄는 불일치입니다. LOW는 고립된 폴리싱 문제입니다.

검증. 브라우저 없이: 컴포넌트가 정의하는 모든 상태(호버, 포커스, 활성, 로딩, 빈 상태)와 코드에서 읽은 모션 지속 시간 및 이징을 확인합니다. 브라우저를 사용하는 경우: 각 상태를 살펴보고, 브라우저의 애니메이션 패널에서 10% 속도로 모션을 재생합니다. 실행할 수 없었던 모든 검사는 Not verified로 보고하십시오.

형식. 각각 위반하는 원칙 아래에 결과를 그룹화하고, 심각도 순으로 정렬하며, 근본 원인당 한 행에 나타나는 모든 위치를 나열합니다:

심각도위치수정 전수정 후이유

위치는 경로/파일:줄입니다. 이유는 위반한 원칙과 사용자 영향을 명시합니다.

HIGH가 남아 있으면 Block으로 끝내고, 그렇지 않으면 Approve로 끝내되, 나머지는 테이블에 남겨 할 일로 표시합니다. 검사하지 않은 범위에 대해 Approve를 절대 하지 마십시오. 보고할 내용이 없으면 "실행 가능한 UI 폴리싱 발견 사항 없음"을 명시하고 검증 결과를 보고하십시오.

Individual skills in this repo

This repo contains 7 individual skills — each has its own dedicated page.

관련 스킬