문제 재정의
이 글에서 논의하는 대응(적응)은 전통적인 @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의 부작용
- input 커서가 굵어짐
scale로 전체 페이지를 확대/축소하면 iOS에서 페이지 내의 input 및 textarea 등 입력창의 커서가 굵어지는 현상이 발생하여 매우 보기 흉합니다. 안드로이드는 괜찮은 것 같습니다.
해결 방법: scale 대응을 포기하고 다른 방안을 사용합니다.
- z-index
scale이 z-index 효과에 영향을 줄 수 있습니다. 확실하지는 않지만 z-index, fixed, 소프트 키보드 등의 요소가 서로 영향을 주어 해결하기 매우 어려운 문제를 일으킬 수 있습니다.
해결 방법: float은 z를 무효화하고, position의 기본값도 z를 무효화합니다. 자세한 정보는 div 레이어 z-index 속성 무효 원인 분석 및 해결 방법을 확인하세요.
- 가로 스크롤바
넓은 화면에서 사라지지 않는 가로 스크롤바가 나타날 수 있으며, overflow 설정을 어떻게 해도 해결되지 않을 수 있습니다.
해결 방법: body에 scale을 설정하지 말고 wrapper에 설정하세요. 이미 그렇게 하고 있다면 반대로 해보세요(body에 scale 설정). 그래도 안 되면 z-index, fixed, input 등 다른 요소를 분리하여 고려해 보세요.
- fixed 레이아웃 무효화
scale 이후에는 fixed 레이아웃이 제대로 작동하지 않아 fixed 부분이 페이지와 함께 스크롤될 수 있으며, 소프트 키보드가 올라올 때도 이 문제가 발생할 수 있습니다.
해결 방법: absolute + JS 보조 위치 계산으로 변경하세요. 복잡한 fixed 레이아웃(예: fixed 레이어 위에 input이 있는 경우)이라면 scale 대응은 포기하는 것이 좋습니다. 버그가 끝도 없이 나올 것입니다.
- 소프트 키보드의 레이아웃 파괴
소프트 키보드가 나타나면 fixed 레이아웃이 무효화되며 현재로서는 해결 방법이 없습니다.
3. 결론
"단순한" 페이지에는 scale 확대/축소 대응을 안심하고 사용할 수 있습니다. "단순함"의 정의는 다음과 같습니다.
-
input,textarea등 입력창이 없어 소프트 키보드가 올라올 일이 없음 -
복잡한
z-index계층 구조가 없음 -
fixed부분이 없음
페이지가 위 조건 중 하나라도 만족하지 않는다면 scale 대응을 사용하지 않는 것이 좋습니다. 버그 폭탄을 맞게 될 것입니다.
P.S. zoom 대응은 필자가 많이 사용하지 않았습니다. scale과 zoom 중 무엇을 사용할지는 다음 원칙을 따릅니다.
-
대전제: 모바일 페이지에서 IE를 지원할 필요가 없다면 scale을 사용할 수 있습니다. 그렇지 않다면 zoom을 사용하세요. Firefox 호환성이 중요하다면 hack을 추가해야 합니다.
-
이미지 확대/축소는 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 사용은 권장하지 않습���다. 이유는 다음과 같습니다.
- 계산이 어려움
현재 요소의 fz 값은 모든 조상 요소로부터 영향을 받습니다.
- 중복 태그
위의 주의 사항 부분을 참고하세요.
- 유연성 부족 및 유지보수 어려움
현재 요소의 fz 값은 모든 자식 요소에도 영향을 줍니다.
2. rem을 이용한 확대/축소
가장 중요한 것은 호환성입니다: [IE8 이하]는 rem을 지원하지 않습니다.
반드시 html에 font-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. 모바일 페이지 대응 전략 요약
-
우선 scale/zoom 방안을 고려합니다. 전제 조건은 *페이지가 단순할 것(단순함의 정의는 앞서 설명함)*입니다.
-
안 된다면 rem/em 방안을 고려하되, 호환성(rem[IE8 이하])에 주의합니다.
-
정 안 되면 이미지 방안을 사용합니다. 요구사항이 높지 않다면 폰트는 무시해도 되지만, 그렇지 않다면 골치 아파질 것입니다.
아직 댓글이 없습니다