preface

Since the development of mobile Internet, suited for various mobile devices, but their physical resolution is multifarious, in general, the UI will provide us with 375 the size of the design draft, so in order to let the H5 to create pages on these different equipment has the same performance as far as possible, front end engineers are going to have to mobile terminal adapter was carried out on the page.

“If this article is helpful to you, ❤️ follow + like ❤️ to encourage the author, the article’s public account launch, followThe front nine southThe first time to get the latest articles ~”

Front knowledge

Before learning mobile adaptation, we need to understand some relevant pre-knowledge.

The screen size

Screen size is measured in inches by the diagonal length of the screen. 1 inch =2.54 cm

Electronic devices usually describe the physical size of a screen in inches, such as 22 or 27 inches on our computers. “Inch” (abbreviated to “in”) means “thumb” in Dutch, and an inch is the width of an average person’s thumb.

Pixels pixel

In terms of computer technology, a pixel is the smallest unit that hardware and software can control. It refers to the smallest unit on the screen, not the smallest unit on the picture. An image typically contains thousands of pixels, each with its own color information, packed tightly together. A pixel is a dot, or a tiny square.

Screen resolution

Screen resolution refers to how many pixels a screen is made up of. The unit is px.

We can see that there are two types of pixels in the figure above: logical and physical, and they are not the same in value. Also, the resolution of the typical UI design is not the same as that of the real model.

Physical pixels (device pixels)

On the same device, its physical pixels are fixed, which is the actual number of points decided by the manufacturer when producing display devices. The size of physical pixels is different for different devices. (The minimum unit that the device controls the display, 1920*1080 pixel resolution, is the physical pixel unit used.)

This can cause problems if all physical pixels are used: For example, a 21-inch monitor has a resolution of 1440×1080, and a 5.8-inch iPhone X has a resolution of 2436×1125. Let’s draw a line with CSS with a length of 20px. If both are measured in physical pixels, it will look fine on the display. On the iPhone X screen, it becomes very small.

Logical pixels (device-independent pixels)

Apple introduced the concept of Retina Display for the first time at the launch of the iPhone4. In the Retina Display used by the iPhone4, four pixels are used as one pixel, which makes the screen look more refined. In addition, in different screens, The same logical pixels render the same size. So high resolution devices, one more logical pixel. As you can see from the first figure, the logical pixels are still different on different devices, but not as different as the physical ones, which brings up the issue of mobile pages needing to be adapted. (Device-independent logical pixels, representing virtual pixels that can be used programmatically)

Ppi per pixel inch

Pixel per inch (PPI) indicates the number of pixels per inch, and the higher the number, the higher the screen density.

PPI=√ (X^2+Y^2)/Z (X: length pixels; Y: number of pixels of width; Z: Screen size)

Phones with ppi between 120 and 160 are classified as low density, 160 to 240 as medium density, 240 to 320 as high density, and above 320 as ultra high density

Device pixel ratio DPR

Device PixelRatio (DPR) refers to the pixel ratio of the device. Device pixel/device independent pixel represents the conversion relationship between device independent pixels and device pixels, which can be obtained from window.devicePixelRatio in JS

The calculation formula is DPR = physical pixel/logical pixel

When the pixel ratio of the device is 1:1, use 1 (1 x 1) device pixels to display one CSS pixel.

When the device pixel ratio is 2:1, use 4 (2 x 2) device pixels to display one CSS pixel.

When the device pixel ratio is 3:1, use 9 (3 x 3) device pixels to display 1 CSS pixel.

Conceptual diagram

Screen size, screen resolution > diagonal resolution/screen size — – > screen pixel density PPI | equipment pixels than the DPR = physical pixel/independent pixel dip (dp) | viewport: scale | CSS pixel px

Viewport viewport

Viewport refers to the viewport, which is the area of the browser or app where the WebView displays the page. Generally speaking, the PC viewport refers to the browser window area, while the mobile port is a bit more complicated and has three viewports:

  • Layout ViewPort: Layout viewport
  • Visual ViewPort: visual viewport
  • Ideal viewport

Layout ViewPort

It is a virtual layout viewport proposed by browsers to solve the problem of page display on mobile phones. This viewport can be changed by setting the viewport with the
tag. Browsers on mobile devices will set their default viewPort to 980px or 1024px (or any other value, depending on the device), but the result will be a horizontal scroll bar because the width of the browser’s viewport is smaller than the default viewPort width.

