1. 개요

모바일 웹앱(PWA) 생태계에서 서비스의 첫인상을 결정짓는 것은 아주 미묘한 터치 반응성이나 부드러운 화면 전환 효과 같은 보이지 않는 디테일이더군요. DoEatFit (v2.0) 모바일 테스트를 진행하던 중, 유저가 식단이나 운동 기록을 입력하기 위해 다이얼로그 모달을 여는 순간 화면 전체가 우측 하단으로 툭 튕기며 부자연스럽게 확대(Auto-zoom)되는 아주 심각한 사용성 방해 문제를 마주쳤습니다. 이 현상이 발생하면 화면 레이아웃이 뷰포트 밖으로 삐져나가게 되어, 유저는 글자를 입력할 때마다 두 손가락으로 화면을 일일이 꼬집어 축소해야만 하는 극심한 피로감을 겪게 되었습니다. 접근성을 지키면서 디자인의 일관성을 사수하기 위한 대응 방안을 간략하게 설명합니다.


2. 핵심 내용

2-1. 🚨 문제 현상 및 원인 분석

  • 현상:
    • 입력창 터치 시: input이나 textarea 요소를 클릭하는 순간 전체 화면 비율이 강제로 줌인됩니다.
    • 모달 진입 시: 사용자가 터치하기도 전에 모달 창이 뜨자마자 화면이 부르르 떨리며 확대가 실행됩니다.
  • 원인:
    1. iOS Safari의 16px 미만 강제 자동 확대: 애플의 iOS 개발진은 모바일 화면 속 작은 글자를 입력할 때 시력 보호와 사용성 향상을 돕기 위해, 입력 요소의 폰트 크기가 16px 미만으로 지정된 필드에 포커스가 갈 경우 화면을 자동 확대하도록 WebKit 브라우저 엔진을 설계해 두었습니다. 기존 DoEatFit 프론트엔드는 모바일 스크린 레이아웃 조율을 위해 Tailwind CSS의 text-sm (14px)을 쓰고 있었기에 WebKit 엔진이 강제 줌인을 일으켰습니다.
    2. Radix UI (Shadcn)의 첫 번째 요소 자동 포커싱: 모달(DialogSheet)이 마운트되는 순간, Radix UI는 접근성 표준을 준수하기 위해 내부에 있는 첫 번째 입력 컴포넌트로 포커스를 자동으로 이동시킵니다. 이때 첫 번째 컴포넌트의 폰트 크기가 16px 미만이었기에, 모달이 열리자마자 뷰포트가 흔들리며 자동 줌인되는 현상이 발생한 것입니다.

2-2. 💡 우아한 해결책 및 구현 코드

  • 해결 방안: 웹 접근성을 보장하면서도 디자인의 완성도를 지키기 위해, 모바일 화면에서는 16px을 무조건 보장하고 데스크탑 환경에서는 오리지널의 정교하고 슬림한 컴팩트 폰트(14px / 11px)를 가변적으로 주입하도록 cva 라이브러리를 활용해 설계했습니다. 또한 모달 진입 시 강제 자동 포커싱을 억제하는 방어 처리를 추가했습니다.
  • 코드 명세:
// input.tsx
const inputVariants = cva(
  "flex w-full rounded-xl border border-input/60 bg-background/50 px-4 py-2 shadow-sm transition-all focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
  {
    variants: {
      variant: {
        // 모바일(기본)은 16px(text-base)을 절대 사수, 데스크탑(md)은 14px(text-sm) 슬림화
        default: "h-11 text-base md:text-sm",
        // 컴팩트형 역시 모바일에서는 16px 보장, 데스크탑은 11px 컴팩트 렌더링
        compact: "h-9 text-base md:text-[11px] px-2",
        search: "h-9 text-base md:text-sm pl-9 pr-8",
      },
    },
    defaultVariants: {
      variant: "default",
    },
  }
)
  • 글로벌 CSS 최후 방어선 및 모달 자동 포커싱 방지:
/* globals.css */
@media (max-width: 767px) {
  input, textarea, select {
    font-size: 16px !important;
  }
}
// 모달 컨텐츠 라이프사이클의 성급한 자동 포커스 방지
<DialogPrimitive.Content 
  onOpenAutoFocus={(e) => e.preventDefault()} 
  className="..."
/>

2-3. ✅ 결과 검증 및 모던 오픈소스 라이브러리 검토

  • 최종 검증:
    • 화면 줌인 고정 확인: 어떤 입력창을 터치하더라도 100% 오리지널 화면 배율이 완벽하게 고정된 채 키보드만 가볍게 올라옴을 입증했습니다.
    • 불필요한 모달 도약 제어: 모달이 열리는 최초 시점에 뷰포트의 위치가 흔들리지 않고 정갈하게 수평을 유지함을 보장받았습니다.
    • 데스크탑 해상도 확인: 웹 브라우저 창을 늘리면 데스크탑 전용 14px, 11px 규격의 아기자기하고 정돈된 밀도감이 정교하게 복원되는 것을 검증했습니다.
  • 추천 오픈소스 라이브러리 검토:
    1. class-variance-authority (cva):
      • 평가: 테일윈드 CSS 클래스의 반응형/조건부 조합을 타입 세이프한 Variant 컴포넌트 아키텍처로 품어 안아 설계하기 위한 필수 도구로 강추합니다.
    2. Radix UI Dialog:
      • 평가: 강력한 웹 접근성 규격을 완벽하게 갖추면서도, 모달 열림 시 포커스 흐름(onOpenAutoFocus 제어 등)을 유연하게 조율할 수 있는 훌륭한 클라이언트 라이브러리입니다.