Recently in refactoring a mobile terminal project, in addition to the construction of the new project for front-end technology stack, also an important question to consider is the mobile terminal adapter, about the understanding of the mobile terminal adapter I has always been a relatively dim state before I don’t know why (learning), so has recently made a further study, In this blog post, I talk about my understanding of mobile adaptation.

In this blog post, I will first explain some basic concepts of mobile devices, including device independent pixels, device pixel ratio and viewport, then further explain mobile adaptation based on this, and finally explore mobile adaptation solutions.

Device Independent pixel (DIP), Device Pixel ratio (DPR)

Let’s start with a look at the various concepts in mobile devices:

  • Device pixel: physical pixel, refers to the smallest unit of display that the device can control, namely pixels on the display screen.
  • Screen size: The diagonal length of the screen, in inches (1 inch = 2.54 cm).
  • Screen resolution: refers to the number of physical pixels on the mobile phone screen, generally expressed as “vertical physical pixel points * horizontal physical pixel points”. For example, the iPhone 6 has a screen resolution of 1334 x 750.
  • Screen pixel density (DPI/PPI) : Refers to the number of physical pixels per inch on a phone’s screen. The value is related to screen resolution and screen size, and is calculated as follows: DPI = √(vertical physical pixel points ² + horizontal physical pixel points ²)/screen size.

Device-independent pixel (DIP), also known as logical pixel, density independent pixel, refers to a device-independent unit used to measure a pixel logically.

Device pixel ratio (DPR) refers to the ratio of physical pixels to device-independent pixels. DevicePixelRatio is read-only, but not constant, and some operations on the browser will change the value.

So how do you figure out the device pixel ratio for each mobile device?

The device pixel ratio is related to the pixel density of the mobile device’s screen. In general, the device pixel ratio is an integer multiple of the screen pixel density divided by 160, i.e. DPR = math.floor (dPI / 160) = math.floor (√(vertical physical pixel count ²+ horizontal physical pixel count ²)/screen size / 160).

Math.floor(√(1334²+750²) / 4.7/160) = 2. If the iPhone 6 measures 4.7 inches and the screen resolution is 1334 * 750, the device pixel ratio for the iPhone 6 is: math.floor (√(1334²+750²) / 4.7/160) = 2.

As mentioned above, device pixel ratio refers to the ratio of physical pixels to device-independent pixels. Therefore, after knowing the device pixel ratio of a mobile device, we can get device-independent pixels of the mobile device, that is, device-independent pixels = physical pixels/device pixel ratio.

If the horizontal resolution of the iPhone 6 is 750 and the device pixel ratio is 2, the logical width of the iPhone 6 (the width of the mobile device measured in device-specific pixels) is 375px.

viewport

Viewprot refers to a virtual window in a mobile device browser that holds a page, which can be larger or smaller than the mobile device’s viewable area.

By default, the viewProt is larger than the viewport on mobile devices, so that the layout of the page is not optimized for mobile devices. Users can pan and zoom to see other parts of the page. The default viewPort on most mobile devices is 980px (the px here refers to device-specific pixels).

When refactoring a mobile page, we often add the following code:

<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = no"/>
Copy the code

This code sets the viewPort of the mobile device to the logical width of the device, with an initial zoom value of 1 and a maximum zoom value of 1, and does not allow the user to zoom.

Let’s look at the properties in viewPort:

When we set width in viewPort to width-device, the viewport width is equal to the logical width of the mobile device, and setting initial-scale to 1 gives the same result. Typically we set both properties at the same time, and when the two properties have different effects due to different values, the browser takes the larger of the two.

Here’s an example to help you understand the viewPort property:

<style>
html,body{
  margin:0;
  padding:0;
}
.box{
  width:100px;
  height:100px;
  background:blue;
}
</style>

<div class="box"></div>
Copy the code

The iPhone 6 debugs in Chrome as follows:

As you can see, the default viewPort on iPhone 6, without the viewPort attribute, is 980px. As mentioned earlier, this is measured in device-specific pixels, which is the same as the px we normally write in our style code. The code defines a blue block that is 100px wide and 100px high, so when viewed horizontally, the blue block takes up 100/980 of the screen, as shown in the figure below.

If we set the viewPort property:

<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = no"/>
Copy the code

The effect is as follows:

In iPhone 6, the device-width value is 375px, so in landscape view, the viewport of the mobile device is set to device-width. Blue blocks make up 100/375 of the screen, as shown.

In-depth understanding of mobile adaptation

Now that we’ve understood the concepts of device independent pixels, device pixel ratio, and viewport, to understand mobile adaptation in depth, we need to understand what device pixel ratio does.

