Communitygithub.com

wensity/wensity-layout

고정 간격 스케일, 명확한 그룹화, 정렬, 그리드, 컨테이너, 테이블 및 320px 휴대폰부터 와이드 데스크톱까지 대응하는 반응형 구조로 웹 UI를 배치합니다. React, Next.js, Tailwind CSS 또는 CSS로 페이지, 섹션, 폼 또는 대시보드 레이아웃을 만들거나 간격, 정렬, 그리드, 컨테이너 또는 반응형 동작을 변경할 때 사용하세요. 간격이 무작위적이거나, 비좁거나 너무 넓은 경우, 정렬이 맞지 않는 경우, 모바일에서 레이아웃이 깨지는 경우, 또는 사용자가 패딩, 마진, 갭, 그리드, 여백, 밀도 또는 반응형 디자인을 언급할 때 사용합니다. 레이아웃을 변경하지 않는 편집의 경우 건너뛰세요.

wensity-layout란 무엇인가요?

이 스킬은 웹 개발자와 AI 에이전트가 일관되고 전문적인 UI 레이아웃을 구축할 수 있도록 설계된 종합 레이아웃 시스템입니다. 4px 기반 간격 스케일, 거리 기반 그룹화, 단일 시작 가장자리 정렬 등 핵심 레이아웃 원칙을 설정하는 방법을 상세히 설명합니다. 스킬은 React, Next.js, Tailwind CSS 및 일반 CSS 프로젝트에서 작동하며, 320px 모바일 기기에서 와이드 데스크톱까지 모든 화면 크기에 대응하는 반응형 구조를 제공합니다. 프로즈, 내로우, 콘텐츠, 와이드, 풀 블리드의 5가지 컨테이너 너비를 정의하고, 12열 그리드 시스템, 카드 자동 채움 그리드, 벤토 그리드 등 다양한 그리드 패턴을 다룹니다. 또한 테이블 레이아웃, 밀도 관리, 터치 타겟 크기(min 44px), z-index 계층, 스티키 요소, 안전 영역 처리 등 실무적인 요구사항을 포함하여 실제 프로젝트에서 바로 적용할 수 있는 체크리스트를 제공합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/wensity/skills/tree/HEAD/skills/wensity-layout

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

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

문서

Wensity Layout (레이아웃)

레이아웃은 사람들이 글자를 읽기도 전에 페이지가 무엇이 중요하고 무엇이 함께 속하는지를 전달하는 방식입니다. 좋은 레이아웃은 고정된 간격 스케일, 거리별 그룹화, 하나의 정렬 시스템이라는 세 가지 습관에서 비롯됩니다. 이 스킬은 이 세 가지를 모두 설정하고 반응형 구조를 다룹니다.

프로젝트에 이미 간격 스케일과 컨테이너 너비가 있다면 그것들을 사용하세요.

1. 간격 스케일 (Spacing Scale)

4px 기준을 사용하세요. 모든 마진, 패딩 및 갭은 이 목록에서 가져옵니다:

토큰px일반적인 용도
14아이콘과 레이블 사이, 좁은 인라인 갭
28컨트롤 내부, 레이블과 입력 필드 사이
312밀집 목록의 항목 사이, 버튼 패딩 y
416카드 패딩(컴팩트), 관련 컨트롤 사이 갭, 모바일 페이지 거터
520버튼 패딩 x (대형)
624카드 패딩, 양식 필드 사이 갭
832섹션 내 그룹 사이
1040섹션 제목과 콘텐츠 사이 (대형)
1248모바일 섹션 패딩
1664앱 내 섹션 사이, 태블릿 섹션 패딩
2080
2496데스크톱 마케팅 페이지의 섹션 패딩
32128히어로 패딩, 하나의 큰 문장을 둘러싸는 공간

Tailwind의 기본 스케일은 이미 4px 기준을 따릅니다(p-4는 16px). 그러므로 Tailwind의 단계를 사용하고 p-[13px] 같은 것을 만들지 마세요. 홀수 값은 렌더링에서 확인한 시각적 보정(1px 차이가 나는 아이콘)에만 허용됩니다.

2. 거리별 그룹화 (Group by Distance)

