preface

Many people may have doubts about the relationship between adaptive and DPR when doing mobile terminal adaptive, and some may have doubts, such as whether there will be problems in my adaptive scheme without DPR. In view of these doubts, I would like to share my opinions in the hope of relieving your worries.

1. What is size adaptation

First of all, adaptation may be understood differently in different people’s eyes, especially in relation to responsiveness. Here’s what I mean by adaptation, and how it differs from responsiveness. Let’s start with responsive design. Responsive design means good layout and content for different screen sizes. To put it simply, a single page can fit many different screen sizes and still look well designed. In order to achieve this purpose, JS or CSS may be used to dynamically change the size of the layout. During this process, element size changes, layout changes, and even elements will be hidden, such as when the page displayed on the PC end is transferred to the mobile end. And adaptive generally consider is another aspect, is the hope of the page design and the design of the design draft ratio is consistent, the purpose of this is adaptive, in the process for different screen width element size will also change, but don’t usually have the layout change, and hidden elements, because the design draft like this, we have to write a page according to the size of the designer sister. So as I said above, those that are written to CSS media queries are not strictly adaptive, because there is a scaling error between breakpoints, and to make the error smaller requires more interpolation. It is obvious that the use of CSS media query is not a good way to do adaptive, we need an accurate way to do this, this time JS out, the following will be a list of widely circulated Taobao solution and netease solution.

2. Taobao solution

Click here to see taobao scheme specific code flexible

Of course, the specific code does a lot of boundary handling and compatibility processing, but the core can be condensed into the following code

(function () {
    var dpr = window.devicePixelRatio;
    var meta = document.createElement('meta');
    var scale = 1 / dpr;
    meta.setAttribute('name'.'viewport');
    meta.setAttribute('content'.'width=device-width, user-scalable=no, initial-scale=' + scale +
      ', maximum-scale=' + scale + ', minimum-scale=' + scale);
    document.getElementsByTagName('head')[0].appendChild(meta); // Dynamically set the zoom size to affect the layout viewport sizefunction resize() {
      var deviceWidth  = document.documentElement.clientWidth;
      document.documentElement.style.fontSize = (deviceWidth / 10) +'px'; } resize(); window.onresize = resize; }) ()Copy the code

This code on the browser can be adaptive, he is the DPR first access equipment, the process of the so-called DPR is device pixels than, what is equipment pixel than, is the unit size, equipment physical pixel number divided by the number of independent pixel size, physical pixel is a mobile phone screen a luminous point, size is fixed, independent pixel also For a phone screen with a DPR of 2, set the CSS width to 1px, which actually covers 2 of the device’s physical pixels. After getting the DPR, set the meta viewport value dynamically to scale the layout. The key here is to set width=device-width and initial-scale. Before describing the effect of both, we need to understand the concept of the layout viewport, formerly known as the initial containing block, which is also called the canvas in the earlier literature. If you’re drawing to scale, a lot of times you have to look at the size of the canvas you’re using. For example, the designer drew a 200px square at 750px. If you’re drawing on a 100cm piece of paper, you might want to calculate the width of the square by 100cm by 200 / 750. You can see that there is no DPR used in this calculation, so how many paper molecules, how many atoms your stroke crosses doesn’t matter at all to my drawing scale. The size of the CSS depends on the size of the layout viewport, which is available in standard mode for web pages

document.documentElement.clientWidth,

Set width=device-width and initial-scale = scale to make the layout viewport DPR big and then scale the whole to fit the device size. This is also easy to verify in the console print layout viewport size on the line

var meta = document.createElement('meta');
        var scale = 0.1;
        meta.setAttribute('name'.'viewport');
Copy the code

var meta = document.createElement('meta');
        var scale = 0.5;
        meta.setAttribute('name'.'viewport');
Copy the code

And what you can see here is that even if I set scale not to be equal to 1 / DRP it doesn’t prevent me from drawing the elements to the scale of the design and there are two things to be careful about here, because I’m using Chrome to simulate this, and I found a couple of problems with that

  1. If the scale value is less than 0.1, the layout viewport can only be magnified 10 times
  2. The layout viewport does not shrink when scale is greater than 1, and the layout viewport no longer matches the width of the device, which does not actually happen.
  3. If you introduce flexible. Js for testing, be careful to remove boundary conditions because scaling affects the layout viewport size and the corresponding boundary conditions will trigger, leading to the misconception that DPR is related to adaptive

To achieve adaptive key is to make the size of the element and the layout viewport binding relationship, although the layout viewport zoom in here, but does not affect the binding relationship, taobao scheme of layout viewport width here ten equal parts, each the size of the equivalent to one over ten of the width of the layout, and put each assigned to the root element of the size of the font size, element size can set the rem Units are bound to the layout viewport, for example 200px, and they map proportionally like this

200px : 640px => xrem : 10rem

Here, 10REM is the width of the layout viewport. As long as the proportion of the element size is maintained, it has nothing to do with DPR

X = 10 * 200/640 = 3.125rem

The calculation here may take a little time, there are some plug-ins that can help to convert px to REM, but the solution is dead, people are alive, you just need to change taobao’s natural ten equal parts, for example, the design is 640px to change

Document. The documentElement. Style. FontSize = (deviceWidth / 6.4) +'px';
Copy the code

It was divided into 6.4 equal parts

200px: 640px => xREM: 6.4rem

X is just 2rem

Flow: REM => Root element font size => Layout viewport

