Q: mobile terminal H5 page HD multi-screen adaptation solution,

Source: Internet
Author: User

Q: mobile terminal H5 page HD multi-screen adaptation solution,
Background

  • Develop mobile terminal H5 page

  • Mobile phones with different resolutions

  • Mobile phones of different screen sizes

Visual draft

Before the front-end development, visual MM will give us a psd file called a visual draft.

For mobile development, in order to achieve the page HD effect, the specifications of visual drafts often follow the following two points:

1) First, select the screen width and height of a mobile phone as the benchmark (previously 320x480 of the iPhone 4, now more than 375x667 of the iPhone 6 ).

2) For the retina screen (for example, dpr = 2), in order to achieve the high-definition effect, the canvas size of the visual draft will be twice the size of the benchmark, that is to say, the number of pixels is four times the original number (for iPhone 6: the original number of pixels is 375x667, and the number of pixels is 750x1334 ).

Problem:

Why can I solve the problem of HD when the canvas size is × 2 for mobile phones with dpr = 2?

How can I restore the true width and height of each block (that is, the layout problem) of a visual draft of 2 times the size in a specific css code )?

Take a look at the problem...

Concepts

Before performing a specific analysis, you must first understand the following key basic concepts (terms ).

Physical pixel (physical pixel)

A physical pixel is the smallest physical display unit on the display (mobile phone screen). Under the scheduling of the operating system, each device pixel has its own color value and brightness value.

Device independent pixel (density-independent pixel)

Device Independent pixels (also called density independent pixels) can be considered as a point in the computer coordinate system. This point represents a virtual pixel (such as css pixel) that can be used by the program ), then it is converted from the relevant system to the physical pixel.

Therefore, there is a certain correspondence between physical pixels and device independent pixels, which is the device pixel ratio.

Device pixel ratio)

The device pixel ratio (dpr) defines the correspondence between the physical pixel and the independent pixel of the device. The value can be obtained according to the following formula:

Device pixel ratio = physical pixel/device independent pixel // on one side up, x direction or y direction

In javascript, you can use window. devicePixelRatio to obtain the dpr of the current device.

In css, you can use-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio, and-webkit-max-device-pixel-ratio to query media, make some style adaptation for devices of different dpr (here only for browsers and webviews of the webkit kernel ).

Taking the above concepts as an example:

The device width and height are 375 × 667, which can be understood as device independent pixels (or css pixels ).

Dpr is 2. According to the above calculation formula, the physical pixel should be × 2, which is 750 × 1334.

Use a picture as shown in the following figure (Forgive me for stealing the picture ):


We can see that for such css styles:

width: 2px;height: 2px;

On different screens (normal screen vs retina screen), css pixels are displayed in the same size (physical size, the difference is that the number of physical pixels corresponding to one css pixel is inconsistent.

On a normal screen, one css pixel corresponds to one physical pixel ). On the retina screen, one css pixel corresponds to four physical pixels ).

Bitmap pixels

A Bitmap pixel is the smallest data unit of a raster image (such as png, jpg, or gif. Each bitmap pixel contains some display information (such as the display position, color value, and transparency ).

Let's talk about the retina display?

In theory, a bitmap pixel corresponds to a physical pixel, so that the image can be displayed perfectly and clearly.

There is no problem on the normal screen, but there will be insufficient bitmap pixels on the retina screen, resulting in blurred images.

It is represented by a graph:


For example, for a retina screen with dpr = 2, one bitmap pixel corresponds to four physical pixels. Because a single bitmap pixel cannot be further divided, it can only be colored nearby, this causes the image to be blurred (pay attention to the preceding color values ).

Therefore, for image HD, a better solution is to double the image (@ 2x ).

For example, the 200x300 (css pixel) img Tag Requires 400x600 images.

As a result, the number of Bitmap pixels is four times the original number. On the retina screen, the number of Bitmap pixels can be 1 to 1 with the number of physical pixels, the image is naturally clear (this also explains a question left behind, why is the canvas size of the visual draft × 2 ?).

There is another problem here. What if I use a double image under a normal screen?

Obviously, on a normal screen, the number of physical pixels corresponding to the 200x300 (css pixel) img tag is 200x300, two times the number of Bitmap pixels is 200 × 300 × 4, so a physical pixel corresponds to four bitmap pixels, therefore, it can only use a certain algorithm (the result is that only the total number of pixels in the source image is 1/4, which is called downsampling). Although the image is not blurred, however, you may feel that the image lacks some sharpness or color difference (but acceptable ).

It is represented by an image:


I made a demo for the two problems above.


In the demo, 100x100 images are placed in the img container of 100 x, 50x50, and 25x25, respectively, and displayed on the retina screen.

Bar chart. You can see the different values of the border pixel through a magnifier:

  • Figure 1: Color nearby. The color value ranges from red to white. It is light and the image looks blurred (it can be understood as stretching ).

  • Figure 2: There is no nearby color. The color value is either red or white, and the image looks clear.

  • Figure 3: Color nearby. The color value ranges from red to white. The image looks colored and lacks sharpness (which can be understood as image extrusion ).

You can identify whether the image is blurred or clear by reading the text "love" (if it does not look obvious, download the original image ).

 

Several Questions

Here we will talk about several typical problems that mobile terminal H5 developers will encounter in different resolutions and mobile phones on different screens.

IMG problems in retina

The solution has been introduced above: double image (@ 2x), and the image container is reduced by 50%.

For example, the image size is 400 × 600;

1. img tag

width: 200px;height: 300px;

2. Background Image

Width: 200px; height: 300px; background-image: url(image@2x.jpg); background-size: 200px 300px; // or: background-size: contain;

The disadvantage is obvious:

1) The image @ 2x is also downloaded, resulting in a waste of resources.

