Mobile Adapt (모바일 적응)
목표
핵심 기능을 제거하지 않고 기존 인터페이스를 휴대폰에서 잘 작동하도록 적응시킵니다. 사용자가 다른 대상을 지정하지 않는 한 iPhone 클래스 모바일 웹을 우선 순위로 둡니다.
기본 대상
사용자가 장치나 브라우저를 지정하지 않으면 다음을 먼저 최적화합니다.
- 세로 및 가로 모드의 iPhone Pro Max 클래스
- iOS Safari
- 약
375-440 CSS px너비의 컴팩트 터치 스크린 - 키보드 열림 사용, 큰 텍스트, 안전 영역, reduced motion
조사 시점
이 스킬은 현재 플랫폼 동작에 의존합니다.
- 사용자가 최신/현재 가이드라인, iPhone 특화 동작, Safari/WebKit 특이사항, safe-area 동작, PWA/홈 화면 동작 또는 직접 인용을 요청할 때는 공식 출처를 검색합니다.
- Apple Developer, WebKit, W3C/WCAG, MDN, Android Developers, web.dev를 선호합니다.
- 최근 플랫폼 변경 사항을 인용할 때는 절대 날짜를 사용합니다.
현재 신뢰도 높은 규칙과 출처는 references/mobile-ui-2026.md를 읽으십시오.
핵심 규칙
-
컴팩트 폰은 단일 창으로 유지하십시오. 가로 모드 폰이 일반적인 중단점을 넘었다고 해서 데스크탑 IA로 전환하지 마십시오. 옆으로 회전된 폰은 여전히 양손으로 팔 길이만큼 떨어져서 쥐고 있습니다. 사용자의 멘탈 모델은 "태블릿"이 아닌 "폰"입니다. 다중 창 레이아웃으로 분할하면 사용자가 편안하게 사용할 수 있을 만큼 큰 것이 없는 혼란스러운 경험을 만듭니다.
-
진정한 최상위 섹션에 대해서만 하단 우선 모바일 내비게이션을 사용하십시오.
3-5개의 주요 목적지로 제한하고, 초과분은More, 시트 또는 보조 흐름으로 이동하십시오. 화면 하단은 엄지손가락의 자연스러운 휴식 영역입니다. 기본 내비게이션을 거기에 배치하면 가장 일반적인 작업에 가장 적은 노력이 필요합니다. 5개 이상의 항목은 탭 대상 크기를 사용 가능한 크기 이하로 줄이고 스캔을 압도합니다. -
모든 상호작용 대상은 양방향으로 최소
44x44 CSS px크기여야 합니다. 여기에는 간과하기 쉬운 보조 요소도 포함됩니다: 인라인 작업 버튼(편집, 삭제, 보기), 확장/축소 토글, 필터 칩, 툴바의 아이콘 버튼, 시트의 닫기 버튼, 체크박스/라디오 행(전체 탭 대상으로<label>사용, 입력만 아님). 정전식 터치스크린은 손가락 접촉 패치의 중심을 약 44pt에서 등록합니다. 더 작은 대상은 특히 움직임이 있을 때 잘못 누르는 불만을 유발합니다. 부족한 일반적인 Tailwind 클래스:h-8(32px),h-9(36px), 아이콘에p-1(~24px),p-1.5(~28px),p-2(~32px). 모든 탭 가능한 요소의 기준선으로h-11(44px),min-h-[44px]또는 동등한 값을 사용하십시오. 이는 Apple HIG에 부합하며 WCAG 2.2의 24px 최소값을 초과합니다. -
hover, 작은 아이콘 탭 또는 숨겨진 행 작업에 의존하지 마십시오. 터치에는 hover 상태가 없습니다. hover를 통해 발견해야 하는 모든 것은 보이지 않습니다. 보이는 컨트롤, 시각적 힌트가 있는 스와이프 작업 또는 컨텍스트 시트/메뉴를 사용하십시오.
-
가로 페이지 스크롤을 피하십시오. 한 손으로 폰을 사용하는 것은 세로 엄지 스크롤입니다. 가로 스크롤은 사용자의 공간 모델을 깨고 보이는 어포던스 없이 콘텐츠를 화면 밖으로 숨깁니다. 전체 페이지 대신 테이블과 차트를 리플로우, 스택, 페이지네이트 또는 로컬 스크롤하십시오.
-
viewport-fit=cover,env(safe-area-inset-*)및min-height: 100dvh를 사용하십시오. 최신 iPhone은 둥근 모서리, Dynamic Island 및 홈 인디케이터를 가지고 있어 직사각형 뷰포트를 잠식합니다. 명시적인 safe-area 처리가 없으면 콘텐츠가 하드웨어 크롬 뒤에 잘립니다.dvh는 기존vh가 처리하지 못하는 축소되는 Safari 툴바를 고려합니다. -
주요 작업을 브라우저 바, 홈 인디케이터, 둥근 모서리 및 온스크린 키보드에서 멀리 유지하십시오. 키보드 뒤나 홈 인디케이터와 겹치는 "제출" 버튼은 기능적으로 손상되었습니다. 사용자가 볼 수 없거나 시스템 제스처를 트리거하지 않고 탭할 수 없기 때문입니다.
-
폼이 많거나 키보드가 많이 사용되는 흐름에는 하나의 기본 스크롤 컨테이너를 선호하십시오. iOS Safari에서 중첩된 스크롤 영역은 스크롤 트래핑을 만듭니다. 사용자의 엄지손가락이 페이지를 스크롤하려 할 때 내부 컨테이너를 스크롤하거나 그 반대의 경우가 발생합니다. WebKit에는 지속적인 버그가 있습니다(참조 파일 참조). 다른 대안이 없을 때만 중첩 스크롤을 사용하십시오.
-
의미론적 모바일 입력을 사용하십시오. 필드 위의 레이블(옆이 아님 — 가로 공간이 없음), 올바른
type,inputmode,autocomplete및enterkeyhint을 사용하십시오. 이러한 속성은 나타나는 키보드를 제어합니다.inputmode="decimal"은 통화용 숫자 패드를 표시하고,enterkeyhint="next"는 사용자가 키보드를 해제하지 않고 폼을 탭으로 이동할 수 있게 합니다. -
큰 텍스트를 실제 레이아웃 입력으로 취급하십시오. iOS 사용자는 시스템 전체의 더 큰 텍스트를 설정할 수 있으며, 많은 사용자가 그렇게 합니다. 줄 바꿈 및 리플로우 — 핵심 의미를 잘림 뒤에 숨기지 마십시오. 잘린 레이블로 인해 사용자가 "저축 계좌"인지 "급여 계좌"인지 추측해야 한다면 레이아웃이 실패한 것입니다.
-
폰에서 차트는 이야기를 뒷받침할 뿐, 이야기 자체가 아닙니다. 폰 화면은 약 5-6개의 읽을 수 있는 막대 또는 하나의 도넛을 렌더링할 수 있습니다. 차트가 자명하기에는 데이터 밀도가 충분하지 않습니다. 핵심 숫자와 텍스트 요약으로 시작하고, 차트는 시각적 보강으로 사용하십시오.
-
사용자가 더 넓은 재설계를 요청하지 않는 한 제품의 기존 브랜드 및 디자인 시스템을 유지하십시오. 모바일 적응은 레이아웃과 상호작용에 관한 것이지, 스킨을 다시 입히는 것이 아닙니다.
예시
내비게이션 셸, 데이터 테이블 또는 제출 버튼이 있는 폼을 변경하기 전에 references/mobile-examples.md를 읽으십시오. 사이드바가 하단 탭 바가 되고, 테이블이 폰에서 카드 목록이 되고, 제출 버튼이 키보드 위에 유지되는 폼에 대한 before/after 코드가 있습니다.
워크플로우
- 대상 컨텍스트를 고정합니다.
- 장치, 브라우저, 방향, 사용 컨텍스트
- 지정되지 않은 경우 기본값은 iPhone Pro Max + iOS Safari
- 셸을 먼저 감사합니다.
- 내비게이션 모드
- 안전 영역
- 고정/상단 고정 바
- 가로 모드 동작
- 키보드 동작
- 각 화면 또는 컴포넌트를 감사합니다.
- 목록 및 행
- 폼
- 테이블
- 차트
- 빈/오류/로딩 상태
- 하드 컷오버를 선택합니다.
- 단일 열이 되는 것
- 카드가 되는 것
- 시트/서랍으로 이동하는 것
More아래에서 보조가 되는 것
- 모바일 우선 적응을 구현합니다.
- 컴포넌트 내부에는 컨테이너 쿼리를 선호합니다.
- 셸/레이아웃 모드 변경에는 뷰포트 쿼리를 선호합니다.
- 명시적으로 요구되지 않는 한 기존의 반 데스크탑/반 모바일 동작을 유지하지 마십시오.
- 컴팩트 세로 및 컴팩트 가로에서 확인합니다.
- Safari/WebKit 우선
- 그 다음 Chromium
- 가장 위험도가 높은 문제를 먼저 보고한 다음, 구체적인 변경 사항과 남은 격차를 보고합니다.
화면 체크리스트
셸 및 내비게이션
- 가로 모드 폰을 폰 셸에 유지합니다.
- 여전히 폰인 장치에 대해 하드
md => 데스크탑 사이드바전환을 피합니다. - 하단 UI에
env(safe-area-inset-bottom)으로 패딩을 추가합니다. - 고정 작업이 하단 내비게이션 위에 오도록 합니다.
- 모바일 레이블을 짧게 유지합니다.
목록 및 행
- 제목, 메타데이터 및 금액이 필요할 때 두 행으로 줄 바꿈되도록 합니다.
- 가격, 잔액 및 합계를 위해 안정적인 공간을 확보합니다.
- squeezed 인라인 메타데이터보다는 stacked 메타데이터를 선호합니다.
- hover가 아닌, 보이는 컨트롤 또는 시트/메뉴로 작업을 노출합니다.
- 행 작업 버튼(편집, 삭제, 보기, 확장)의 크기를 최소
44x44 CSS px로 조정합니다. 기본 내비게이션 및 툴바 버튼뿐만 아니라 모든 행 작업 버튼에 해당합니다.
폼
- 컴팩트 폰에서는 한 열을 사용합니다.
- 제출 버튼이 키보드 위에 보이도록 유지합니다.
- 명확한 전체 너비 기본 CTA를 사용합니다.
- 긴 흐름을 단계 또는 점진적 공개로 나눕니다.
- 서식 지정 또는 정밀도가 중요한 경우 통화에
type="number"를 피합니다.
테이블 및 가져오기/검토 흐름
- 밀도가 높은 편집 가능한 테이블을 폰에서 카드/목록으로 변환합니다.
- 실제 테이블이 유지되어야 하는 경우 가로 스크롤을 테이블로만 격리합니다.
- 고정 헤더와 툴바가 포커스된 입력을 가리지 않도록 합니다.
차트 및 통계
- 핵심 숫자와 짧은 설명으로 시작합니다.
- 컴팩트 범례와 텍스트 폴백을 추가합니다.
- 읽을 수 없는 밀집 막대보다는 가로 스크롤 또는 페이지 비교를 선호합니다.
- 컴팩트 화면에서 작은 파이/도넛을 피합니다.
검증
각 검사에 대해 특정 통과 조건을 확인하고 제안된 도구를 사용하십시오. 실제 장치 테스트가 최고 표준입니다. 시뮬레이터는 반복 작업에 유용하지만 키보드 타이밍, 스크롤 관성 또는 터치 정밀도를 완전히 재현할 수 없습니다.
-
세로 및 가로 모드 — 폰이 두 방향 모두에서 모바일 셸을 유지합니다. 레이아웃 손상, 콘텐츠 오버플로우, 데스크탑 사이드바 또는 다중 창 보기로의 갑작스러운 전환이 없어야 합니다. 375px (iPhone SE/mini 클래스), 390px (iPhone Pro), 430px (iPhone Pro Max) 세로 및 해당 가로 등가물에서 테스트합니다. Chrome DevTools 장치 툴바 또는 Xcode 시뮬레이터를 사용하십시오.
-
iOS Safari 안전 영역 — 콘텐츠가 Dynamic Island, 둥근 모서리 또는 홈 인디케이터로 잘리지 않습니다. 하단 고정 요소에는 보이는
env(safe-area-inset-bottom)패딩(Face ID iPhone에서 약 34px)이 있습니다. 뷰포트 메타 태그에viewport-fit=cover가 설정되어 있는지 확인하십시오. 설정되지 않으면 모든env(safe-area-inset-*)값이0을 반환합니다. Xcode 시뮬레이터(장치별 정확한 삽입) 또는 Polypane 26+(실제 safe-area 삽입 프리셋이 있는 데스크탑 브라우저)에서 가장 잘 테스트됩니다. Chrome DevTools 135+는Emulation.setSafeAreaInsetsOverride를 지원하지만 수동 구성이 필요합니다. -
키보드 열림 폼 흐름 — 각 입력을 순서대로 포커스하고 다음을 확인합니다: (1) 포커스된 필드가 보이도록 스크롤됨, (2) 제출 작업이 표시되고 탭 가능함, (3) 고정 헤더가 포커스된 필드를 가리지 않음.
position: fixed; bottom: 0요소는 iOS 키보드 뒤에 숨는다는 점(레이아웃 뷰포트가 축소되지 않음)과position: sticky; bottom: 0도 키보드 표시 중에 고정되지 않는다는 점(WebKit 버그 #202120)에 유의하십시오. Playwright와 Cypress는 실제 온스크린 키보드를 트리거할 수 없습니다. 실제 장치 테스트 또는 Safari Web Inspector가 있는 Xcode 시뮬레이터가 필요합니다. -
큰 텍스트 / 디스플레이 줌 — WCAG 1.4.4 (AA)는 콘텐츠 손실 없이 텍스트를 200%까지 크기 조정할 수 있어야 합니다. WCAG 1.4.10 (AA)는 가로 스크롤 없이 400% 줌(320px 너비 뷰포트에 해당)에서 리플로우가 필요합니다. 다음을 테스트합니다: (1) 브라우저 줌을 200%로 설정하고 잘리거나 겹치지 않는지 확인, (2) 뷰포트를 1280px로 설정하고 400%로 줌하여 320px 리플로우 요구 사항 시뮬레이션, (3) iOS 설정 > 손쉬운 사용 > 디스플레이 및 텍스트 크기 > 더 큰 텍스트를 최대로 활성화. 뷰포트 메타 태그가
user-scalable=no또는maximum-scale을 2.0 미만으로 설정하지 않는지 확인합니다. -
Reduced motion — 애니메이션이
prefers-reduced-motion: reduce를 존중합니다. 전환은 여전히 상태 변경을 전달하지만 모션보다는 크로스페이드 또는 불투명도를 사용합니다. iOS Safari는 Reduce Motion이 켜져 있을 때 웹 애니메이션을 자동으로 억제하지 않습니다. 개발자가 처리해야 합니다. Chrome DevTools 렌더링 탭 > "Emulate prefers-reduced-motion", Safari Web Inspector 환경설정 재정의(2022년 후반부터 사용 가능) 또는 Playwright의page.emulateMedia({ reducedMotion: 'reduce' })를 통해 테스트합니다. -
빈/오류/로딩 상태 — 이러한 상태가 컴팩트 화면에서 제대로 렌더링됩니다. 로딩 스켈레톤이 데스크탑 레이아웃이 아닌 모바일 레이아웃과 일치합니다. 오류 메시지가 스크롤 없이 읽을 수 있습니다.
-
독립형/PWA 모드 (해당되는 경우) — 앱이
display: standalone을 지원하는 경우 상태 표시줄 영역, 홈 인디케이터 및 제스처 영역이 처리되는지 확인합니다. 축소 가능한 툴바가 없기 때문에svh와dvh는 독립형 모드에서 동일한 값으로 해석됩니다(WebKit 버그 #261185). WebKit 버그 #254868은 잘못된 높이 값을 유발할 수 있습니다. WebKit 버그 #265578은 Safari UI가 다시 보기로 애니메이션될 때 시각적 뷰포트 높이가 늦게 업데이트되도록 합니다. -
가로 문서 스크롤 없음 — 페이지 본문을 왼쪽/오른쪽으로 스와이프해도 움직임이 발생하지 않습니다. 가로 스크롤은 특정 컨테이너(테이블, 캐러셀)로 격리되어 있으며, 보이는 오버플로우 어포던스와 Safari UI 이동을 방지하기 위한
overscroll-behavior: contain(WebKit 버그 #240861)이 있어야 합니다. Playwright에서 자동화된 확인:const hasOverflow = await page.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth ); expect(hasOverflow).toBe(false);
결과물
이 스킬을 사용할 때 다음을 생성하십시오:
- 간단한 모바일 적응 계획
- 가장 위험도가 높은 문제를 먼저
- 구체적인 화면별 변경 사항
- 수행된 검증
- 남은 장치/브라우저 불확실성