Background
- Developing mobile H5 Pages
- Face different resolution of the phone
- Face different screen size of the phone
Visual manuscript
Before the front-end development, the visual mm will give us a PSD file, called the visual manuscript.
For mobile development, in order to achieve the effect of high-definition pages, visual Draft specifications will often follow the following two points:
1, first, choose a phone's screen width high as a benchmark (formerly iphone4 320x480, now more is Iphone6 375x667).
2, for the retina screen (such as: dpr=2), in order to achieve high-definition effect, the canvas size of the visual manuscript will be twice times the benchmark, that is, the number of pixels is 4 times times the original (for Iphone6: The original 375x667, will become 750x1334).
Problem:
1, for dpr=2 mobile phone, why the canvas size x2, you can solve the HD problem?
2, for twice times the size of the visual manuscript, in the specific CSS encoding how to restore the true width of each chunk (that is, layout problems)?
Take a question and look down ...
Some concepts
Before you perform a specific analysis, you must first know the following key basic concepts (terminology).
Physical pixels (physical pixel)
A physical pixel is the smallest physical display unit on a display (phone screen), and each device pixel has its own color value and luminance value under the operating system's schedule.
Device independent pixels (density-independent pixel)
Device-independent pixels (also called density-independent pixels) can be thought of as a point in a computer coordinate system that represents a virtual pixel (such as a CSS pixel) that can be used by a program and then converted from a related system to a physical pixel.
Therefore, there is a certain correspondence between the physical pixels and the device independent pixels, which is the next device pixel ratio.
Unit pixel ratio (device pixel ratio)
The device pixel ratio (abbreviated DPR) defines the correspondence between the physical pixels and the device's independent pixels, and its value can be obtained by the following formula:
设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向
In JavaScript, you can get the DPR of the current device through Window.devicepixelratio.
In CSS, media queries can be made via-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio and-webkit-max-device-pixel-ratio, For different DPR devices, do some styling (this is only for WebKit kernel browsers and WebView).
Combined with the above concepts, an example is illustrated below:
Take Iphone6 as an example:
1, the device width is 375x667, can be understood as device independent pixels (or css pixels).
2, DPR is 2, according to the above calculation formula, its physical pixels should be x2, for 750x1334.
Show it with a picture, that's it (forgive me for stealing pictures):
As you can see, for such a CSS style:
width: 2px;height: 2px;
on different screens (normal screen vs retina screen), the size (physical size) of the CSS pixels is consistent, and the difference is that the number of physical pixels corresponding to the 1 CSS pixels is inconsistent.
On a normal screen, 1 css pixels correspond to 1 physical pixels (1:1).
Under the Retina screen, 1 css pixels correspond to 4 physical pixels (1:4).
Bit image voxel
A bit image element is the smallest data unit of a raster image (e.g. PNG, JPG, GIF, etc.). Each bit image contains some of its own display information (such as: Display position, color value, transparency, etc.).
When it comes to this, you have to say, what is the display of the retina film?
In theory, the 1-bit pixels correspond to 1 physical pixel images for a perfectly clear display.
There is no problem on the normal screen, but there is not enough bit image dot in the retina screen, which causes the picture to blur.
Use a picture to indicate:
For example, for the retina screen of dpr=2, 1 bit pixels correspond to 4 physical pixel, because the single bit image can not be further segmented, so only the nearest color, resulting in blurred images (note the above several color values).
Therefore, for the picture HD problem, the better solution is twice times the picture (@2x).
such as: 200x300 (CSS pixel) img tag, you need to provide 400x600 pictures.
As a result, the number of bit image pixels is 4 times times the original, in the Retina screen, the number of pixel points can be compared with the number of physical points to form a ratio of 1:1, the picture is naturally clear (this also explains a question left before, why the canvas size of the visual manuscript to X2? )。
Here is another question, if the ordinary screen, also used twice times the picture, what will happen?
Obviously, in the ordinary screen, the 200x300 (CSS pixel) img tag, the corresponding number of physical pixels is 200x300, and twice times the image of the number of bits is 200x300*4, so there is a physical pixel point corresponding to 4 bit image point, So its color can only pass a certain algorithm (the result is a total of only the original image of One-fourth, we call this process called downsampling), the naked eye, although the image will not be blurred, but will feel the picture is missing some sharpness, or a bit of chromatic aberration (but still acceptable).
Use a picture to indicate:
For the above two issues, I did a demo (intranet access) Mad poke here.
In the demo, the 100x100 images are placed in the 100x100,50x50,25x25 img container and displayed under the Retina screen.
The bar chart, through the magnifying glass can actually see the boundary pixel point value of the difference:
- Figure 1, the nearest color, color value between the red and white, biased, the picture will appear blurred (can be understood as picture stretching).
- Figure 2, no near the color, the color value is either red, or white, the picture looks very clear.
- Figure 3, the nearest color, color value between the red and white, biased, the picture looks bad color, lack of sharpness (can be understood as image extrusion).
Love Word map, you can see the text "Love" to distinguish between blurred picture or clear.
(PS: If it doesn't look obvious, you can use your mobile phone to scan the code page (intranet address) or click on the original view will be more intuitive point.
Several questions
Here to say, mobile H5 development, at different resolutions, different screen phones will encounter a few classic problems.
Retina, picture HD problem
The solution is already covered in this question: twice times the picture (@2x), then the picture container shrinks by 50%.
such as: Picture size, 400x600;
1.img Label
width: 200px;height: 300px;
2. Background image
width: 200px;height: 300px;background-image: url([email protected]);background-size: 200px 300px; // 或者: background-size: contain;
Such a disadvantage, it is obvious, under the ordinary screen:
1, the same download @2x pictures, resulting in a waste of resources.
2, the picture because of downsampling, will lose some sharpness (or chromatic aberration).
So the best solution is: Under different DPR, load different sizes of pictures.
Whether it is through CSS media queries, or through JavaScript conditions can be judged.
So the question comes, so, isn't it just to prepare two sets of pictures? (@1x and @2x)
I think, do good company, will have such a picture server, through the URL to get parameters, then you can control the picture quality, you can also cut the picture into different sizes.
So we only need to upload large image (@2x), the rest of the small map to the image server processing, we only need to be responsible for stitching the URL.
For example, such an original image:
https://img.alicdn.com/tps/TB1AGMmIpXXXXafXpXXXXXXXXXX.jpg // 原图
You can do a picture clipping like this:
// 200×200https://img.alicdn.com/tps/TB1AGMmIpXXXXafXpXXXXXXXXXX.jpg_200x200.jpg// 100×100https://img.alicdn.com/tps/TB1AGMmIpXXXXafXpXXXXXXXXXX.jpg_100x100.jpg
(PS: Of course, cutting only to the original image of the cut, to ensure that the picture is clear ~)
Under Retina, border:1px problem
This is probably the designer's most sensitive, most concerned about the problem.
First of all, why is there retina, border:1px this said?
We normally write CSS, like this border:1px, in the retina screen, what is the problem?
First, take a look at the following figure:
The above two graphs are the test results under IPHONE3GS (dpr=1) and Iphone5 (dpr=2), and in contrast, for the 1px border display, they are consistent and no difference.
So what are the advantages of the retina display, and why do designers think that the line is thick under the HD screen (right)? Clearly and around the same ~
Or a picture to explain (forgive me for stealing the picture again):
, for a 1px wide line, their physical size on the screen (gray area) is indeed the same, the difference is actually the smallest physical display unit on the screen, that is, the physical pixels, so for a straight line, iphone5 it can show the minimum width is actually the red line in the graph circled out of the gray area, Using CSS to represent, theoretically speaking, 0.5px.
So, the designer wants the retina under the border:1px, in fact is 1 physical pixel width, for CSS, can be considered as border:0.5px; this is the smallest unit that can be displayed under Retina (dpr=2).
However, not all mobile browsers can identify border:0.5px;,ios7 below, Android and other systems, 0.5px will be treated as 0px, then how to achieve this 0.5px it?
The simplest approach is 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;}
As usual we write border-bottom:1px solid #ddd, and then through the Transform:scaley (. 5) reduced by 0.5 times times to achieve 0.5px effect, but so hack is not enough general (such as: rounded corners, etc.), write up also trouble.
Of course there are many other hack methods, the internet can be searched, but each has pros and cons, here is more recommended or page scale scheme, is more general, almost meet all scenarios.
For Iphone5 (dpr=2), add the following meta tag, 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, all the border:1px in the page will be reduced by 0.5, thus achieving border:0.5px effect.
Some people worry that the page scale will affect performance, @ Wonderful net students have done performance testing, see here (intranet address).
Take a look at the implementation of the comparison (the picture on the right is optimized):
(PS: The picture has been compressed, it may not seem obvious, you can use the phone to scan the code or click here (Intranet address) comparison to see)
However, page scale inevitably poses some problems:
1. Font size will be scaled
2, the page layout will be scaled (such as: div width higher)
These two questions are mentioned later ...
Multi-screen Adaptive layout problem
Mobile layout, in order to adapt to a variety of large-screen mobile phones, the best solution is to use relative unit Rem.
Based on the REM principle, all we have to do is change the font-size size (base value) of the root node HTML dynamically for different screen sizes and DPR of the phone.
Here we extract a formula (REM represents a Datum value)
rem = document.documentElement.clientWidth * dpr / 10
Description
1, multiplied by DPR, is because the page is likely to achieve 1px border the page will zoom (scale) 1/DPR times (if not, dpr=1).
2, divided by 10, is to take the whole, convenient calculation (theoretically can be any value)
So just like the following, the HTML font-size may:
IPHONE3GS:320PX/10 = 32px
IPHONE4/5:320px * 2/10 = 64px
iphone6:375px * 2/10 = 75px
For dynamically changing the font-size of the root node HTML, we can do it via CSS or through JavaScript.
CSS, you can change the HTML font-size by using the device width 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: The device width range of media queries to dynamically change the REM benchmark value, in fact, is not accurate, such as: Width of 360px and 320px width of the phone, because the screen width in the same range (<375px), so will be treated equally (REM reference value is the same), In fact, their screen widths are not equal, and their layouts should be different. In the end, the conclusion is that such a practice is not accurate enough, but sufficient.
JavaScript way, through the above formula, calculate the baseline value REM, and then write the style, probably as follows (code reference from Kimi m-base module)
var dpr, rem, scale;var docEl = document.documentElement;var fontEl = document.createElement(‘style‘);var metaEl = document.querySelector(‘meta[name="viewport"]‘);dpr = window.devicePixelRatio || 1;rem = docEl.clientWidth * dpr / 10;scale = 1 / dpr;// 设置viewport,进行缩放,达到高清效果metaEl.setAttribute(‘content‘, ‘width=‘ + dpr * docEl.clientWidth + ‘,initial-scale=‘ + scale + ‘,maximum-scale=‘ + scale + ‘, minimum-scale=‘ + scale + ‘,user-scalable=no‘);// 设置data-dpr属性,留作的css hack之用docEl.setAttribute(‘data-dpr‘, dpr);// 动态写入样式docEl.firstElementChild.appendChild(fontEl);fontEl.innerHTML = ‘html{font-size:‘ + rem + ‘px!important;}‘;// 给js调用的,某一dpr下rem和px之间的转换函数window.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;
This way, can accurately calculate the different screen should be the REM benchmark value, the disadvantage is to load such a section of JS code, but personally think this is the best solution for the present.
Because this solution solves three problems at the same time:
1, border:1px problem
2, Picture HD problem
3. Screen adaptation layout problem
When it comes to layout, it's natural to answer the original question: How do you restore the true width of your visual artwork in CSS encoding?
Prerequisites:
1, got a high-definition visual manuscript for Iphone6 750x1334
2, using the above-mentioned high-definition scheme (JS code).
If there is a chunk in the PSD file: The width of the high 750x300px Div, then how to convert to REM units?
The formula is as follows:
rem = px / 基准值;
For a iphone6 visual manuscript, its benchmark value is 75 (previously mentioned);
So, after we've determined the visual manuscript (that is, we've determined the benchmark), we usually write a mixin with less, like this:
// 例如: .px2rem(height, 80);.px2rem(@name, @px){ @{name}: @px / 75 * 1rem;}
So, for the wide-750x300px Div, we write with less:
.px2rem(width, 750);.px2rem(height, 300);
Convert to HTML, that's it:
width: 10rem; // -> 750pxheight: 4rem; // -> 300px
Finally, because DPR is 2, the page scale is 0.5, so the real width on the phone screen should be 375x150px, just good.
If the page does not have scale 0.5, our code would have to do this:
.px2rem(width, 375);.px2rem(height, 150);
Such a wide height, we often get the way:
1, the 750x1334 visual manuscript into the size of the 375x667, then to the size of this chunk (feel good silly).
2, in the 750x1334 volume is 750x300px after the width of the block, then mental arithmetic divided by 2 (feel good Trouble).
Finally, a comparison chart with no layout adaptation () and a REM layout adaptation () is given:
(The phones above are: IPHONE3GS, iphone5, Iphone6)
It is obvious that the width and height of the various blocks of REM adaptation will vary with the width of the mobile phone screen, the most obvious can see a list of that part, the last picture of the visual draft requirements only a little bit, REM layout on any screen is displayed very well.
Font size Issues
Since the above scheme will make the page scaling (scale), for the width of the page block, we can rely on high-definition visual manuscript, because the visual manuscript is X2, we can directly amount to, then how to handle the font?
For the font scaling problem, the original requirements of the designer is this: any phone screen font size must be uniform, so we for different resolutions (DPR different), will do the following:
font-size: 16px;[data-dpr="2"] input { font-size: 32px;}
(Note that the font can not be used with REM, the error is too large and does not fit any screen under the same font size)
For convenience, we will also write a mixin with less:
.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 三星note4 [data-dpr="4"] & { @{name}: @px * 2px; }}
(Note: The HTML DATA-DPR attribute is mentioned in the previous JS scheme, it is useful here.)
According to experience and testing, or will appear these odd DPR, here do a unified compatible ~
When used, it's like this:
.px2px(font-size, 32);
Of course, for other CSS properties, if you also want to be consistent under different DPR, you can also do this, such as:
.px2px(padding, 20);.px2px(right, 8);
Reference articles
http://www.smashingmagazine.com/2012/08/20/towards-retina-web/
Http://www.paintcodeapp.com/news/iphone-6-screens-demystified
http://www.inserthtml.com/2012/09/designing-retina-devices/
http://iconmoon.com/blog2/iphone-6-plus-screen-size/
Http://dieulot.net/css-retina-hairline
At last
If the wrong place, welcome message, Sina Weibo –lovesueee.
Original address: http://www.aliued.com/?p=3166
More Articles
Mobile high-definition, multi-screen adaptation scheme