가장 중요한 단일 레이아웃 규칙: 그룹 내부의 공간은 그룹 사이의 공간보다 작아야 합니다. 레이블은 입력 필드에서 8px 떨어져 있고, 다음 필드는 24px 떨어져 있습니다. 카드 제목은 텍스트 위 8px, 다음 카드는 24px 떨어져 있습니다. 내부와 외부 간격이 같으면 모든 것이 떠다니고 아무것도 그룹으로 읽히지 않습니다.

  • 내부 갭과 외부 갭의 비율을 약 1:2 또는 1:3으로 목표하세요.
  • 제목 위에는 아래보다 더 많은 공간을 두세요. 제목은 뒤따르는 콘텐츠에 속합니다. 일반적: 섹션 제목 위 48px, 아래 16px.
  • 박스 앞에는 간격을 두세요. 먼저 거리로 그룹화하세요. 거리만으로 충분하지 않을 때만(밀집 테이블, 툴바, 복잡한 배경의 콘텐츠) 테두리, 구분선 또는 배경을 추가하세요. 모든 그룹 주위에 박스를 두면 페이지가 무거워집니다.
  • 형제 요소에는 gap을 사용하세요(flex gap-4, grid gap-6) 자식에 마진을 사용하는 대신. 간격을 한 곳에 유지하고 목록 끝의 잘못된 마진을 방지합니다.

3. 리듬, 단일함이 아닌 (Rhythm, Not Sameness)

모든 섹션이 96px 패딩, 중앙 정렬 제목, 세 개 항목의 그리드를 가진 페이지에는 리듬이 없습니다. 의도적으로 밀도를 다양화하세요:

  • 밀집된 섹션(특징 그리드, 테이블, 로고)과 열린 섹션(한 문장, 하나의 큰 이미지)을 번갈아 사용하세요.
  • 중요한 섹션에 더 많은 공간을 할당하세요. 공간은 주의를 분배하는 방법입니다.
  • 콘텐츠가 진정으로 동일한 종류의 것일 때만 레이아웃을 반복하세요.

4. 정렬 (Alignment)

  • 하나의 시작 가장자리. 섹션의 제목, 단락, 버튼 및 이미지는 동일한 시작 선을 공유합니다. 대부분의 "뭔가 어색하다"는 불만은 몇 픽셀 차이 나는 두 가장자리 때문입니다.
  • 기본적으로 시작에 정렬하세요(text-align: start, 영어에서는 왼쪽, 아랍어 또는 히브리어에서는 오른쪽). 짧고 독립적인 콘텐츠(히어로 헤드라인, 단일 CTA 블록, 빈 상태)에만 중앙 정렬을 사용하세요. 양식, 테이블, 목록 및 긴 텍스트는 시작에 정렬합니다.
  • 테이블과 통계 열의 숫자는 끝에 정렬하세요.
  • 박스가 아닌 텍스트에 정렬하세요. 레이블 옆의 아이콘은 레이블의 캡 높이 또는 중앙에 정렬해야 하며, 선 상자의 상단이 아닙니다. Flex 행에서 단일 행은 items-center; 여러 줄 텍스트의 경우 아이콘에 작은 상단 마진을 추가하여 items-start를 사용하세요.
  • 시각적 조정: 재생 아이콘, 화살표 및 둥근 모양은 수학적으로 중앙에 있을 때 중앙에서 벗어나 보입니다. 확인한 후 1~2px 조정하세요.

5. 컨테이너 및 너비 (Containers and Widths)

컨테이너최대 너비용도
Prose65ch (약 640~720px)기사, 문서, 긴 단락
Narrow560~640px양식, 로그인, 집중된 작업, 중앙 히어로 문구
Content1120~1280px대부분의 마케팅 섹션 및 앱 페이지
Wide1440~1600px대시보드, 갤러리, 편집기
Full bleed100%배경, 이미지, 가장자리에 닿아야 하는 제품 샷
  • 페이지 거터: 휴대폰 16px, 태블릿 24px, 데스크톱 32~48px. 일관성 유지: 사이트 전체에 중단점당 하나의 거터 값.
  • 배경과 콘텐츠 너비를 분리하세요. 섹션의 배경은 전체 폭으로 실행될 수 있지만 콘텐츠는 콘텐츠 컨테이너 내에 유지됩니다.
  • 와이드 화면에서 텍스트를 전체 너비로 실행하지 마세요. 이미지와 그리드는 커질 수 있지만 단락은 그럴 수 없습니다.

6. 그리드 (Grids)

  • 마케팅 레이아웃에는 12열이 반, 1/3, 1/4 및 비대칭 분할(7과 5, 8과 4)을 제공합니다. 비대칭 분할은 6과 6보다 더 디자인된 느낌을 줍니다.
  • 카드의 자동 채움 그리드로 열 수가 공간을 따르게 합니다:
.cards { display: grid; gap: 24px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); }

