What you need to know about mobile adaptation – This article summarizes mobile adaptation very well, but it is not easy to understand the content of viewport, so I add my personal understanding and practice

Mobile adaptation, we often encounter in the development, which may encounter a lot of problems:

  • 1pxThe problem
  • UIFigure perfect fit scheme
  • iPhoneXAdaptation scheme
  • Landscape adaptation
  • The hd screen picture is blurred
  • .

We may already know how to solve the above problems in development, but the principle of the problem, and the principle of the solution may be unclear. In the process of solving these problems, we tend to encounter many concepts: pixel, resolution, PPI, DPI, DP, DIP, DPR, viewports, etc.

inches

The physical size of the screen is usually described in inches, such as 17 and 22 for computer monitors and 4.8 and 5.7 for mobile phones.

Note that the dimensions above are the diagonal length of the screen:

“Inch” (abbreviated to “in”) means “thumb” in Dutch, and an inch is the width of the average person’s thumb at the bottom of a fingernail.

Inches and centimeters: 1 inch = 2.54 centimeters

The resolution of the

There are usually two kinds of resolution, screen resolution and image resolution, which are made up of pixels.

pixel

A pixel, a small square, has two properties: position and color. Electronic screens (cell phones, computers) are made up of squares with specific positions and colors.

Pixels can be used as the smallest component of an image or electronic screen. Here we open an image using Sketch:

Zoom in to see these pixels:

Screen resolution

Screen resolution refers to how many pixels a screen consists of. Here’s what Apple’s website says about the phone’s resolution:

The iPhone XS Max and iPhone SE have resolutions of 2688 x 1242 and 1136 x 640, respectively. This represents the number of pixels the phone has vertically and horizontally.

Of course, high resolution does not mean that the screen is clear. The clarity of the screen is also related to size (the inches above), which is derived from PPI and DPI.

Image resolution

We usually refer to the image resolution actually refers to the number of pixels in the image, for example, a picture resolution of 800 x 400. This means that the image has 800 pixels vertically and 400 pixels horizontally, respectively.

The higher the resolution, the clearer the picture is of the same size.

Pixel density PPI

PPI (Pixel Per Inch) : The number of pixels Per Inch used to describe the sharpness of a screen and the quality of an image.

  1. When using PPI description [image], the higher the PPI, the higher the picture quality, and when using PPI description screen, the higher the PPI, the clearer the screen.

  2. Using PPI to describe the screen, we can see that the iPhone XS Max has a PPI of 458 and the iPhone SE has a PPI of 326, which is enough to justify the sharper screen of the former.

As the phone size is the diagonal length of the phone, we usually use the following method to calculate PPI:


Horizontal pixel The number 2 + Vertical pixel The number 2 Diagonal inches \frac{\ SQRT {horizontal pixels ^2+ vertical pixels ^2}}{diagonal inches}

For example, the PPI of the iPhone 6 is 326 pixels.

Print density DPI

DPI (Dot Per Inch) : Refers to the number of dots Per Inch, which is the number of dots Per Inch on a printer. DPI refers to the number of dots Per Inch on a printer.

When a picture is displayed on the screen, its pixel count is arranged in a regular way, with each pixel having a specific position and color.

When using a printer to print, the printer may not print out the dots regularly, but use one print point after another to present the image. There will be a certain gap between the print points, which is described by DPI: the density of print points.

In the image above we can clearly see how the printer uses ink dots to print an image. Therefore, the higher the PRINTER’s DPI, the higher the precision of the printed image, which also consumes more ink spots and time.

Equipment pixel

Device physical pixels

In fact, the pixels we described above are all physical pixels, the actual physical light emitting units on the device, also known as device physical pixels. Device Independent Pixels (DIP)

Device independent pixel DIP

Smart phones are developing very fast. Until a few years ago, we still had very low resolution phones. For example, the white phone on the left below has a resolution of 320×480 (physical pixels of the device), on which we could browse normal text, pictures, etc.

However, with the development of technology, low-resolution mobile phones can no longer meet our needs. Soon, higher-resolution screens were created, such as the black phone below, which has a resolution of 640×940 (physical pixels of the device), exactly double that of the white phone.

In theory, images and text of the same size on a white phone will be zoomed twice as large on a black phone because it has twice as much resolution. With higher resolution phones, page elements will get smaller and smaller.

However, that’s not the case. Smartphones that we use today, no matter how high the resolution, display similar interface proportions. The Retina Display, which jobs first introduced at the launch of the iPhone4, solves this problem and makes it a generational phone.

In the retina screen used on the iPhone4, the 2×2 pixels are used as one pixel to make the screen look more refined, but the size of the elements does not change.

If the black phone uses retina screen technology, the result would be something like this: if the list is 300 pixels wide, on a horizontal line, the white phone would render it with 300 physical pixels, while the black phone would actually render it with 600 physical pixels.

We have to use a unit to tell phones of different resolutions simultaneously what size elements they display on the screen — Device Independent Pixels, or DIP, or DP. Above we said that the list is 300 pixels wide. In fact we can say that the list is 300 device-independent pixels wide.

The design side likes to call DIP the device logical pixel, which means the same thing, to distinguish the device physical pixel

Open chrome’s Developer tools, and you can simulate the display of each phone model. Each model will display one size. For example, the iPhone X will display 375×812.

Device pixel ratio DPR

Device Pixel Ratio (DPR) is the Ratio of physical pixels to independent pixels of the Device.

  1. On the Web, the browser provides us with window.devicePixelRatio to help us get the DPR.

  2. In the CSS, you can use media to query min-device-Pixel-ratio to distinguish DPR:

    @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){ }
    Copy the code
  3. In React Native, we can also use PixelRatio. Get () to get the DPR.

Of course, there are exceptions to the above rule, and the iPhone 6, 7, and 8 Plus actually have 1080 x 1920 physical pixels, which can be seen in the developer tools: Its device-independent pixels are 414 x 736, and the device pixel ratio is 3. The product of device-independent pixels and the device physical pixel ratio is not 1080 x 1920, but 1242 x 2208.

