This article summarizes and explains some solutions and knowledge for mobile H5 HD and multi-screen adaptation. Before the front-end development, visual MM will give us a psd file called the visual draft. For mobile development, in order to achieve the page HD effect, the specifications of visual drafts often follow the following two points :......,.
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:
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 ).
For the retina screen (such as dpr = 2), the canvas size of the visual draft is twice the size of the benchmark to achieve the high-definition effect, 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 ).
Based on the above concepts, let's give an example:
Take iPhone 6 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:
For the above two problems, I made a demo (Intranet access) mad here.
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:
, Color nearby, the color value is between red and white, light, the image looks blurred (can be understood as image stretching ).
, There is no nearby color, the color value is either red or white, the picture looks very clear.
, Color nearby, color value between red and white, biased, picture looks colored difference, lack of sharpness (can be understood as picture squeeze ).
You can identify whether the image is blurred or clear by reading the text "love.
(Ps: if it does not look obvious, you can scan the webpage (intranet address) on your mobile phone or click the source image to view it more directly.
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:
The @ 2x image is also downloaded, resulting in a waste of resources.
Because of 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, an original image is as follows:
Https://img.alicdn.com/tps/tb1agmmip??afxp=*xx.jpg // source Image
You can crop an image as follows:
// 200×200https://img.alicdn.com/tps/TB1AGMmIp**afXp****XX.jpg_200x200.jpg// 100×100https://img.alicdn.com/tps/TB1AGMmIp**afXp****XX.jpg_100x100.jpg
(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.
Some people worry that the page scale will affect the performance. @ Miao Jing has done a performance test. For details, see here (intranet address ).
Take a look at the comparison after implementation (the picture on the right is optimized ):
(Ps: The image has been compressed and may not look obvious. You can use your mobile phone to scan the code or click here (intranet address) for comparison)
However, page scale will inevitably cause some problems:
The font size is scaled.
The page layout is scaled (for example, the width of p 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, what we need to do is:Dynamically change the font-size (reference value) of the root node html based on different cell phone screen sizes and dpr ).
Here we extract a formula (rem indicates the reference value)
rem = document.documentElement.clientWidth * dpr / 10
Note:
Multiply by dpr because the page may be scaled by 1/dpr to achieve 1px border (if not, dpr = 1 ),.
Dividing by 10 is to take 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:
html{font-size: 32px;}//iphone 6 @media (min-device-width : 375px) { html{font-size: 64px;}}// iphone6 plus @media (min-device-width : 414px) { html{font-size: 75px;}}*/
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"] '); dpr = window. devicePixelRatio | 1; rem = docEl. clientWidth * dpr/10; scale = 1/dpr; // sets the viewport and scales to achieve the high-definition metaEl effect. setAttribute ('content', 'width = '+ dpr * docEl. clientWidth + ', initial-scale =' + scale + ', maximum-scale =' + scale + ', Minimum-scale = '+ scale +', user-scalable = no'); // you can set the data-dpr attribute and use docEl for 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:
Border: 1px Problem
Image HD Problems
Screen Adaptation layout problems
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:
I got a 750x1334 high-definition visual draft for iPhone 6.
Use the above HD solution (js Code ).
If there is a block that is measured in the psd file: 750 x Px in width, how can it be converted to the 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 p 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:
After converting a visual draft of 750x1334 to a size of 375x667, you can measure the size of the block (it feels silly ).
After the block width and height of 750x1334 are 750 x PX, divide the value 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 Xiaomi 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 also point out Sina Weibo-Lovesueee.
Source: http://www.cnblogs.com/lovesueee/p/4618454.html.