min(100%, 280px)는 280px보다 좁은 화면에서 오버플로를 방지합니다. auto-fill은 카드가 한두 개만 있을 때 카드 너비를 일정하게 유지합니다. auto-fit은 적은 수의 카드를 늘려 행을 채웁니다. 의도에 따라 선택하세요.

  • 유연한 트랙이 축소되도록 하세요. 그리드와 Flex 자식은 기본적으로 콘텐츠 아래로 축소되지 않으므로 긴 텍스트나 넓은 테이블이 대시보드를 오버플로할 수 있습니다. 유연한 트랙에는 minmax(0, 1fr)을 사용하고 텍스트를 포함하는 Flex 자식에는 min-width: 0(Tailwind min-w-0)을 사용하세요:
.app-shell { display: grid; grid-template-columns: 16rem minmax(0, 1fr); }
.row > .text { min-width: 0; }
  • 동일한 콘텐츠에만 동일한 높이를 사용하세요. 한 행의 카드는 기본적으로 그리드에서 가장 큰 카드까지 늘어납니다. 계획 세트에는 괜찮지만, 하나의 카드가 분명히 주요 카드일 때는 잘못된 방식입니다.
  • 벤토 그리드: 중요도에 따라 타일 크기를 다르게 하고, 하나의 갭 값을 유지하며, 모든 타일에 실제 콘텐츠를 제공하세요. 빈 장식 타일은 템플릿처럼 보입니다.
  • 행의 카드들이 제목, 본문 및 버튼을 서로 정렬해야 할 때 subgrid를 사용하세요(grid-template-rows: subgrid).

7. 반응형 구조 (Responsive Structure)

모바일 우선으로 설계한 다음 공간이 커짐에 따라 구조를 추가하세요.

  • 중단점은 콘텐츠를 따르며 디바이스를 따르지 않습니다. 레이아웃이 잘못 보이기 시작하는 곳에 하나를 추가하세요. Tailwind의 sm 640, md 768, lg 1024, xl 1280은 훌륭한 기본값입니다.
  • 축소만 하지 말고 구조를 변경하세요. 모바일에서 3열 특징 그리드는 1열이 되고, 텍스트와 이미지가 나란히 배치된 것은 이미지가 두 번째(또는 메시지를 전달한다면 첫 번째)에 오도록 쌓이며, 테이블은 카드 목록이 되거나 자체 컨테이너 내에서 가로로 스크롤되며, 사이드바는 드로어가 됩니다.
  • 다양한 너비로 나타나는 컴포넌트에는 컨테이너 쿼리를 사용하세요(사이드바의 카드와 메인 열의 카드):
.card-wrap { container-type: inline-size; }
@container (min-width: 480px) { .card { grid-template-columns: 160px 1fr; } }

Tailwind v4: 부모에 @container, 자식에 @md:grid-cols-2.

  • 화면에 따라 간격을 조정하세요. 섹션 패딩: 모바일 48px, 태블릿 64px, 데스크톱 96px. 갭은 16에서 24, 32로 단계적으로 증가할 수 있습니다.
  • 뷰포트 높이: 전체 높이 레이아웃에는 h-screen(100vh) 대신 min-h-dvh(또는 100dvh)를 사용하세요. 100vh는 툴바가 있는 모바일 브라우저의 가시 영역보다 높으므로 콘텐츠가 그 아래 숨겨집니다.
  • 노치가 있는 휴대폰의 안전 영역: 고정된 하단 막대에 padding-bottom: env(safe-area-inset-bottom)을 사용하고 뷰포트 메타 태그에 viewport-fit=cover를 포함하세요.
  • 오른쪽에서 왼쪽 언어: left와 right 대신 논리적 속성(margin-inline-start, padding-inline, inset-inline-end; Tailwind ms-*, pe-*, start-*)을 사용하고 dir="rtl"로 테스트하세요. 방향성 아이콘(뒤로 가기 화살표, 쉐브론)은 미러링하지만 로고나 모든 아이콘은 미러링하지 마세요.
  • 가로 페이지 스크롤은 절대 없습니다. 320px에서 확인하세요. 일반적인 원인은 고정 너비, 긴 단어나 URL, w-screen 요소(스크롤바 너비 포함) 또는 음수 마진입니다.

8. 테이블 (Tables)

  • 레이블 역할의 헤더 행, 테이블이 스크롤될 때 sticky(position: sticky; top: 0), 착색된 표면 또는 더 강한 하단 테두리 사용.
  • 밀도별 행 높이: 컴팩트 36px, 기본 44px, 여유 52px. 사용자가 다를 때 전환을 제공하세요.
  • 행은 가는 선 구분선 또는 줄무늬 색상 중 하나로만 구분하세요. 둘 다 사용하지 마세요.
  • 숫자는 tabular-nums로 끝 정렬; 텍스트는 시작 정렬; 상태 및 작업은 마지막 열에.
  • 모바일의 넓은 테이블: 첫 번째 열을 sticky로 유지하면서 자체 컨테이너 내에서 가로 스크롤(overflow-x: auto)하거나 행당 카드로 전환하세요. 테이블이 페이지를 옆으로 밀지 않도록 하세요.
  • 빈 상태, 로딩 상태 및 오류 상태는 테이블 프레임 내에 있으며, 사용자가 무엇이 나타날지 알 수 있도록 헤더를 유지하세요.