In fact, the phone will automatically render by squeezing 1242 x 2208 pixels into 1080 x 1920 physical pixels, which we don’t care about. 1242 x 2208 is called the design pixel of the screen. Our development process is based on this design pixel.

In fact, device pixel ratio didn’t exist until Apple introduced retina screens, because until then, mobile devices used physical pixels directly for display.

Next, Android uses other technical solutions to achieve screens with a DPR greater than 1, but the principle is similar. Because Android has so many screen sizes and a wide range of resolutions, unlike Apple, which only has its own set of devices and sizes. Therefore, to ensure the display effect of various devices, Android divides devices into several sections according to their pixel density:

Of course, all Android devices may not strictly follow the above resolution, each type may correspond to several different resolutions, so each Android phone can determine its OWN DPR based on a given range and thus have a similar display. Of course, only similar, due to the differences in size and resolution of each device, device independent pixel will not be completely equal, so various Android devices still can not be completely equal in display.

CSS pixel unit: PX

CSS pixels are virtual pixels that can be understood as “intuitive” pixels that can be larger or smaller with device-independent pixel and zoom behavior. All lengths in the browser are measured in CSS pixels, which are px.

In the CSS specification, units of length can be divided into two categories: absolute and relative. Px is a relative unit, 1 px is a physical pixel of the device.

In the previous section, we learned that in mobile browsers and some desktop browsers, the Window object has a Device Pixel Ratio (DPR) property, which is officially defined as the Ratio of the Device’s physical pixels to device-independent pixels. We can derive the following formula:

  1. DPR (device pixel ratio) = device physical pixels/DIP (device independent pixels)And px is relative to the physical pixel of the device, so the formula can also beDPR = PX / DIP
  2. inNo browser zoom or zoom to 100%Cases:PX = DIP * DPRWhen the DPR of a device is 2, for example, in width, we all know that the physical pixel of iphone6 device is 750px, the independent pixel of the device is 375px, and the pixel ratio of the device is 2, which are fixed by the manufacturer. So according to the formula on iphone61 PX = 2 device-independent pixel units. The iphoneX, on the other hand, just looks at the device’s pixel ratio1 PX = 3 device-independent pixel units, so it can be seen that CSS pixel unit PX changes dynamically on the mobile terminal.It is also such a set of CSS code to achieve the same size phone, different screen resolutions, display the same effect.

    For example, an icon icon on iphone6, the designer may deliver two different UI design draft, want to display the correct effect:

    1. If the total width of the design submitted by the designer is 750px, then the device [physical pixels] standard will be used. The size of the icon in the design is 32px, so we have to divide the CSS by 2 = 16px.

    2. If the total width of the design is 375px, then the device will be standard. The size of the icon in the design draft should be 16px. When we write the units of CSS, we write 16px directly. The designer helped us to convert the pixel ratio.

Display zoom behavior

In addition to the fixed device-independent pixels, there is also a very, very important factor in how an interface looks, which is user manipulation or automatic display scaling.

System and page zooming

There are three types of display zoom behaviors:

  1. Apple’s unique [RetinaScaling, which brings the concept of device-independent pixels, can be understood as “a unique operating system layer”.The zoom“】
    • What is scaled is the device physical pixel.
    • Effect: Control multiple device physical pixels to merge into one [device independent pixel]
    • Feature: Users do not need to operate the system
  2. In the operating systemSystem display zoom], the user can operate the zoom behavior, similar to Retina effect.
    • What is scaled is the device physical pixel.
    • Effect: Control multiple device physical pixels to merge into one [device independent pixel]
    • Features: Manual setting is required on the desktop system. Zooming is not enabled by default. Zooming is enabled on the bottom of the mobile system
  3. Internal window of the browserPage display zoom】,
    • The scaled CSS pixel is a virtual pixel in PX
    • Effect: Controls how many device-independent pixels CSS pixels occupy
    • Features: As the user zooms in and out, the span of CSS pixels occupied by the device changes at any time. The system then displays the zoom and then translates down to how many physical pixels occupied by the device. Another way to understand is that the page display scaling is based on the system display scaling.

CSS Pixel scaling

CSS pixels are visually easy to resize. When zooming in and out of a browser page, they are the changed CSS pixels. When zooming in, one CSS pixel covers two device-independent pixels horizontally or vertically. For example, if the width of the page is 100px, when the page is doubled in size, it will occupy 200 device pixels instead of 100. If scaled down, the opposite is true, occupying only 50 device-independent pixels.

Illustration:

  1. Device independent pixels (dark blue background), CSS pixels (translucent background).
  2. The image on the left shows multiple CSS pixels covered by a single device pixel when the user zoomed out.
  3. The image on the right shows a SINGLE CSS pixel covering multiple device-independent pixels when the user zoomed in.

Whether CSS pixels are scaled down or enlarged, the number of pixels remains the same, say 100px. It is still 100px, but the device-independent pixels it occupies have changed (the volume has changed, the visual size has changed).

Desktop browser

Desktop computers such as PC and MAC are increasingly using high-resolution screens. For example, if the 4K display is not scaled, the physical size of more than ten inches and the font is too small on notebook computers will lead to the problems mentioned above in mobile terminals. Of course, Apple’s Retina technology has been applied to MAC Book for a long time. PC computer is only manual operation of the [system display zoom], to enlarge the content display effect.

  1. When the user system does not scale, such as a super-sized 4K display, there is no need to scale. 1 pixel of system application GUI and font = 1 device physical pixel = 1 device independent pixel = 1px Web CSS pixel unit

  2. When the user system zoom factor is 200%, for example, on a small laptop display, 1 pixel of system application GUI and font = 4 device physical pixel = 1 device independent pixel = 1px Web CSS pixel units

Generally, in Web pages, CSS pixels are 1px = 1 device-independent pixel if the user does not manually zoom in and out. This is why front-end writing desktop CSS does not need to worry about adaptation, the PX unit is directly equal to the device-independent pixels, and naturally ADAPTS to the system’s various scales.

