본문으로 건너뛰기

모바일 페이지 대응 전략

무료2015-08-20#Front-End#Solution#移动页面适配#机型适配#适配解决方案#em#rem#scale整页缩放#zoom缩放

모바일 페이지는 다양한 버전의 Android 및 iOS 브라우저와 호환되어야 하며, 다양한 해상도의 화면에 대응하는 것은 까다로운 문제입니다. 이 글에서는 자주 사용되는 두 가지 페이지 대응 솔루션과 그 장단점을 자세히 소개합니다.

문제 재정의

이 글에서 논의하는 대응(적응)은 전통적인 @media 미디어 쿼리를 의미하는 것이 아닙니다.

  • media query는 모바일 기기와 PC, 패드를 구분하는 데 사용되며, 이러한 기기들에 맞춰 3세트의 스타일을 작성해야 합니다. 일반적으로 백분율 너비와 작은 화면에서의 일부 내용 숨김 처리를 포함합니다.

  • 이 글에서 논의하는 대응은 페이지 레이아웃이나 내용을 변경하지 않고, 다양한 모바일 기기에서 시각적 효과가 거의 동일하게 나타나도록 하는 것입니다. 예를 들어:

우리는 iPhone 6와 iPhone 4에서 효과가 거의 동일하기를 원합니다. 순수 CSS만으로는 불가능하며, 다양한 모바일 기기에 적응하기 위해 JS와 레이아웃의 협력이 필요합니다. 모바일 기기 화면 대응에는 여러 난관이 있습니다.

  • 화면 가로세로 비율의 차이

키가 작고 넓은 휴대폰도 있고, 폭이 좁고 긴 휴대폰도 있습니다.

  • DPI의 차이

화면은 매우 작지만 해상도는 매우 높은 화면이 있습니다.

  • 고해상도 화면(Retina)에서의 이미지 왜곡

하나의 픽셀을 여러 조각으로 나누어 표시하는 화면이 있습니다.

media query는 이러한 문제를 해결하는 데 도움이 되지 않습니다. 이 글에서 논의하는 방안들도 겨우 해결할 수 있을 뿐입니다(번거롭거나 부작용이 존재함).

1. scale/zoom을 이용한 전체 페이지 확대/축소

1. scale과 zoom의 차이

  • zoom 확대/축소는 기본적으로 왼쪽 상단을 중심으로 하며 변경할 수 없습니다. 주변 요소를 덮어쓰는 문제가 발생하지 않습니다.

  • scale 확대/축소는 기본적으로 중앙을 중심으로 하며 변경 가능합니다. 주변 요소를 덮어쓰는 문제가 존재합니다(확장된 부분이 공간을 차지하지 않음).

  • zoom이 자식 요소를 확대/축소하면 정렬이 깨집니다.

  • scale이 자식 요소를 확대/축소하면 정렬이 깨지며, inline 요소에는 효과가 없습니다.

  • zoom이 부모 요소를 확대/축소해도 상대적 위치에 영향을 주지 않습니다.

  • scale이 부모 요소를 확대/축소할 때 왼쪽 상단을 중심으로 설정하면 상대적 위치에 영향을 주지 않습니다.

  • zoom은 Firefox를 제외한 모든 브라우저와 호환됩니다 (IE5.5+).

  • scale은 IE11+ 및 Firefox와 호환됩니다.

DEMO: scale과 zoom의 차이

2. scale의 부작용

  1. input 커서가 굵어짐

scale로 전체 페이지를 확대/축소하면 iOS에서 페이지 내의 inputtextarea 등 입력창의 커서가 굵어지는 현상이 발생하여 매우 보기 흉합니다. 안드로이드는 괜찮은 것 같습니다.

해결 방법: scale 대응을 포기하고 다른 방안을 사용합니다.

  1. z-index

scale이 z-index 효과에 영향을 줄 수 있습니다. 확실하지는 않지만 z-index, fixed, 소프트 키보드 등의 요소가 서로 영향을 주어 해결하기 매우 어려운 문제를 일으킬 수 있습니다.

해결 방법: float은 z를 무효화하고, position의 기본값도 z를 무효화합니다. 자세한 정보는 div 레이어 z-index 속성 무효 원인 분석 및 해결 방법을 확인하세요.

  1. 가로 스크롤바

넓은 화면에서 사라지지 않는 가로 스크롤바가 나타날 수 있으며, overflow 설정을 어떻게 해도 해결되지 않을 수 있습니다.

해결 방법: body에 scale을 설정하지 말고 wrapper에 설정하세요. 이미 그렇게 하고 있다면 반대로 해보세요(body에 scale 설정). 그래도 안 되면 z-index, fixed, input 등 다른 요소를 분리하여 고려해 보세요.

  1. fixed 레이아웃 무효화

scale 이후에는 fixed 레이아웃이 제대로 작동하지 않아 fixed 부분이 페이지와 함께 스크롤될 수 있으며, 소프트 키보드가 올라올 때도 이 문제가 발생할 수 있습니다.

해결 방법: absolute + JS 보조 위치 계산으로 변경하세요. 복잡한 fixed 레이아웃(예: fixed 레이어 위에 input이 있는 경우)이라면 scale 대응은 포기하는 것이 좋습니다. 버그가 끝도 없이 나올 것입니다.

  1. 소프트 키보드의 레이아웃 파괴

소프트 키보드가 나타나면 fixed 레이아웃이 무효화되며 현재로서는 해결 방법이 없습니다.

3. 결론