9. 밀도 (Density)

화면이 사용되는 빈도에 맞게 밀도를 조정하세요:

  • 마케팅 및 온보딩: 여유. 화면당 적은 항목, 넉넉한 공간, 큰 글꼴.
  • 일일 사용 앱 화면: 컴팩트. 3644px 행, 812px 갭, 14px 텍스트. 매일 화면을 사용하는 사람들은 한 번에 더 많은 것을 보고 싶어합니다.
  • 테이블 및 데이터 도구: 밀집, 사용자가 다를 때 밀도 전환 제공.
  • 하나의 패널 내에서 밀도를 혼합하지 마세요.

10. 터치 타겟 및 히트 영역 (Touch Targets and Hit Areas)

  • 터치 화면에서 탭 가능한 모든 것에 대해 44x44px 타겟, 보이는 아이콘이 16px이더라도. (WCAG 2.2 AA는 최소 24x24px 필요; 44px가 편안한 크기입니다.) 패딩으로 히트 영역을 키우거나, 레이아웃이 변경되지 않도록 컨트롤 중앙에 배치된 보이지 않는 의사 요소를 사용하세요:
.icon-btn { position: relative; }
.icon-btn::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: max(100%, 44px); height: max(100%, 44px);
  transform: translate(-50%, -50%);
}
  • 별도의 탭 타겟 사이에 최소 8px 이상 두어 엄지손가락이 두 개를 동시에 누르지 않도록 하세요.

11. 계층 (Layering)

작은 z-index 스케일을 유지하고 다음 값만 사용하세요:

:root { --z-dropdown: 10; --z-sticky: 20; --z-overlay: 30; --z-modal: 40; --z-toast: 50; --z-tooltip: 60; }

showModal()로 열린 네이티브 <dialog>와 popover 속성이 있는 요소는 브라우저의 최상위 레이어에 렌더링되므로 모든 z-index 위에 있으며 z-index가 필요하지 않습니다. z-index: 9999는 쌓임 맥락을 이해하지 못했다는 의미입니다. 숫자를 높이는 대신 쌓임 맥락(종종 부모의 잘못된 transform, filter 또는 isolation)을 수정하세요.

12. 스티키 및 고정 요소 (Sticky and Fixed Elements)

  • 스티키 헤더: 짧게 유지(56~64px)하고, 페이지가 스크롤될 때만 배경(단색 또는 블러)을 제공하여 페이지 상단이 깔끔하게 유지되도록 하세요.
  • 앵커가 있는 제목에 헤더 높이와 동일한 scroll-margin-top을 추가하여 페이지 내 링크가 헤더 아래에 떨어지지 않도록 하세요.
  • 모바일의 고정 하단 막대는 위의 안전 영역 패딩이 필요하며 페이지의 마지막 콘텐츠를 가리지 않아야 합니다. 막대 높이만큼 페이지 하단에 패딩을 추가하세요.

13. 완료 전 확인 (Check Before You Finish)

  • 모든 간격 값이 4px 스케일에 있습니다.
  • 그룹 내부 공간이 그룹 사이 공간보다 확실히 작습니다.
  • 제목 위에 아래보다 더 많은 공간이 있습니다.
  • 섹션당 하나의 시작 가장자리; 테이블에서 숫자는 끝 정렬.
  • 유연한 트랙은 minmax(0, 1fr)를 사용합니다. 텍스트 자식은 축소될 수 있습니다.
  • 단락은 와이드 화면에서도 약 65ch로 제한됩니다.
  • 레이아웃이 모바일에서 축소 대신 구조를 변경합니다.
  • 320px에서 가로 스크롤 없음; 전체 높이 섹션은 dvh를 사용합니다.
  • 터치 타겟이 최소 44px(절대 24px 미만 안 됨).
  • z-index 값이 스케일에서 비롯됩니다.
  • 눈을 가늘게 뜨고 보기 테스트: 가장 중요한 것과 그룹이 세부 사항이 흐려져도 명확합니다.

이 문서는 원본 SKILL.md에서 번역되었습니다.

Individual skills in this repo

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

관련 스킬