Discussed above is the display system scaling or Reatina, said converting equipment physical pixel by scaling 】 【 】 device independent pixel, and the scaling behavior of users, said PX 】 【 CSS pixels by scaling transformation will take many equipment independent pixel 】 【, it also proves that the CSS is a kind of virtual pixel, pixels but can small.

The following is a user zoom in and out demonstration:

  1. The unit of CSS pixels on a page when the user manually reduces the page display to 25% (the minimum manual reduction factor)1px equals 0.25 device-independent pixelsIn the figure below, the HTML root element is3964px * 0.25 = 991 device-specific pixel width = the width of the browser's current window
  2. When the user manually magnifies the page display to 500% (the maximum manual magnification factor), the CSS pixels of the page in units of 1px are equal to 5 device-independent pixels. The HTML root element in the figure below is372.8px * 5 = 1864 device-specific pixel width = the width of the browser's current window

It is important to keep in mind that the width of the HTML root element may not be the maximum content width of the page, when we give the browser the current window size of 1093 device-independent pixels

<! DOCTYPE html><html lang="en">
  <head>
    <style>
      .ccc {
        width: 3000px;
        background-color: red;
        font-size: 20px;
      }
    </style>
  </head>
  <body>
    <div class="ccc">My width is 3000px pixels</div>
  </body>
</html>
Copy the code

So desktop browsers also have a default behavior: horizontal scrollbars appear when the width of the web page exceeds the size of the browser window

Mobile browser

In the early days, the Web was still dominated by PC websites. Gradually, smart phones emerged with built-in mobile browsers to surf the Internet and read PC Web content.

Because mobile applications are generally full-screen, the window width of the mobile browser is equivalent to the screen width of the mobile phone, that is, the browser window width is fixed on the mobile terminal. Early phones didn’t have Retina “zoom” technology, where 1 device physical pixel = 1 device individual pixel = 1PX CSS pixels in the browser, and then Retina came along, (Device pixel ratio DPR * 1) Device physical pixel = 1 device independent pixel = 1px CSS pixel in the browser, same principle as desktop browser, we just need to know that on the browser, when CSS pixel scaling does not occur: 1 device independent pixel = 1px CSS virtual pixel.

Found in actual operation, the mobile phone screen is in is too narrow, the equipment physical/independent pixel width is very small, in order to watch the PC in mobile browser web content, the major browsers began to control automatically narrow CSS pixels (user manual zoom in with the desktop browser page shows a meaning, just on the mobile end became the default behavior). Break the default balance of 1px CSS virtual pixels for each device, allowing more CSS content to be displayed on each device’s physical/independent pixels, and eventually complete PC web content on mobile phones.

Note that the Meta Viewport tag is not used in web documents when demonstrating above, it is another solution that cannot coexist.

Since CSS pixels are automatically shrunk, developers have to agree on a standard, so a default standard of 980px has emerged. On mobile browsers, regardless of the actual width of the current web page, the CSS pixels converted from the current browser window width are set to 980px. Page content beyond the horizontal scroll bar, no longer automatically zoom out.

The average WIDTH of PC web pages at that time was small, close to 980px, almost exactly the width of a full PC web site on a phone, with the occasional few horizontal scrollbars. The solution could be apple’s

Although the PC web page can be displayed on the mobile terminal through the above method, the experience is not good, and the content is crowded and narrow, requiring users to zoom in to view the content.

The right approach would be adaptive or responsive refactoring of the site, developing content specifically for mobile. Another solution, Meta Viewport, is also presented by Joe (🐂).

Viewport Viewport

The viewport represents the currently visible area of the computer graphics. In Web browser terms, viewports are essentially the same as browser Windows, except for the browser’S UI, menu bar, address bar, and so on.

The Viewport feature, a mobile-specific Meta value, defines various behaviors of the Viewport. This feature was first introduced by Apple to solve the problem of mobile browsers displaying PC web pages, and was followed by more and more vendors.

The two solutions proposed by Apple, CSS pixel default width of browser window 980px, are designed to solve the problem of PC web page display directly on mobile. Viewports are another set of solutions for serving web pages developed specifically for mobile and determining how well they fit on the screen.

When a web document has a Meta Viewport tag, 980px is not enabled by default.

The viewport is the visible area of the browser’s current window size. From the previous introduction, we should know that the browser window size can be expressed in various units, as follows:

  1. Device physical pixels: Number of pure hardware screen light emitting units, one physical pixel per unit
  2. Device independent pixel: The operating system’s device pixel ratio determines how many physical pixels are combined into a single pixel display
  3. CSS pixel: Complete virtual pixels, the specific number of [device-independent pixels] occupied according to the proportion of [display zoom]

When it comes to web pages, the W3C specification decides to use CSS pixels px to define the length, while the browser renders web pages and the current window size can be expressed in CSS pixels px, and the HTML root element is calculated according to the CSS pixels of the current window size.

Again because the CSS pixel unit scalable features, even if browser window size (device independent pixels) did not change, such as the desktop browser without dragging the window, such as mobile browser in full screen under the current window, CSS pixel unit PX specific value can be through the scaling of random change, thus influence the overall page display size on mobile phones.

In addition to the user’s manual scaling of CSS pixels (page display size) and the default mobile browser scaling of 980px, there is a Meta Viewport tag that controls the CSS pixel values for the current window width and the CSS pixel scaling factor.

Many articles refer to PPK’s concept of A table of two viewports: Layout viewport, Visual Viewport, ideal Viewport. Personally, I was impressed at first glance, and the more I looked at it, the more confusing it was, the more difficult it was to understand, and none of these three viewports appeared in any formal specification.

Meta Viewport tag

The
element represents any metadata information that cannot be represented by one of the other HTML meta-related elements, and it tells the browser how to parse the page.

We can use the
element’s viewport to help us set viewports, zooming, and so on to make the mobile end look better.

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

Here is a configuration of viewport. Let’s see what they mean:

Value Possible values describe
width Positive integers ordevice-width Defines the width of the current viewport in px pixels
height Positive integers ordevice-height Defines the height of the current viewport, in px pixels
initial-scale 0.0-10.0 Defines the initial scaling factor for the viewport
minimum-scale 0.0-10.0 Define the minimum value for scaling; Must be less than or equal tomaximum-scaleThe value of the.
maximum-scale 0.0-10.0 Define the maximum scale; Must be greater than or equal tominimum-scaleThe value of the.
user-scalable A Boolean value (yesorno) If set tonoUsers will not be able to zoom in or out of web pages. The default value is yes.



