Mobile adaptation scheme and conversion between REM and px

Source: Internet
Author: User

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 Retina screen (for example: 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:

For dpr=2 's phone, why is the canvas size X2 to solve HD problems?

For twice times the size of the visual manuscript, how to restore the real width of each chunk (i.e. layout problem) in the specific CSS encoding?

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:

Device pixel ratio = physical pixel/device independent pixel//in one Direction, x direction or y direction

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-- taking Iphone6 as an example:

The device has a width height of 375x667, which can be understood as a device independent pixel (or CSS pixel).

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:

12 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 questions, I made a demo.

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 (if it does not appear obvious, please download the original).

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

12 width: 200px;height: 300px;

2. Background image

1234 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) also downloaded @2x pictures, resulting in a waste of resources.

2) image due to 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 (click Preview), can be similar to the picture cropping:

200x200

100x100

(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):

12345678910111213 .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):

In this way, all the border:1px in the page will be reduced by 0.5, thus achieving border:0.5px effect.

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

However, page scale inevitably poses some problems:

1) font size will be scaled

2) The layout of the page will be scaled (e.g.: 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) Multiply DPR because the page is likely to be scaled (scale) 1/DPR times in order to implement the 1PX border page (if not, dpr=1).

2) divided by 10, is for rounding, 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:

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)

123456789101112131415161718192021222324252627 vardpr, rem, scale;vardocEl = document.documentElement;varfontEl = document.createElement(‘style‘);varmetaEl = document.querySelector(‘meta[name="viewport"]‘);scale = 1 / dpr;dpr = win.devicePixelRatio || 1;rem = docEl.clientWidth * dpr / 10;// 设置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);    returnv * rem;};window.px2rem: function(v) {    v = parseFloat(v);    returnv / 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 Fit 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) Use the above-mentioned HD 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/reference value;

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:

1234 // 例如: .px2rem(height, 80);.px2rem(@name, @px){    @{name}: @px / 75 * 1rem;}

So, for the wide-750x300px Div, we write with less:

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

Convert to HTML, that's it:

12 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:

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

Such a wide height, we often get the way:

1) 750x1334 The visual manuscript into the size of the 375x667, then to the size of the block (feel good silly).

2) after 750x1334 The block width is 750x300px, 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:

1234 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:

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

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

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

Mobile adaptation scheme and conversion between REM and px

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.