Problem Restatement
The adaptation discussed in this article does not refer to traditional @media queries.
-
media queryis used to distinguish between mobile devices, PCs, and tablets, requiring three sets of styles, usually with percentage widths and hiding some content on small screens. -
The adaptation discussed here aims to maintain roughly the same visual effect across various mobile devices without changing page layout or content, for example:
We want the effect to be roughly the same on iPhone 6 and iPhone 4. Pure CSS isn't enough; JS is needed to coordinate the layout to adapt to various mobile devices. There are many difficulties in adapting to mobile screens:
- Different screen aspect ratios
Some phones are short and wide, while others are narrow and long.
- Different DPI
Some screens are very small but have very high resolutions.
- Image distortion on high-definition (Retina) screens
Screens that split one pixel into several segments for display.
media query does not help solve these problems, and the solutions discussed in this article can only barely resolve them (they are either troublesome or have side effects).
I. Scaling the Entire Page with scale/zoom
1. Differences between scale and zoom
-
zoomscaling defaults to the top-left corner as the center and cannot be changed; it doesn't cause issues with overlapping surrounding elements. -
scalescaling defaults to the center; this can be changed, but it might overlap surrounding elements (the scaled content doesn't take up space). -
zoomscaling on child elements can break alignment. -
scalescaling on child elements can break alignment and is ineffective for inline elements. -
zoomscaling on a parent element does not affect relative positions. -
scalescaling on a parent element will not affect relative positions if it is set to center on the top-left corner. -
zoomis compatible with almost any browser except Firefox (IE 5.5+). -
scaleis compatible with IE 11+ and Firefox.
DEMO: Differences between scale and zoom
2. Side Effects of scale
- Thick input cursor
Scaling the entire page with scale causes the cursor in input fields like input and textarea to become thick on iOS, which looks terrible; Android doesn't seem to have this issue.
Solution: Give up on scale adaptation and use other solutions.
z-index
scale might affect z-index; it's uncertain because factors like z-index, fixed positioning, and the soft keyboard can interact and cause extremely difficult problems.
Solution: float will invalidate z-index, and the default value of position will also invalidate it. For more info, see Analysis and Solutions for Invalid z-index on div Layers
- Horizontal scrollbars
Unremovable horizontal scrollbars may appear on wide screens, regardless of overflow settings.
Solution: Don't apply scale to body; apply it to a wrapper. If you're already doing that, try the reverse (apply it to body). If it still doesn't work, consider isolating other factors like z-index, fixed, input, etc., which might be related.
- Fixed layout failure
After applying scale, fixed layouts fail; fixed elements scroll with the page. Soft keyboard pop-ups can also trigger this.
Solution: Use absolute + JS-assisted positioning. For complex fixed layouts (e.g., an input on a fixed layer), it's better to abandon scale adaptation, as bugs will be endless.
- Soft keyboard breaking the layout
Once the soft keyboard pops up, the fixed layout breaks; there is currently no solution.
3. Conclusion
You can safely use scale for scaling and adapting "simple" pages. "Simple" is defined as:
-
No input fields like
inputortextarea, ensuring the soft keyboard won't pop up. -
No complex
z-indexhierarchies. -
No
fixedelements.
If the page doesn't meet any of the above criteria, it's recommended not to use scale for adaptation, or you'll be bombarded by bugs.
P.S. I haven't used zoom adaptation much. Regarding scale vs zoom, here are some principles:
-
Main premise: If the mobile page doesn't need to support IE, you can use
scale; otherwise, stick tozoom. If Firefox compatibility is important, you'll need to add hacks. -
Either
zoomorscaleworks for image scaling; for full-page scaling,scaleis recommended.
4. Case Study
Amap Green Travel Event: Full-page adaptation using scale.
5. Frameworks
Baishu's pageResponse, a 1.4K ultra-lightweight library.
II. fontsize + em/rem Relative Units
1. Scaling with em
You need to set font-size: 62.5%; on html (or body) (the so-called 65.5% hack, making 1em = 10px for easier calculation). Then, unify all length units as em. Of course, you also need JS to dynamically change the font-size of html (or body).
DEMO: Adaptation using em scaling (Note: The fz value of the current element affects top/left/right/bottom positioning, so you have to wrap it in another layer to control fz, using the outer layer for positioning).
em is not recommended because:
- Hard to calculate
The current element's fz value is inherited from all ancestor elements.
- Redundant tags
See the note above.
- Inflexible and hard to maintain
The current element's fz value also affects all its child elements.
2. Scaling with rem
The most important factor is compatibility: rem is not supported in [IE8-].
You must set font-size: 10px; on html (again, 10px for easy calculation). Then unify all length units as rem, and use JS to set the fz value of html.
DEMO: Adaptation using rem scaling
It's recommended to use rem whenever possible. rem avoids inheritance issues, so you don't need to worry about ancestor fz values. It's very flexible, with the only downside being compatibility ([IE8-] is not supported).
3. Precautions
When using em/rem, note that some versions of Chrome do not support font-size smaller than 12px (even if fz is set to 10, the actual render is 12px). The 62.5% hack will fail; at this point, 1em/1rem will equal 12px instead of 10px.
In newer versions of Chrome, setting -webkit-text-size-adjust: none; is useless. The effect on mobile is unknown.
4. Case Study
Mobile Taobao: Single screen + JS simulated scrolling (it's quite powerful!).
5. Benefits of em/rem
(A side note, somewhat unrelated to the main content)
Why do some pages only use em/rem for text while using px for everything else?
Because px is an absolute unit. Users can set their browser's default font size; if the text unit is px, it won't scale according to user settings, whereas em/rem will.
III. img + div Width Percentage, Height auto
This is an old method, nothing fancy. The downside is that text doesn't scale with it. There are two solutions:
- Embedding text into images
The downside is slower page loading.
- Manually calculating
fzwith JS to scale fonts (combined with em/rem)
Calculating a specific scale factor based on screen width/height, DPI, etc., and multiplying it by the base fz to scale fonts. The downside is that it's tedious and hard to find a suitable factor (only works for some models).
DEMO: Not provided, please check the case studies.
Case Studies
-
Amap All-Star Navigation Voice Event: Text scaling was not handled; requirements were low.
-
Mobile JD: Text scaling not handled, but content is mainly image-based, so the impact is minimal.
IV. Summary of Mobile Page Adaptation Solutions
-
Prefer the
scale/zoomsolution, provided that the page is simple (definition of "simple" mentioned above). -
If that doesn't work, consider the
rem/emsolution, keeping compatibility in mind (rem [IE8-]). -
As a last resort, use the image solution. If requirements are low, you can ignore fonts; otherwise, you're in trouble.
No comments yet. Be the first to share your thoughts.