Skip to main content

Mobile Page Adaptation Solutions

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

Mobile pages need to be compatible with various versions of Android and iOS browsers. Adapting to screens with different resolutions is a tricky problem. This article details two common page adaptation solutions and their pros and cons.

Problem Restatement

The adaptation discussed in this article does not refer to traditional @media queries.

  • media query is 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

  • zoom scaling defaults to the top-left corner as the center and cannot be changed; it doesn't cause issues with overlapping surrounding elements.

  • scale scaling defaults to the center; this can be changed, but it might overlap surrounding elements (the scaled content doesn't take up space).

  • zoom scaling on child elements can break alignment.

  • scale scaling on child elements can break alignment and is ineffective for inline elements.

  • zoom scaling on a parent element does not affect relative positions.

  • scale scaling on a parent element will not affect relative positions if it is set to center on the top-left corner.

  • zoom is compatible with almost any browser except Firefox (IE 5.5+).

  • scale is compatible with IE 11+ and Firefox.

DEMO: Differences between scale and zoom

2. Side Effects of scale

  1. 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.

  1. 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

  1. 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.

  1. 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.

  1. 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:

  1. No input fields like input or textarea, ensuring the soft keyboard won't pop up.

  2. No complex z-index hierarchies.

  3. No fixed elements.

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:

  1. Main premise: If the mobile page doesn't need to support IE, you can use scale; otherwise, stick to zoom. If Firefox compatibility is important, you'll need to add hacks.

  2. Either zoom or scale works for image scaling; for full-page scaling, scale is 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:

  1. Hard to calculate

The current element's fz value is inherited from all ancestor elements.

  1. Redundant tags

See the note above.

  1. 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 fz with 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

IV. Summary of Mobile Page Adaptation Solutions

  1. Prefer the scale/zoom solution, provided that the page is simple (definition of "simple" mentioned above).

  2. If that doesn't work, consider the rem/em solution, keeping compatibility in mind (rem [IE8-]).

  3. As a last resort, use the image solution. If requirements are low, you can ignore fonts; otherwise, you're in trouble.

References

Comments

No comments yet. Be the first to share your thoughts.

Leave a comment