"단순한" 페이지에는 scale 확대/축소 대응을 안심하고 사용할 수 있습니다. "단순함"의 정의는 다음과 같습니다.

  1. input, textarea 등 입력창이 없어 소프트 키보드가 올라올 일이 없음

  2. 복잡한 z-index 계층 구조가 없음

  3. fixed 부분이 없음

페이지가 위 조건 중 하나라도 만족하지 않는다면 scale 대응을 사용하지 않는 것이 좋습니다. 버그 폭탄을 맞게 될 것입니다.

P.S. zoom 대응은 필자가 많이 사용하지 않았습니다. scale과 zoom 중 무엇을 사용할지는 다음 원칙을 따릅니다.

  1. 대전제: 모바일 페이지에서 IE를 지원할 필요가 없다면 scale을 사용할 수 있습니다. 그렇지 않다면 zoom을 사용하세요. Firefox 호환성이 중요하다면 hack을 추가해야 합니다.

  2. 이미지 확대/축소는 zoom과 scale 모두 가능하지만, 페이지 전체 확대/축소는 scale을 권장합니다.

4. 사례

고덕지도_친환경 여행 활동: scale 확대/축소 전체 페이지 대응

5. 프레임워크

PeunZhang의 pageResponse, 1.4K 초경량

2. fontsize + em/rem 상대 단위

1. em을 이용한 확대/축소

html(또는 body)에 font-size: 62.5%;를 설정해야 합니다(소위 62.5% hack, 1em=10px로 계산하기 편리하게 하기 위함). 그런 다음 모든 길이 단위를 em으로 통일하고, JS를 이용해 html(또는 body)의 font-size를 동적으로 변경해야 합니다.

DEMO: em 확대/축소 대응 (주의: 현재 요소의 fz 값이 top/left/right/bottom 위치 계산에 영향을 주므로, fz를 조절하는 레이어를 하나 더 감싸고 바깥쪽 레이어에서 위치를 잡아야 합니다)

em 사용은 권장하지 않습���다. 이유는 다음과 같습니다.

  1. 계산이 어려움

현재 요소의 fz 값은 모든 조상 요소로부터 영향을 받습니다.

  1. 중복 태그

위의 주의 사항 부분을 참고하세요.

  1. 유연성 부족 및 유지보수 어려움

현재 요소의 fz 값은 모든 자식 요소에도 영향을 줍니다.

2. rem을 이용한 확대/축소

가장 중요한 것은 호환성입니다: [IE8 이하]는 rem을 지원하지 않습니다.

반드시 htmlfont-size: 10px;를 설정해야 합니다(10px 역시 계산 편의를 위함). 그런 다음 모든 길이 단위를 rem으로 통일하고, JS로 html의 fz 값을 설정하면 됩니다.

DEMO: rem 확대/축소 대응

가능하면 rem 사용을 권장합니다. rem은 상속 값 문제가 없으며 조상의 fz 값을 신경 쓸 필요가 없어 매우 유연합니다. 유일한 단점은 호환성 문제([IE8 이하] 미지원)입니다.

3. 주의 사항

em/rem을 사용할 때 Chrome의 일부 버전에서 font-size가 12보다 작은 것을 지원하지 않을 수 있음에 주의해야 합니다(fz를 10으로 설정해도 실제 렌더링은 12로 됨). 이 경우 62.5% hack이 무효화되어 1em/1rem이 10px가 아닌 12px이 됩니다.

최신 버전의 Chrome에서는 -webkit-text-size-adjust: none;을 설정해도 효과가 없으며, 모바일 환경에서의 효과는 미지수입니다.

4. 사례

타오바오 모바일 버전: 단일 화면 + JS 시뮬레이션 슬라이드 (매우 강력합니다~)

5. em/rem 사용의 장점

(본문 내용과는 큰 상관이 없는 여담입니다)

어떤 페이지들은 텍스트에만 em/rem을 폰트 단위로 사용하고 나머지는 px를 사용하는데, 왜 그럴까요?

px는 절대 단위이지만 사용자는 브라우저의 기본 폰트 크기를 설정할 수 있습니다. 이때 텍스트 단위가 px라면 사용자의 설정에 따라 텍스트가 확대/축소되지 않지만, em/rem은 확대/축소되기 때문입니다.

3. img+div 너비 백분율, 높이 auto

이것은 고전적인 방법으로 특별할 것은 없습니다. 단점은 텍스트가 함께 확대/축소되지 않는다는 것인데, 두 가지 해결 방법이 있습니다.

  • 텍스트를 모두 이미지에 포함시킴

단점은 페이지 로딩이 느려집니다.

  • JS로 fz 값을 수동 계산하여 폰트 크기 조절 (em/rem과 함께 사용)

화면 너비, DPI 등의 값으로 특정 비율 인자를 계산하여 기본 fz에 곱해 폰트 크기를 조절합니다. 단점은 번거롭고 적절한 비율 인자를 계산하기 어렵습니다 (일부 기종만 대응 가능).

DEMO: 생략합니다. 사례를 참고하세요.

사례

4. 모바일 페이지 대응 전략 요약

  1. 우선 scale/zoom 방안을 고려합니다. 전제 조건은 *페이지가 단순할 것(단순함의 정의는 앞서 설명함)*입니다.

  2. 안 된다면 rem/em 방안을 고려하되, 호환성(rem[IE8 이하])에 주의합니다.

  3. 정 안 되면 이미지 방안을 사용합니다. 요구사항이 높지 않다면 폰트는 무시해도 되지만, 그렇지 않다면 골치 아파질 것입니다.

참고 자료

댓글

아직 댓글이 없습니다

댓글 작성