2) due to downsampling, the image will lose some sharpness (or chromatic aberration ).

So the best solution is to load images of different sizes under different dpr.

It can be determined either through css media queries or through javascript conditions.

So the question is, isn't it necessary to prepare two sets of images? (@ 1x and @ 2x)

I think a good company will have such an image server. It can get parameters through url, control the image quality, and crop the image to different sizes.

Therefore, we only need to upload a large image (@ 2x), and the remaining small images are handed over to the image server for processing. We only need to splice the URLs.

For example, you can crop an image like this (Click Preview:

// 200x200


// 100x100


(Ps: Of course, the cropping only performs proportional cropping on the source image. You must ensure that the image is clear ~)

Border: 1px in retina

This is probably the most sensitive and important issue for designers.

First of all, why does border: 1px in retina exist?

We normally write css, like this border: 1px;. What is the problem on the retina screen?

Let's take a look at the figure below:


The above two figures show the test results under iPhone3gs (dpr = 1) and iPhone5 (dpr = 2) respectively. The comparison shows that the border of 1px is consistent, there is no difference.

So what are the advantages of the retina display? Why do designers think that the lines under the high-definition screen (right) are thick? It is the same as that of the left and right sides ~

I will explain it through a picture (Forgive me for stealing the image again ):


For a straight line with a width of 1 px, the physical size (gray area) on the screen is indeed the same. The difference is actually the smallest physical display unit on the screen, that is, the physical pixel, therefore, for a straight line, the minimum width displayed by iPhone 5 is actually the gray area of the red coil in the figure. It is expressed by css, which is theoretically 0.5px.

Therefore, the designer wants border: 1px under retina, which is actually 1 physical pixel width. For css, it can be considered as border: 0.5px;, which is under retina (dpr = 2) the smallest unit that can be displayed.

However, not all mobile browsers can recognize border: 0.5px;, less than ios7, and in other android systems, 0.5px will be treated as 0px. How can we achieve this?

The simplest way is like this (element scale ):

.scale{    position: relative;}.scale:after{    content:"";    position: absolute;    bottom:0px;    left:0px;    right:0px;    border-bottom:1px solid #ddd;    -webkit-transform:scaleY(.5);    -webkit-transform-origin:0 0;}

We will write border-bottom: 1px solid # ddd; as usual, and then use transform: scaleY (. 5) reduce the size by 0.5 times to reach PX, but the hack is not general enough (such as rounded corners), which is troublesome to write.

Of course, there are many other hack methods that can be found on the Internet, but they have their own advantages and disadvantages. Here we recommend the page scale solution, which is more common and meets almost all scenarios.

For iPhone 5 (dpr = 2), add the following meta tag and set viewport (scale 0.5 ):


In this way, all the border: 1px on the page will be reduced by 0.5 to achieve the border: 0.5px; effect.

Take a look at the comparison after implementation (the picture on the right is optimized ):


However, page scale will inevitably cause some problems:

1) the font size is scaled.

2) The page layout is scaled (for example, the width of the div is higher)

These two questions will be discussed later...

Multi-screen Adaptive Layout

Mobile Terminal layout, in order to adapt to a variety of big screen mobile phones, the current best solution is to use the relative unit rem.

Based on the rem principle, we need to dynamically change the font-size (reference value) of the root node html based on the screen size of different mobile phones and dpr ).

Here we extract a formula (rem indicates the reference value)

Rem = document.doc umentElement. clientWidth * dpr/10

Note:

1) Multiply by dpr because the page may be scaled by 1/dpr to achieve 1px border (if not, dpr = 1 ).

2) divide by 10 to get an integer for easy calculation (theoretically it can be any value)

As shown in the following figure, the font-size of html may be:

IPhone3gs: 320px/10 = 32px

IPhone4/5: 320px * 2/10 = 64px

IPhone6: 375px * 2/10 = 75px

We can use css or javascript to dynamically change the font-size of the root node html.

In css mode, you can use the device width for media queries to change the font-size of html:


Disadvantage: it is not accurate enough to dynamically change the rem reference value through a media query such as the device width range. For example, if the width is 360px and the width is 320px, because the screen width is within the same range (<375px), it will be treated equally (the rem benchmark value is the same), and in fact their screen width is not equal, their layout should also be different. In the end, the conclusion is that such an approach is not accurate enough, but is sufficient.