Note that modern browsers seem to ignore this property and force users to zoom in and out,To view

All of the above attributes, the core of which are width and initial-scale attributes, are auxiliary.

The width attribute

This property can be set to a positive integer or device-width. It sets the viewport width, which is the CSS pixel representation of the browser’s current window size. The browser window width is directly specified by the positive integer value of the width property, expressed in CSS pixels PX.

First proposed by PPK, width property set viewport is: layout viewport. But no specification mentions the word (MDN is not an official specification)

Because the content area width of the HTML root element of a web document inherits the browser’s current window width, you can obtain the CSS pixel value of the browser’s current window width by using the following properties.

document.documentElement.clientWidth
Copy the code

Note that this does not include the browser’s vertical scroll bar, the HTML root element’s border, margin, etc., so do not set the border, margin, etc., on the root element to be accurate.

Initial – scale properties

This property is used to define the initial zoom coefficient of the viewport, that is, the default initial zoom coefficient of the browser window. The value ranges from 0.0 to 10.0, corresponding to 0% to 1000% zoom ratio.

Note that initial-scale, at 100% scaling (value 1), the CSS pixel unit of the browser window is 1px = 1 device-independent pixel. Other scaling scales will change this ratio. For example, when initial-scale is set to 2, 1px = 2 device-independent pixels. Since the scaling behavior changes the conversion ratio of CSS pixels, it is equivalent to changing the display effect of the current browser window, because in the case of the same width of the phone, the device independent pixel of the phone is also fixed and unchanged, changing the ratio column, only the total CSS pixels become larger or smaller.

The CSS pixel value of the changed window width can be obtained by using the following properties, and since this API is provided by the browser and not inherited from the HTML element above, the vertical scroll bar is included.

The vertical scroll bar was a problem in the past, but now it looks more like a floating layer on the real phone in 2021. It doesn’t interfere with the document flow, that is, it doesn’t affect the layout, so we don’t have to worry about it

window.innerWidth
Copy the code

Note that the initial-scale property conflicts with the width property, as both of them actually control the CSS pixel value of the browser window, which determines how large and small the display should be. So who should browsers listen to?

Real machine checks initial-scale scaling

Do not use the mobile mode of the desktop browser to simulate the effect, it is not accurate, its initial-scale value is always 4x, i.e. the web document set initial-scale is invalid, use a real mobile browser

For the real phone test, take iphoneX as an example, the device-independent pixel of iphoneX is fixed at 375px, while mobile browsers run in full screen. Therefore, the window width of iphoneX browser in terms of device-independent pixel is also fixed at 375px forever. Let’s assume that a web page is running on a browser with the Meta Viewport tag set and the property value is

<meta name="viewport" content="width=300, initial-scale=1" />
Copy the code

As shown above, the width of the browser window is set to 300px CSS virtual pixels (width attribute) and the CSS is scaled to 100% (initial-scale attribute)

It can be concluded from the above graph that: Since the scale is 100%, i.e. 1px = 1 device independent pixels, and the total device independent pixels is 375, the width of the current browser window should also be 375px using CSS pixels, and the width property specifies 300px, less than 375px. So the width property is automatically raised from 300px to 375px to indicate the proper browser window width.

This is the case when the CSS pixel value of the initial-scale property is larger than the CSS pixel value specified by the width property. What if it’s less than? We reset the Meta Viewport tag zoom property:

<meta name="viewport" content="width=300, initial-scale=2"/>
Copy the code

Since the zoom is 200%, 1px = 2 device-specific pixels, 375/2 = 187.5px if the total number of individual pixels remains the same, the CSS pixel value for the current browser window width should be 187.5px. Then verify on the real machine:

Looking at the image above, we can see that the overall display does look like it has been doubled, which means that the CSS pixels hold more device-independent pixels. The CSS value for the current browser width is 188px (187.5 rounded to 188px). In addition, width does not automatically change to the CSS pixel value of the current browser window to 188px. It is still 300px, which is inconsistent with width.

So there’s only one possibility: because initial-scale scaling CSS pixels relative to device-independent pixels must take precedence to get the correct scaling feedback. When its scaled value is greater than the value specified by width, width is automatically promoted to equal the scaled value. When it is scaled to a value smaller than the value specified by width, you can see from the figure above that the actual window width is the scaled value, and width is no longer used to indicate the current window width, becoming the maximum zoom value (specifying the user’s finger touch zoom). On the real iphoneX (no android), it’s true that the finger can only zoom down to 300px.

Another thing to mention is that if the Meta Viewport tag is set to width=300 and no initial-scale attribute is set, what is the default value equivalent to initial-scale?

<meta name="viewport" content="width=300"/>
Copy the code

As shown above, the initial-scale CSS pixel value follows width, which is scaled by 300 (width) /375 (current mobile device pixel independent) = 0.8. The default value is calculated dynamically and the browser window width is really determined by width.

Mobile adaptation

The implementation analysis above is a mess and not very useful in practice, so we can discard these strange manifestations. From the Angle of mobile terminal adaptation, the most suitable attribute setting is given to achieve the purpose of adaptation.

The width property of the Meta Viewport tag also has a device-width property. Set the CSS value of the browser’s current window width to the number of device independent pixels, for example, iphone5 width is 320 device independent pixels (also called device logical pixels), i.e. device-width = 320px, IphoneX = device-width = 375px.

Set the scale of the initial-scale property to 1, or 100%, with no scaling. Combined with the following tags:

<meta name="viewport" content="width=device-width, initial-scale=1"/>
Copy the code

The above Settings achieve: the CSS pixel of the browser window on the mobile end is strictly equal to the device-independent pixel of the mobile phone, that is, 1px = 1 device-independent pixel effect. The different PX units of our webpage will be one-to-one corresponding device-independent pixels, and [device-independent pixels] will be converted into [how many physical pixels of devices] to render images without our concern, which automatically realizes the same effect under different mobile browsers.

