Mobile HD and multi-screen adaptation solutions [Source: http://div.io/topic/1092], div.io1092
Lovesueee was released before January 1, August.
Mobile HD and multi-screen adaptation solutions
Background Visual draft
Before front-end development, visual MM will give us a psd file calledVisual draft
.
For mobile development, in order to achieve the page HD effect, the specifications of visual drafts often follow the following two points:
Problem:
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 degree of difference between physical pixels and device independent pixels.Correspondence
This is what we will talk about next.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 usewindow.devicePixelRatio
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
Perform media queries and make 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:
Toiphone6
For example:
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 (1:1
).
On the retina screen, one css pixel corresponds to four physical pixels (1:4
).
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, a better solution for image HD problems isDouble Image
(@ 2x ).
For example, the 200x300 (css pixel) img Tag Requires 400x600 images.
In this way, the number of Bitmap pixels is the original4
Times, on the retina screen,Number of Bitmap pixels
You canNumber of physical pixels
Formation1 : 1
The image is naturally clear (this also explains a problem left behind, why is the size of the canvas of the visual draft required?×2
?).
There is another problem here. If the screen is normalDouble Image
What will happen?
Obviously, on a normal screen, the number of physical pixels corresponding to the 200x300 (css pixel) img tag is200×300
AndDouble Image
The number of Bitmap pixels is200×300*4
Therefore, a physical pixel corresponds to four bitmap pixels, so the color of the physical pixel can only be obtained through a certain algorithm (the result is that only the total number of pixels in the source image is 1/4, we call this processdownsampling
), Although the image is not blurred to the naked eye, it may feel that the image lacks some sharpness or a little color difference (but it is 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
Through a magnifier, we can see that the values of the border pixels are different:
- 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 ).
Love chart
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 described above:Double image (@ 2x)
And then the image container is reduced.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:
So the best solution is:Loading 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 there will be such a good company.Image Server
You can get parameters through the url, and then control the image quality or 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/TB1AGMmIpXXXXafXpXXXXXXXXXX.jpg // source Image
You can crop an image as follows:
// 200×200https://img.alicdn.com/tps/TB1AGMmIpXXXXafXpXXXXXXXXXX.jpg_200x200.jpg// 100×100https://img.alicdn.com/tps/TB1AGMmIpXXXXafXpXXXXXXXXXX.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 thisborder: 1px;
Is there any problem on the retina screen?
Let's take a look at the figure below:
The above two images are shown iniphone3gs(dpr=1)
Andiphone5(dpr=2)
The following test results show that for 1 px border, they are consistent and there is no difference.
So what do designers think about the advantages of the retina display?HD screen
Bottom (right) LineRough
What about it? 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 ):
For1px
The physical size (gray area) of the wide straight lines on the screen is indeed the same. The difference is actually the smallest physical display unit on the screen, that is, the physical pixel, so for a straight line, the minimum display width of iPhone 5 is actually the gray area of the red coil in the figure. It is expressed by css, theoretically0.5px
.
So, what the designer wants isborder: 1px;
It is actually a physical pixel width. For css, it can be consideredborder: 0.5px;
This is the smallest unit that can be displayed under retina (dpr = 2.
However, not all mobile browsers can recognize this vulnerability.border: 0.5px;
In other systems such as iOS 7 and android, 0.5px is treated as 0px. How can this problem be solved?0.5px
What about it?
The simplest way is (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 write as usualborder-bottom: 1px solid #ddd;
And thentransform: scaleY(.5)
Reduced by 0.5 times to achieve0.5px
However, hack is not general enough (such as rounded corners.
Of course, there are many other hack methods that can be searched online, but they have their own advantages and disadvantages.Page scale
The solution is more common and meets almost all scenarios.
For iPhone 5 (dpr = 2), add the following meta tag and set viewport (scale 0.5 ):
<meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no">
In this way, allborder: 1px
Will be reduced by 0.5 to achieveborder: 0.5px;
.
Some people worry that page scale will affect performance,@ Miao Jing
You have performed performance tests. For more information, see 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:
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 relative unitsrem
.
Based on the rem principle, what we need to do is:For different mobile phonesScreen Size
Anddpr
Dynamically change the htmlfont-size
Size (reference value).
Here we extract a formula (rem indicates the reference value)
rem = document.documentElement.clientWidth * dpr / 10
Note:
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.
Css Mode
You can use the device width to modify the font-size of html for media queries:
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: Device widthRange
These media queries dynamically change the rem reference value, which is not accurate enough. For example, if the width of a mobile phone is 360px and the width of a mobile phone is 320px, because the screen width is within the same range (<375px ), so they will be treated equally (with the same rem benchmark value). In fact, their screen width is not the same and their layout should be different. In the end, the conclusion is that such an approach is not accurate enough, but is sufficient.
Javascript
, Use the formula above to calculate the reference value rem, and then write the style as follows (for the code, refer to the m-base module from kimi)
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:
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:
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
Because dpr is 2 and the page scale is 0.5, the actual width and height displayed on the mobile phone screen should be375×150
Px, 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:
The last one isNo layout adaptation ()
AndAdaptation with rem layout ()
Comparison diagram:
(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 designer's original requirements for font scaling are as follows:The font size on any mobile phone screen must be consistent
So we will do the following for different resolutions (different dpr:
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.
References