Here’s the easiest example to understand. The iPhone 3 and the iPhone 4 have the same screen size, but the iPhone 3 has a 480 x 320 screen resolution and the iPhone 4 has a 960 x 640 screen resolution, The iPhone 4 has twice the horizontal and vertical resolution of the iPhone 3.

Assuming that the iPhone 3 and iPhone 4 both have a pixel ratio of 1, the logical widths of these devices are 320px and 640px, respectively. From the viewPort example, If the blue block has a width ratio of 100/320 in iPhone 3 and 100/640 in iPhone 4, we can see that the same code looks very different on different mobile devices.

In fact, the iPhone 3 device has a pixel ratio of 1 and the iPhone 4 device has a pixel ratio of 2, so we can see that they are both logically 320px wide, so the blue block is actually the same size on the two different mobile devices.

So we can conclude that using px units, the same style of code appears almost the same on mobile devices with different screen resolutions (note that this is basically not exactly the same) because the device pixel ratio on mobile devices converts device independent pixels.

Why is it that the display is almost the same on mobile devices with different resolutions, but not exactly the same? Because there are many mobile devices with different screen resolutions, not all of them have the same logical width.

For example, iPhone 6 has a resolution of 1334 * 750, and the device pixel ratio is 2, so its logical width is 375px, and the blue block ratio is 100/375 with the viewPort attribute. You can see that the blue portion of the screen is not the same as the iPhone 3 or iPhone 4.

Therefore, we can know that the device pixel ratio helps us to carry out mobile end adaptation to a certain extent. In fact, there are other solutions we need to adapt to mobile. The fundamental reason we need mobile adaptation is that there are many mobile devices with different logical widths

One of our ultimate goals for mobile adaptation is to make it roughly the same proportion on different mobile devices (in the case of the above example, the blue block is the same proportion on different mobile devices).

Mobile adaptation solutions

Finally, it is to explore solutions for mobile adaptation. Here I would like to give a call to the blog post “Thinking about front-end design draft and workflow from font size of NetEase and Taobao”, which is really good. In this blog, the mobile terminal adaptation solutions of Pull check, NetEase and Taobao are introduced respectively. Pull check ADAPTS mobile devices with different resolutions to a certain extent by setting the percentage of styles, which is suitable for simple projects. NetEase and Taobao use a well-known scheme, rem adaptation.

Comparatively speaking, I think NetEase’s scheme is easier to understand and practice, so I also refer to NetEase’s scheme to achieve mobile terminal adaptation in my project. For Taobao’s mobile adaptation scheme, it is more sophisticated, interested in children’s shoes can read their own understanding oh.

So, what is REM? Rem (font size of the root Element) means setting the font size according to the font size of the root element. Like PX, it is a CSS style unit that will be converted to PX units based on the font-size value of the root element, using the formula px = rem * HTML (font-size).

html{
  font-size:10px;
}
div{
  width:2rem;  // 2*10=20px
}
Copy the code

Therefore, the core idea of mobile adaptation is to use REM as the style unit and set the font size value of the root element according to mobile devices with different resolutions.

How do you properly set the font size of the root element?

Taking the iPhone 6 design as the benchmark, i.e. the horizontal resolution of the design is 750, and taking 100 as the reference number (i.e. the multiple of 100 between rem and PX), we can know that the width of the HTML is 7.5rem (750/100). We know that the logical width of the iPhone 6 is 375px, so the width of the HTML is 375px, so 7.5rem * HTML = 375px, HTML (font-size) = deviceWidth / 7.5.

Set the font size of the root element with js

var deviceWidth = document.documentElement.clientWidth; Document. The documentElement. Style. FontSize = deviceWidth + / 7.5'px';
Copy the code

One prerequisite, of course, is to set the viewProt width to the logical width of the mobile device

<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = no"/>
Copy the code

When deviceWidth is greater than 750px, we should visit the PC version of the page, so when deviceWidth is greater than 750px, we should not change the font size value of the root element. The complete code is as follows

var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 750) deviceWidth = 750; Document. The documentElement. Style. FontSize = deviceWidth + / 7.5'px';
Copy the code

In order to make our writing style more consistent with the size of the design draft, we can use sass function to set a conversion function between PX and REM

@function pxToRem($num) {@return ($num/100) * 1rem;
}
Copy the code

When we have a design element that is 100px wide and 100px high, we can write it like this

div{
  width:pxToRem(100);
  height:pxToRem(100);
}
Copy the code

It is also important to note that in order for fonts to look comfortable on mobile devices with different resolutions, they should not be rem sized, but px sized.

Finally, summarize the mobile adaptation solution I used in the project:

  • Set the viewPort width to the mobile device logical width;
  • Js is used to set the font size value of the root element according to different resolutions of mobile devices. Note the critical value of mobile and PC terminals.
  • Use px units for fonts in styles and REM units for other elements.
  • Use function in sass to set a conversion function between PX and REM;