Notice why it’s almost the same, not perfect? Because different mobile devices have different device-independent pixels, take a closer look at the picture above. So when our UI design is produced on a smaller device, such as 375px for iphoneX, the Meta Viewport tag above will automatically adapt. However, facing the 414 device independent pixels of iphoneXR, there is a blank area of 414-375 = 39 device independent pixels, so there is a more perfect mobile adaptation scheme (rem and vw/vh). Note that they are all based on Meta Viewport, not discarding the Meta Viewport tag.

Mobile terminal adaptation scheme

The above media query + percentage layout is only suitable for PC site, static information display, etc. After Apple developed the Retina screen, mobile phones and other devices were based on these standards, while the percentage layout had to calculate DPR multiplier, a bunch of query conditions and code redundancy after each calculation from the parent element or itself. The following two techniques are more convenient and concise.

Flexible/rem layout

Flexible solution is an early open source mobile terminal adaptation solution of Ali. After referring to Flexible, we uniformly use REM layout on the page.

The core code is very simple:

// Set 1rem = 1/10 of the current viewport
function setRemUnit () {
    var rem = document.documentElement.clientWidth / 10
    document.documentElement.style.fontSize = rem + 'px'
}
setRemUnit()
Copy the code

Document. The documentElement. ClientWidth can access the contents of the HTML root node zone width (not including the borders and from the outside), through the above we also know that the browser is equivalent to the current window CSS pixel values, Also the width property value of the Meta Viewport tag.

Rem units are specified in the CSS specification to be calculated relative to the font size of the HTML node. For example, 2rem is twice the font size of the HTML node.

In the above code, the FONT size of the HTML node is set to 1/10 of the page clientWidth (i.e. 1rem is equal to 1/10 of the page viewport), which means that the REST of the REM calculation will be proportional to the page.

So in the face of different equipment independent pixel models, such as equipment independent pixel difference of 375 and 414, can according to the proportion of elements with conversion, namely in 1 times the design draft, differences will be solved in device independent pixel level, and then through equipment independent pixel 】 【 into device pixels than 】 【 【 equipment physical pixel 】 for rendering. Almost perfect for mobile (note the two problems with 1-pixel and bitmap zoom blur)

On the implementation level, we just need to convert the UI image into REM.

Take iPhone6 as an example: the viewport is 375px, then 1rem = 37.5px. At this time, the width of a given UI element is 75px (device-independent pixels, i.e., one times the design text). We only need to set it to 75/37.5 = 2rem.

Designers should use 1-fold diagrams (design-independent/logical pixels) for design

Of course, the calculation of each layout is tedious, we can use PostCSS px2REM plugin to help us with this process (webPack compilation time this plugin does the conversion), so just write px units.

By listening for window resize events (window size change) and pageShow events (page load), you can ensure that the setRemUnit function in the above code is automatically called when you encounter different models to adjust the HTML fontSize automatically.

window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow'.function (e) {
    if (e.persisted) {
      setRemUnit()
    }
})
Copy the code

In fact, vw/ VH units have long been provided in the CSS specification for this kind of viewport calculation, but the browser compatibility was not good in the past, so Ali flexible solution, which uses REM units to simulate the effect of VW/VH units.

Later flexible solutions became obsolete as VW/VH units became more compatible

Flexible’s small problem

Note that flexible uses the clientWidth value, which is the width specified value. If the width specified value is greater than the initial-scale value innerWidth, the browser’s current window width will be discarded and the initial-scale value will be used. Must be initial-scale with high priority, otherwise scaling will not work.

If the width of the Meta Viewport tag of a web document is device-width, do not make the initial-scale scale larger than 100%, as long as it is larger than the page, clientWidth is greater than the innerWidth. No longer represents the current viewport, the REM layout of the flexible scheme is inaccurate.

In real development, no one sets the Meta Viewport tag like this, so don’t worry, the flexible option will work.

Vw/vh layout

As mentioned above, the flexible scheme is used to simulate VW/VH units. From the compatibility of the above picture, it is perfect at present and can be used safely.

Vw and VH units divide viewport width and viewport height into 100 parts.

Note as vw reference is not the document. The documentElement. ClientWidth, but window. The innerWidth value, namely the initial – scale after scaling the browser window width of CSS pixel values.