And of course you can divide it into 100 equal parts, just so you can transition to vw units later

So why taobao to introducing the DPR, enlarged layout then narrow, one is that the plan is a good way to solve the problem of 1 px border, for Gao Qingbing set 1 px pixel size, actually across the DPR device pixels, so look line is thin enough, and the design draft arises discrepancy, and through the solution of layout is enlarged and reduced just to you It fixes the problem. But then came along with a problem, look at the screenshots we see the font size is changed, when the scale is set to 0.1 basic can’t see, the reason is that usually we won’t use the font size setting of rem, but use, is the px unit, the font size didn’t increase along with the amplification of layout viewport, but along with the overall scale of the page Here we have to respond to different DPR processing, in the taobao code we can see

docEl.setAttribute('data-dpr', dpr);
Copy the code

This is done by mounting DPR information on the root element and then setting the corresponding CSS properties for example

[data-dpr=2] div{
    font-size: 32px
}
[data-dpr=3] div{
    font-size: 48px
}
Copy the code

Especially for Android phones, all kinds of magic DPR, if every set like this would be a disaster so Taobao is very clever

 var isAndroid = win.navigator.appVersion.match(/android/gi);
        var isIPhone = win.navigator.appVersion.match(/iphone/gi);
        var devicePixelRatio = win.devicePixelRatio;
        if(isIPhone) {// for iOS, use the double solution for 2 and 3 screens, use the double solution for the restif(devicePixelRatio >= 3 && (! dpr || dpr >= 3)) { dpr = 3; }else if(devicePixelRatio >= 2 && (! dpr || dpr >= 2)){ dpr = 2; }else{ dpr = 1; }}else{// For other devices, still use the double solution DPR = 1; } scale = 1 / dpr;Copy the code

Simple enough, android HD screen doesn’t exist, but it doesn’t really matter, just 1px lines on Android screen

If you want to be responsive as well as adaptive, you need to set them one by one as you did with the fonts above, because CSS media queries are also for layout viewport sizes. For Taobao, they must have a set of engineering solutions to solve this technical problem, for the pit of the partners estimated have to think of their own, the preprocessor is essential. It can be seen from the above that Taobao introduced DPR not to make adaptive, but to solve the 1px problem. Of course, other difficulties were also introduced. In this case, it would be much simpler to give up solving the 1px problem.

3. Netease Solution

Removed boundary handling and compatibility handling, introduced in head because meta is not set dynamically

 <meta name="viewport" content="Width =device-width, user-Scalable =no, initial scale=1.0, maximum-scale=1.0, Minimum-scale =1.0">
Copy the code
 (function () {
    var dpr = window.devicePixelRatio;
    function resize() { var deviceWidth = document.documentElement.clientWidth; Document. The documentElement. Style. FontSize = (deviceWidth / 6.4) +'px'; } resize(); window.onresize = resize; }) ()Copy the code

Netease’s solution does not introduce anything related to DPR, which also shows that mobile terminal adaptive has nothing to do with DPR

200px: 640px => xREM: 6.4rem

x= 2rem

Flow: REM => Size of root element => Layout viewport

Since the adaptation has nothing to do with DPR, it can be extended to many scenarios

4. Other options

1. When the layout viewport equals the device width, bind the root element font size directly to the device width size

Document. The documentElement. Style. FontSize = (screen. Width / 6.4) +'px';
Copy the code

The related article here is based on the pseudo-responsive development of screen.width

2. Direct fixed layout viewport

<! DOCTYPE html> <html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <meta name="viewport" content="width=640, user-scalable=no""> <meta name="renderer" content="webkit"> < span style> HTML, body {margin: 0} div {width: 200px; height: 200px; background: red; } body { background: blue; } </style> <script> </script> </head> <body> <div id="size200px"</div> </body> </ HTML >Copy the code

Width =device.width =device.width =device.width =device.width =device. The initial scale is used to scale the layout viewport size, and the default is that the layout viewport initial size is equal to the device width, which is called the ideal viewport. In other words, if you set the initial scale, you don’t have to set it Width =device.width =device. Width =device. Width =device. Width =device. If you don’t understand what a viewport does, you can refer to the relationship between viewport and viewBox in SVG. The principle is the same.

3. Use the new unit vw, vw is specially for adaptive, 100VW is the layout viewport width, very impressive, you do not need to set js

200px: 640px => xvw : 100vw

X is equal to 200 times 100/640, which is 31.25vw

Flow: VW => Layout viewport

Look at compatibility

Compatible can also, here is also the relevant data sharing hand tao Chinese New Year project used to the front-end technology

conclusion

Mobile device size adaptation has nothing to do with DPR. Except taobao solution, all other solutions have to deal with the 1px problem, but it also reduces the trouble of responding to different DPR devices, and none of them can solve all the problems. And as a new unit, VW, it’s time to go into the pit

Refer to the article

1. Zhang Xinxu [based on the screen. The width of the pseudo responsive development] (https://www.zhangxinxu.com/wordpress/2016/06/pseudo-response-layout-base-on-screen-width/) 2. Desert [share in hand for Chinese New Year projects adopt to the front-end technology] (https://www.w3cplus.com/css/taobao-2018-year.html). 3. [fleible](https://github.com/huainanhai/flexible/blob/master/public/js/frame/flexible.debug.js) 4. Zhang xinxu [a brief introduction to the devicePixelRatio]Copy the code