In javascript mode, the above formula is used to calculate the reference value rem, and then write the style, which is roughly as follows (the code reference is from kimi's m-base module)

Var dpr, rem, scale; var docEl = document.doc umentElement; var fontEl = document. createElement ('style'); var metaEl = document. querySelector ('meta [name = "viewport"] '); scale = 1/dpr; dpr = win. devicePixelRatio | 1; rem = docEl. clientWidth * dpr/10; // sets the viewport and scales to achieve metaEl. setAttribute ('content', 'width = '+ dpr * docEl. clientWidth + ', initial-scale =' + scale + ', maximum-scale =' + scale + ', mi Nimum-scale = '+ scale +', user-scalable = no'); // you can specify the data-dpr attribute and specify docEl as the css hack. setAttribute ('data-dpr', dpr); // dynamic write style docEl. firstElementChild. appendChild (fontEl); fontEl. innerHTML = 'html {font-size: '+ rem + 'px! Important;} '; // The Conversion Function window between rem and px in a dpr. rem2px = function (v) {v = parseFloat (v); return v * rem;}; window. px2rem: function (v) {v = parseFloat (v); return v/rem;}; window. dpr = dpr; window. rem = rem;

In this way, we can accurately calculate the expected rem reference value for different screens. The disadvantage is that we need to load such a piece of js code, but I personally think this is the best solution at present.

This solution solves three problems at the same time:

1) border: 1px Problem

2) image HD Problems

3) screen adaptation Layout

Speaking of layout, you naturally have to answer the question that was left behind: how to restore the true width and height of the visual draft in css coding?

Prerequisites:

1) I got a 750x1334 HD visual draft for iPhone 6.

2) use the above HD solution (js Code ).

If there is a block that is measured in the psd file: a div with a width of 750 × PX, how can it be converted to a rem unit?

The formula is as follows:

Rem = px/reference value;

For an iPhone 6 visual draft, its reference value is 75 (previously mentioned );

Therefore, after determining the visual draft (that is, determining the benchmark value), we usually use less to write a mixin, like this:

// For example:. px2rem (height, 80);. px2rem (@ name, @ px) {{ name }:@ px/75 * 1rem ;}

Therefore, for the div with a width of 750 x PX, we use less to write as follows:

.px2rem(width, 750);.px2rem(height, 300);

Convert to html as follows:

width: 10rem; // -> 750pxheight: 4rem; // -> 300px

Finally, because dpr is 2 and the page scale is 0.5, the actual width and height displayed on the mobile phone screen should be 375 × 150px, which is just right.

If the page does not have a scale 0.5, our code should be like this:

.px2rem(width, 375);.px2rem(height, 150);

We often get this wide and high:

1) convert the visual draft of 750x1334 to a size of 375x667, and then measure the size of the block (it feels silly ).

2) After the block width and height of 750x1334 is 750 x PX, divide it by 2 (it feels troublesome ).

Finally, we provide a comparison between no layout adaptation () and rem layout adaptation:


(The above mobile phones are: iPhone 3gs, iPhone 5, and iPhone 6)

Obviously, the width and height of each block adapted by rem will change with the screen width of the mobile phone. The most obvious part is the part of the list. The last visual draft requires only a little bit, the rem layout is displayed well on any screen.

Font size Problems

Since the above scheme will scale the page, for the width and height of the page block, we can rely on the high-definition visual draft, because the visual draft is × 2, we can just scale it out. What should we do with the font?

The original requirements of the designer for font scaling are as follows: the font sizes on the screen of any mobile phone should be uniform, so we will handle different resolutions (different dpr) as follows:

font-size: 16px;[data-dpr="2"] input {  font-size: 32px;}

(Note: The font cannot use rem, the error is too large, and cannot meet the same font size in any screen)

For convenience, we will also use less to write a mixin:

. Px2px (@ name, @ px) {@ {name}: round (@ px/2) * 1px; [data-dpr = "2"] & {@ {name }: @ px * 1px;} // for mx3 [data-dpr = "2.5"] & {{ name}: round (@ px * 2.5/2) * 1px ;} // for note [data-dpr = "2.75"] & {@{ name}: round (@ px * 2.75/2) * 1px ;} [data-dpr = "3"] & {@ {name}: round (@ px/2*3) * 1px} // for Samsung note4 [data-dpr = "4"] & {{ name }:@ px * 2px ;}}

(Note: The data-dpr attribute of html is mentioned in the previous js solution, which is useful here)

Based on experience and test, the dpr of these odd samples will still appear, and the unified compatibility is implemented here ~

It is like this:

.px2px(font-size, 32);

Of course, for other css attributes that must be consistent under different dpr, you can also perform this operation, such:

.px2px(padding, 20);.px2px(right, 8);

Last

I have summarized some solutions for mobile terminal H5 HD and multi-screen adaptation, and explained their knowledge. If not, please point it out.

 


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.