We can through the document. The documentElement. ClientWidth viewport size for layout

Visual ViewPort

It refers to the viewable area of the browser, which is what we see on mobile devices. The default is the same size as the current browser window. When the user zooms the browser, it does not change the size of the layout viewport, but it does change the size of the visual window.

We can get the visual viewport size using window.innerWidth.

Ideal Viewport

The ideal viewport. The idea, first introduced by Apple and followed by other browser vendors, was to solve the problem of page elements being too small under the layout viewport, so that pages displayed in the ideal viewport would have the optimal width without the user having to zoom in and out. The so-called ideal viewport means that the page drawing area can be perfectly adapted to the viewport size of the width of the device, and all the content of the website can be viewed normally without the need for a scroll bar, and the text and pictures are clear. For example, the ideal viewport width of all iphones is 320px, and the ideal viewport of Android devices is 320px and 360px, etc.

Ideal viewport = visual viewport when page scaling is 100%.

We can use screen.width to get the ideal viewport size.

meta viewport

For mobile pages, you can use
tags to configure viewport size, zoom, etc.

<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = no" />
Copy the code
  • width: This property is used to control the width of the window. It can be set to an exact number of pixels, such as 320, or to a keyword such as device-width, which indicates the actual width of the device. It is common to set width to adaptive layoutdevice-width.
  • height: This property is used to control the height of the viewport. The height can be set to 640, the exact number of pixels, or todevice-heightThis keyword indicates the actual height of the device. The height of the window is generally not set, so that the content is exceeded by scrolling.
  • initial-scale: This property is used to specify the initial scale of the page and can be configured0.0 ~ 10The Numbers,Initial-scale =1 means no scaling and the window is exactly equal to the ideal window, when the value is greater than 1, the window is enlarged; when the value is less than 1, the window is shrunk. This represents only the initial window zoom value. The user can also zoom in by dragging the gesture with two fingers to zoom in or double-clicking the gesture to zoom in.Default initial-scale on Android devices:There is no default value, it must be set for this property to take effect. On the iPhone and iPad, no matter how wide you make the viewPort, ifNo default scaling value is specified, the iPhone and iPad willAutomatically calculates the scale valueSo that the current page does not have a horizontal scroll bar (or the width of the viewport is the width of the screen).
  • maximum-scale: Indicates the maximum scale that the user can manually zoom in0.0 ~ 10The Numbers.
  • Minimum-scale: This property is similar to maximum-scale and is used to specify the minimum percentage of page reduction. Typically, no value is defined for this property, and the page is too small to navigate.
  • user-scalable: Indicates whether to allow users to manually zoom in and out. It can be configuredNo or yes. When set to no, users will not be able to scale the page using gestures.

It is important to note that viewPort is only valid for mobile browsers, not PC browsers.

Adaptation and scaling

In order to make the mobile page look good, we must make the layout viewport and the visual viewport equal to the ideal viewport as much as possible, so we usually set width=device-width, which equals the layout viewport to the ideal viewport; Setting initial-scale=1.0 is equivalent to making the visual port equal to the ideal viewport;

As mentioned above, width can determine the width of the layout viewport. In fact, it is not the only determinant of the layout viewport. Setting initial-scale can also affect the layout viewport, because the layout viewport width takes the maximum width and viewport width.

Such as: If the ideal viewport width is 400px, set width=device-width, initial-scale=2. Set the layout viewport to a device-width of 400px.

If width=device-width and initial-scale=0.5, then the visual viewport width= ideal viewport width/initial-scale is 800px, and the layout viewport is 800px.

Mobile terminal adaptation scheme

When we do H5 mobile development, the most used unit is PX, also known as CSS pixel. When the page zoom ratio is 1:1, a CSS pixel is equal to a device independent pixel. But CSS pixels can be easily changed. For example, when a user enlarges a page, CSS pixels will be enlarged, and the CSS pixels will span more device pixels.

Page scaling factor = CSS pixels/device-independent pixels

Rem adaptation