The official directly used the correct opening method 😄, there will be no flexible small problem

  • vw (Viewport's width):1vwEqual to 1% of the viewport width
  • vh (Viewport's height)1vhEqual to 1% of the viewport height
  • vmin : vwvhThe smaller value of
  • vmaxSelection:vwvhThe maximum value of

If the viewport is 375px, 1vw = 3.75px, and the width of a given UI element is 75px (device-independent pixels, 1 times the design), We just need to set it to 75/3.75 = 20vw.

We don’t have to do this by ourselves, we can use the postCSS-px-to-viewPort plugin for PostCSS.

When writing code, we only need to write px units according to the design drawing given by the UI (the premise is that the design draft is 1x, designed with device-independent pixels).

Vw also has a small defect: the conversion of PX to VW may not be completely divisible, so there is a certain pixel difference, but the difference is so small that it can be ignored.

The safety area

After the release of the iPhoneX, many manufacturers released phones with edge screens (also known as alien screens).

There are just three changes to the appearance of the phones: corners, bangs and Home indicators. To accommodate these phones, the concept of a safe zone was born: a safe zone is a viewable window area that is not subject to the above three effects.

To ensure that the page looks good, we must limit the page to a safe range, but not affect the overall effect.

viewport-fit

Viewport-fit is an attribute created specifically for the iPhoneX that restricts how web pages can be displayed in secure areas.

Contain: visual window completely contains the content of the web page

Cover: The content of the web page completely covers the visual window

The default setting is auto and contain.

Env, constant

We need to properly place the top and bottom within the security zone. In iOS11, two new CSS functions, env and constant, are used to set the distance between the security zone and the boundary. There can be four constants inside a function:

  • safe-area-inset-left: Distance between the security zone and the left boundary
  • safe-area-inset-right: Distance between the security zone and the right boundary
  • safe-area-inset-top: Distance between the security zone and the top boundary
  • safe-area-inset-bottom: Distance between the security zone and the bottom boundary

Note: We must specify viweport-fit to use these two functions:

<meta name="viewport" content="viewport-fit=cover">
Copy the code

Constant works on iOS < 11.2, env works on iOS >= 11.2, which means we tend to set them both, limiting pages to safe zones:

body {
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}
Copy the code

Landscape adaptation

Many viewports we need to display different layouts for landscape and portrait, so we need to check that different styles are given in different scenarios:

JavaScript detects landscape

Window. orientation: Gets the orientation of the screen

window.addEventListener("resize".() = >{
    if (window.orientation === 180 || window.orientation === 0) { 
      // Rotate the screen 180 degrees in normal direction
        console.log('portrait');
    };
    if (window.orientation === 90 || window.orientation === -90) {// The screen rotates 90 degrees clockwise or 90 degrees counterclockwise
        console.log('landscape'); }});Copy the code

The CSS detects landscape screen

@media screen and (orientation: portrait) {
  / * vertical screen... * /
} 
@media screen and (orientation: landscape) {
  /* Landscape specific style... * /
}
Copy the code

1 px problem

Mobile 1PX solution – Nuggets

To adapt to various screens, we write code that uses device-independent pixels to lay out the page.

On screens with a device pixel ratio greater than 1, the 1px we write is actually rendered by multiple physical pixels, which makes 1px look thick on some screens.

1px is a problem because the reason 1px will render 2px physical pixels is an effect, not a cause.

The root cause is this: the 750px design draft has the 1px physical pixel expected by the UI designer, which corresponds to the 0.5px device independent pixel on the actual 375px draft. The 0.5px device independent pixel is supported for IOS8+, but not for android; So Android will render a device independent pixel of 0.5px into a device independent pixel of 1px. That is, android will render a device independent pixel of 1px on a 375px image at 2px physical pixels, which is thicker.

Fake 1 pixel:

True 1 pixel:

Media enquiries @media

Media queries use device pixel ratio scaling to set decimal pixels

Disadvantages: Poor compatibility, currently IOS8+ only support, in IOS7 and below, Android is display 0px.

IOS8+ already supports px values with decimals. Media query corresponds to devicePixelRatio with a query value -webkit-min-device-pixel-ratio.

.border { border: 1px solid # 999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
    .border { border: 0.5 px. solid # 999}}@media screen and (-webkit-min-device-pixel-ratio: 3) {
    .border { border: 0.333333 px. solid # 999}}Copy the code

Border image border-image

Determine the pixel ratio of different devices based on media query to give different border-image

Disadvantages: need to make a 0.5 pixel line image

In order to facilitate reuse, multiple use, do not need to modify one by one, it is not recommended to convert the image to base64 form

.border_1px{
    border-bottom: 1px solid # 000;
}
@media only screen and (-webkit-min-device-pixel-ratio:2) {.border_1px{
        border-bottom: none;
        border-width: 0 0 1px 0;
        border-image: url(../img/1pxline.png) 0 0 2 0stretch; }}Copy the code
  • border-width: Specifies the width of the border. You can set four values: top right, bottom left.
  • border-image: The first parameter is the URL image, the last four parameters are [top right bottom left], the last parameter is the border image rendering method.
  • CSS3 border-image CSS3 border-image

Background image background-image

Similar to the border-image, prepare a qualified border background image and simulate it on the background.

Disadvantages: need to make a 0.5 pixel line image

In order to facilitate reuse, multiple use, do not need to modify one by one, it is not recommended to convert the image to base64 form

.border_1px{
    @media only screen and (-webkit-min-device-pixel-ratio:2) {.border_1px{
            background: url(../img/1pxline.png) repeat-x left bottom;
            background-size: 100% 1px; }}}Copy the code

Background image gradient linear-gradient

Using the linear-gradient property of background-image, from color to transparent, the default direction is from top to bottom, from 0deg to 50% of the color is border color, and then the bottom half of the color is transparent.

Then set the width of the background to 100% (depending on the desired width) and the height to 1px, and remove the tile behavior no-repeat, so the colored border is 0.5px, recommended.

.bg_border {
    background-image: linear-gradient(0deg,black 50%,transparent 50%);
    background-size: 100% 1px;
    background-repeat: no-repeat;
}
Copy the code

Shadow simulates box-shadow

Shadow can also be achieved, the advantage is that there is no rounded corner problem, the disadvantage is that the color is not good control

div {
    box-shadow: 0 1px 1px -1px rgba(0.0.0.0.5);
}
Copy the code

Use of the box-shadow attribute:

`box-shadow: h-shadow v-shadow [blur] [spread] [color] [inset]`
Copy the code
  • The parameters respectively represent: horizontal shadow position, vertical shadow position, blur distance, shadow size, shadow color, change outer shadow to inner shadow, the last four are optional;
  • Key note: Why willSet the shadow size to negative? Set to-1px? First of all, we need to understand the meaning of “shadow size” : when the shadow size is a positive integer, the whole shadow will expand, when it is negative, the whole shadow will shrink, when it is exactly negative 1, you can achieve device-independent pixel0.5 px.Splitter effect

Dynamically scale initial-scale

Obtain the pixel ratio of the device by using JS, and then dynamically set initial-scale scaling to make the CSS virtual pixels equal to the real physical pixels. Note that the CSS virtual pixels are not equal to the device-independent pixels. The CSS pixels are equal to the device-independent pixels only when the scale is fixed at 100%. The dynamic setting of the zoom behavior, is to break the system’s multiplier behavior, manual control.

For example: when the iphoneXR device pixel ratio is 3 and we scale the page 1/3 times, 1px is equal to one real device physical pixel of the screen, equal to 0.33333333 device independent pixels, the line is no longer thick.

const scale = 1 / window.devicePixelRatio;
const viewport = document.querySelector('meta[name="viewport"]');
if(! viewport) { viewport =document.createElement('meta');
    viewport.setAttribute('name'.'viewport');
    window.document.head.appendChild(viewport);
}
viewport.setAttribute('content'.'width=device-width,user-scalable=no,initial-scale=' + scale + ',maximum-scale=' + scale + ',minimum-scale=' + scale);
Copy the code

But! We know that the Meta Viewport is a global meta-information tag, so setting this is self-defeating. All CSS pixel units written next are not self-adaptive because they are represented by physical pixels of the device. On models with a larger device pixel ratio, 20px occupies a smaller number of device-independent pixels, such as 20/2 = 10 pixels on iphoneX and 20/3 = 6.6666 pixels on iphoneXR.

The above scheme is the one adopted by flexible earlier. I haven’t seen its source code, so I don’t know how to solve this problem temporarily. We must not be able to use it.

Pseudo-element + transform

Based on media query, determine the pixel ratio of different devices to scale the transform line. This method can meet various scenarios without compatibility problems and is most recommended.

To satisfy rounded corners, just add border-radius to the pseudo-element as well

.border_1px:before{
    content: ' ';
    position: absolute;
    top: 0;
    height: 1px;
    width: 100%;
    background-color: # 000;
    transform-origin: 50% 0%;
}
@media only screen and (-webkit-min-device-pixel-ratio:2) {.border_1px:before{
        transform: scaleY(0.5); }}@media only screen and (-webkit-min-device-pixel-ratio:3) {.border_1px:before{
        transform: scaleY(0.33); }}Copy the code

One more note: empty elements cannot use pseudo-elements. What is an empty element? An element that cannot contain child nodes (which is semantically correct, because pseudo-elements are also child nodes) is simply a single label.

Common empty elements are input, SELECT, textarea, and other form elements. The most common pit to tread on is a textarea with a 1px border. Since this is not supported, use another solution.

What are the empty elements? Look at MDN- empty element

Vector SVG

The above border-image and background-image can simulate 1px borders, but they are bitmaps and need to be imported externally.

With PostCSS’s postCSs-write-SVG plugin, we can create a 1px border for SVG directly using border-image and background-image:

@svg border_1px { 
    height: 2px; 
    @rect { 
        fill: var(--color, black); 
        width: 100%; 
        height: 50%; }}.example { 
    border: 1px solid transparent; 
    border-image: svg(border_1px param(--color #00b1ff)) 2 2 stretch; 
}
Copy the code

The compiled:

.example {
    border: 1px solid transparent;
    border-image: url("data:image/svg+xml; charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='2px'%3E%3Crect fill='%2300b1ff' width='100%25' height='50%25'/%3E%3C/svg%3E")
        2 2 stretch;
}
Copy the code

Image blur problem

Most of the images we use are bitmaps (PNG, JPG…) A bitmap is made up of individual pixels, each with a specific position and color value:

In theory, each pixel of the bitmap should be rendered using one physical pixel on the screen for optimal display.

On a screen with DPR > 1, a pixel of the bitmap may be rendered by multiple physical pixels. However, these physical pixels cannot be accurately assigned to the color of the corresponding bitmap pixel, and can only be approximated, so the same image will be blurred on a screen with DPR > 1:

In order to ensure image quality, we should render one image pixel with one screen pixel as much as possible, so we need to display images with different resolutions for different DPR screens.

For example, display a double graph (@2x) on a screen with DPR =2 and a triple graph (@3x) on a screen with DPR =3.

Media enquiries @media

Use @media query to judge the pixel ratio of different devices to display images with different precision:

// Only for background images.avatar{
    background-image: url(conardLi_1x.png);
}
@media only screen and (-webkit-min-device-pixel-ratio:2) {.avatar{
        background-image: url(conardLi_2x.png); }}@media only screen and (-webkit-min-device-pixel-ratio:3) {.avatar{
        background-image: url(conardLi_3x.png); }}Copy the code

Background image image-set

In CSS, use the background-image srcset value, and the browser will automatically match the best image based on the pixel density

// Only for background images.avatar {
    background-image: -webkit-image-set( "conardLi_1x.png" 1x, "conardLi_2x.png" 2x );
}
Copy the code

Don’t forget to include the browser prefix, caniuse to check compatibility

Image label SRcSET

In the template /HTML/JSX, use the srcset attribute of the img tag, and the browser will automatically match the best image based on the pixel density.

<img src="conardLi_1x.png"
     srcset=" conardLi_2x.png 2x, conardLi_3x.png 3x">
Copy the code

SVG vector diagram

SVG stands for Scalable Vector Graphics.

Unlike bitmaps, which are pixel-based, SVG is a shape description of an image, so it is essentially a text file, small in size and undistorted no matter how many times it is magnified.

In addition to drawing SVG manually in code, we can also use SVG images as bitmaps, a total of four.

// 1. Manually draw using SVG tags<svg>.</svg>// 2. The img tag is imported directly into SVG images<img src="conardLi.svg">// 3. Convert smaller SVG images to Base64 encoding and embed them directly in the IMG tag without relying on external resources<img src="data:image/svg+xml; base64,[data]">Avatar {background: URL (conardli.svg); // 4. }Copy the code

Replace the image SRC address

In js, use window.devicePixelRatio to get the devicePixelRatio, traverse all the images, and replace the image address:

const dpr = window.devicePixelRatio;
const images =  document.querySelectorAll('img');
images.forEach((img) = >{
  img.src.replace(".".` @${dpr}x.`);
})
Copy the code

Adaptive and responsive

Mobile terminal is inseparable from adaptive and responsive layout schemes. The concepts, differences, advantages and disadvantages of responsive layout and adaptive layout and how to choose them?

A conceptual distinction between

Adaptive layout: Responsive layout is to achieve different display of web browsing on terminals with different screen resolutions. Responsive design makes the site a better browsing experience on mobile phones and tablets. In other words, a website can accommodate multiple terminals, rather than making a specific version for each terminal.

  1. By detecting the viewport resolution, it can determine whether the device currently accessed is PC, tablet or mobile phone, so as to request the service layer and return to different pages.
  2. Multiple sets of interfaces need to be developed, and the screen adaptation of the page is within a certain range: for example, the screen adaptation of the page should be larger than 1024 pixels on PC and smaller than 768 pixels on mobile.
  3. Content congestion can occur if the screen is too small.

Responsive layout: Adaptive layout is a new web design method and technology that can forget to make web pages adaptive to display on devices of different sizes. It requires the development of multiple interfaces to adapt to different terminals.

  1. Through the detection of viewport resolution, for different clients to do code processing in the client side, to show different layout and content.

  2. Only need to develop a set of interface can be, is a set of pages all adapt.

  3. A web design that automatically recognizes screen width and adjusts accordingly.

The advantages and disadvantages

Adaptive layout:

  1. advantages: can be designed independently, do any style you want, but also can achieve database synchronization, flexible design, can be optimized independently in line with the rules of the search engine.
  2. disadvantages: Mobile phone sites sometimes cannot be completely consistent with THE content of PC sites, and the workload is heavy. Adaptive mobile phone sites often use different subdomain names or directories to jump, so the weight is scattered for optimization, and visitors’ browsing experience is still defective.

Responsive layout:

  1. advantages: more convenient browsing, can increase the experience of visitors, there is no need to design mobile phone station, PC station is mobile phone station, for optimization, weight is not scattered, more in line with the rules of the search engine.
  2. disadvantages: The design style is often limited, difficult to implement complex framework structure, and the front-end CSS code volume increases.

Usage scenarios

Choose adaptive website: mainly because they have a PC station before the construction of mobile phone station, PC station can not do small screen device moderate browsing, and can not be greatly revised to affect the website optimization, so the construction of adaptive mobile phone station jump to achieve mobile phone, iPad, etc., in line with browsing, mobile phone station database is generally synchronous.

Choose responsive website: often is the construction of new station design, before no PC station or mobile phone, do not need to take into account website optimization and data synchronization, can be designed as responsive website, responsive website is more consistent with visitors browsing, increase the website experience, but also more in line with the website optimization work.

Bottom line: A responsive layout is still better than an adaptive layout, but an adaptive layout is more realistic because you only need to consider a few states rather than many. Therefore, no matter what kind of design has their own characteristics, we should choose a suitable layout according to the needs of the project.

Responsive implementation

The adaptive scheme needs to develop multiple sets of equipment, which is troublesome. So more popular responsive layout, as long as the development of a set is enough, the disadvantage is the CSS is heavy, the specific technology is introduced below:

The original link

Media queries

CSS3 media queries allow us to define different styles for different media types, and when resizing the browser window, the page will also be rerendered according to the width and height of the browser.

How to determine the segmentation point of media query is also a problem that will be encountered in the development. The following is the distribution of screen resolution of mobile devices and computers in the market. It can be found that the screen resolution of different brands and models of devices is generally different. If we choose 600px, 900px, 1200px and 1800px as the segmentation points, it can be adapted to 14 common models:

Of course, this is just one of the ways to divide it, but we can also divide it like this: 480px, 800px, 1400px, 1400px

How does Bootstrap, once a typical responsive layout framework, break points?

The above segmentation scheme may not meet the actual requirements of the project, so we can first use the segmentation points with large span for segmentation, and then add new segmentation points according to the actual situation if the mismatch occurs.

Mobile OR PC first?

Both mobile-first and PC-first are based on the fact that as the screen width increases or decreases, the later styles override the previous ones. Therefore, min-width is preferred for mobile devices and max-width is preferred for PC devices.

Percentage layout

With percentage units, you can make the width and height of the components in the browser change with the height of the browser to achieve a responsive effect. The grid system in Bootstrap uses percentages to define the width and height of elements. CSS3 supports maximum and minimum heights. Percentages and Max (min) can be used together to define the width and height of elements on different devices.

/* iphone6 7 8 plus */
@media screen and (max-width: 414px) {
    aside {
      float: none;
      width: 100%;
      height: 5%;
      background-color: yellow;
    }
    main {
      height: calc(100vh - 5%); background-color: red; }}/* iphoneX */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 3) {
    aside {
      float: none;
      width: 100%;
      height: 10%;
      background-color: blue;
    }
    main {
      height: calc(100vh - 10%); background-color: red; }}/* iphone6 7 8 */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 2) {
    aside {
      float: none;
      width: 100%;
      height: 3%;
      background-color: black;
    }
    main {
      height: calc(100vh - 3%); background-color: red; }}/* iphone5 */
@media screen and (max-width: 320px) {
    aside {
      float: none;
      width: 100%;
      height: 7%;
      background-color: green;
    }
    main {
      height: calc(100vh - 7%); background-color: red; }}Copy the code

But we have to figure out what the percentage of neutrons in CSS is relative to. Let’s jump to the conclusion: it’s calculated relative to the MDN of the element.

A percentage is used in the height or width of a child element relative to its immediate parent, width relative to its parent, and height relative to its parent.

The top and bottom of the child elements, if set in percentage, are relative to the height of the parent element of the direct non-static positioning (the default positioning), and the left and right of the same elements, if set in percentage, are relative to the width of the parent element of the direct non-static positioning (the default positioning).

When an element does not write position, it defaults to position: static

The padding of the child element, if set to a percentage, is either vertical or horizontal relative to the width of the parent element, regardless of the height of the parent element. The margin of a child element, if set to a percentage, is relative to the width of the parent element, both vertically and horizontally.

If border-radius is set to a percentage, the value is relative to the width of the device. In addition to border-radius, translate and background-size are all relative to the device.

The HTML root element directly inherits the browser’s current window width.

From the above introduction to percentage units, it is easy to see that there are two obvious drawbacks to using all percentage units for a responsive layout:

  • The calculation is difficult, if we want to define the width and height of an element, according to the design draft, must be converted into percentage units.
  • As you can see, if percentages are used in each attribute, the attribute relative to the parent element is not unique. Such aswidthheightRelative to the parent elementwidthheightAnd themargin,paddingBoth vertically and horizontally are relative to the width of the parent element,border-radiusIt is relative to the elements themselves and so on, which makes our use of percentage units easy to complicate layout problems. ,
  • In the correct way, use the above “Mobile Adaptation Solution”