Rem (font size of the root Element) is a new relative unit of CSS3, which refers to the font size relative to the root element.

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, user - scalable = no" />
    <title>Document</title>
    <style>* {margin:0;padding:0}
        .box{
            width: 10rem;
            height: 4rem;
            background-color: antiquewhite;
            font-size: 0.53 rem; /* 20px*/
        }
    </style>
    <script>
        function setRootRem() {
            const root = document.documentElement;
            /** take iPhone6 as an example: the layout viewport is 375px, we divide it into 10 parts, 1rem = 37.5px, * the UI is given a width of 375px (device-independent pixels), * we just need to set it to 375/37.5 = 10rem. * /
            const scale = root.clientWidth / 10
            root.style.fontSize = scale + 'px'  
        }
        setRootRem()
        window.addEventListener('resize', setRootRem)
    </script>
</head>
<body>
    <div class="box">The front nine south</div>
</body>
</html>
Copy the code

Ok, here we can see that when we select different devices for testing, the font size of the root node will change with the width of the device layout viewport, so the element width of 10rem is always equal to the width of the current layout viewport, and the font size will also change with the device. This is called mobile terminal adaptation. In fact, flexible, an open source mobile terminal adaptation solution first proposed by Ali, has a very simple principle.

For example, if the font size of the design is 20px, we need to calculate the corresponding REM value. According to our rules, 1px = 1/37.5 REM. So 20px should correspond to 20/37.5 = 0.53rem. So this is a solution we usually use with CSS preprocessors. For those of you who are not familiar with CSS preprocessors, I recommend reading my previous article: When it comes to CSS preprocessors, do you only use nesting?

Rem is used with CSS preprocessors

Here I will use vue+less to simple operation, specific can be encapsulated to the bottom layer, here to demonstrate the principle.

I recommend using my own scaffolding (SongYao – CLI) to quickly generate a VUE project. After installing the dependencies, start configuring less.

/*rem.less*/
@device-width: 375; /* Device layout viewport */
@rem: (@device-width/10rem);
Copy the code

Then configure @rem as the less global variable

//vue.config.js
module.exports = {
    css: {
        loaderOptions: {less: {
                additionalData: ` @import '~@/static/rem.less'; `}}}}Copy the code

Configure the method of calculating REM in the entry file of vUE

// toRem.js
export default function() {
    const root = document.documentElement;
    /** take iPhone6 as an example: the layout viewport is 375px, we divide it into 10 parts, 1rem = 37.5px, * the UI is given a width of 375px (device-independent pixels), * we just need to set it to 375/37.5 = 10rem. * /
    const scale = root.clientWidth / 10
    root.style.fontSize = scale + 'px'  
}


//main.js
import Vue from 'vue'
import App from './App.vue'
import toRem from "./utils/toRem" //
toRem()
window.addEventListener('resize', toRem)
Vue.config.productionTip = false

new Vue({
  render: h= > h(App),
}).$mount('#app')

Copy the code

You can then use the global @rem variable in VUE for mobile development

<template> <div class="songyao"> <h1>{{username}}</h1> <p> Check out the <a Href = "http://47.100.126.169/zmengBlog" target = "_blank" rel = "noopener" > dream blog < / a > < / p > < p > WeChat public no. : <span class="wx_name"> <span ></p> </div> </template> <script> export default {name: 'songyao', data() { return { username: 'songyao-cli(vue template)'}},} </script> <style lang="less">. } p{ font-size: (16/@rem); } .wx_name{ color:brown; } } </style>Copy the code

However, the above scheme is a transitional scheme, viewPort is a scheme proposed by Apple, before the major browsers on its compatibility is not very good, which has this REM adaptation scheme.

There is such a sentence in flexible Document of Ali open source library:

Since viewPort units are compatible with many browsers, lib-flexible is a transition solution that can be abandoned, and there are problems with both current and previous versions. It is recommended that you start using viewPort instead.

Yes, it’s slowly being abandoned, but many companies still use it.

Vw and VH fit

Vw (Viewport Width) and VH (Viewport Height) are viewwindow-based units proposed in CSS3.

Vh and VW schemes divide the visual viewport width window.innerWidth and visual viewport height window.innerHeight into 100 portions.

The flexible solution above mimics this solution, as vw was not well compatible earlier.

  • vw(Viewport's width):1vwEqual to the visual viewport1%
  • vh(Viewport's height) :1vhFor the height of the visual port1%
  • vmin : vwvhThe smaller value of
  • vmaxSelection:vwvhGreater value of

If the visual port is 375px, 1vw = 3.75px, and the UI is given an element 75px wide (device-independent pixels), we just need to set it to 75/3.75 = 20vw.

Here we can also use less to achieve, do not have to manually calculate, calculate the process we give less good, we directly in accordance with the design draft to develop on the line

// rem.less again we add a @vw variable
@device-width: 375;
@rem: (@device-width/10rem);
@vw: (100vw/@device-width);
Copy the code
<template> <div class="songyao"> <h1>{{username}}</h1> <p> Check out the <a Href = "http://47.100.126.169/zmengBlog" target = "_blank" rel = "noopener" > dream blog < / a > < / p > < p > WeChat public no. : <span class="wx_name"> <span ></p> </div> </template> <script> export default {name: 'songyao', data() { return { username: </script> <style lang="less">. Songyao {h1{// font-size: (24/@rem); font-size: 24*@vw; } p{ // font-size: (16/@rem); font-size: 16*@vw; } .wx_name{ color:brown; } } </style>Copy the code

viewport+PX

OK, let’s talk about a viewport solution recommended by the Flexible team. This scheme allows us to develop directly according to the notes on the design draft without paying attention to the difference in screen size of the device, and use PX directly without converting units.

Add
to the HTML head tag.

If the UI gives us a design with a width of 375px, we need to set the width of the viewport of the page to 375, and then scale the entire page according to the logical pixels of the device.

export function initViewport() {
    const width = 375;  // Width of design draft
    const scale = window.innerWidth / width
    // console.log('scale', scale)
    let meta = document.querySelector('meta[name=viewport]')
    let content = `width=${width}, init-scale=${scale}, user-scalable=no`
    if(! meta) { meta =document.createElement('meta')
        meta.setAttribute('name'.'viewport')
        document.head.appendChild(meta)
    }
    meta.setAttribute('content', content)
}
Copy the code
<template> <div class="songyao"> <h1 class="name_rem">{{ username }}</h1> <h1 class="name_vw">{{ username }}</h1> <h1 Class = "name_px" > {{username}} < / h1 > < p > understand scaffolding and scaffolding instruction please click personal blog < br > check out the < a href = "http://47.100.126.169/zmengBlog" Target = "_blank" rel = "noopener" > dream blog < / a > < / p > < p > WeChat public no. : <span class="wx_name"> <span ></p> </div> </template> <script> export default {name: 'songyao', data() { return { username: </script> <style lang="less">. Songyao {p{// font-size: (16/@rem); font-size: 16*@vw; } .name_rem{ font-size: (24/@rem); } .name_vw{ font-size: 24*@vw; } .name_px{ font-size: 24px; } .wx_name{ color:brown; } } </style>Copy the code

Here we put the three schemes together and compare them. They all correspond to 24px on the 375 design draft. The three schemes are basically the same.

conclusion

At present, these three schemes are the most commonly used schemes, and they all have their own advantages and disadvantages.

Rem solution

  • The adaptation principle is slightly complicated
  • You need JS
  • It is easy to calculate the conversion from PX to CSS REM
  • The scheme is flexible, which can realize both the whole scale and the local no scale

Vw plans

  • Simple adaptation principle
  • JS is not required for adaptation
  • The calculation of converting px marked in the design draft to VW of CSS is complicated
  • The scheme is flexible, which can realize both the whole scale and the local no scale

Viewport + px project

  • Simple adaptation principle
  • You need JS
  • Use design notes directly without conversion
  • The scheme is rigid and can only achieve page level limb scaling

Recommended reading

  • Performance optimized HTML, CSS, JS loading order
  • HTTP history, the difference between HTTP1.1 and HTTP2.0
  • Super comprehensive summary of Vue interview knowledge points, help golden three silver four
  • Common front-end sorting algorithms
  • A few tips for CSS performance optimization
  • Common front-end security problems and preventive measures
  • Why are big factories using GIF as a burying point?
  • Don’t just know about KFC, you should know about BFC, IFC, GFC and FFC

The original address point here, welcome everyone to pay attention to the public number “front-end South Jiu”, if you want to enter the front-end exchange group to learn together, please click here

I’m Nan Jiu, and we’ll see you next time!!