4

The author has been working as a front-end since graduation, and now, 90% of the projects are dealing with the mobile terminal, so when the word "mobile H5" is written on the resume, I will be asked about the adaptive solution and the high-definition solution.

"Adaptive" refers to a set of UI (such as 750*1334), which shows almost the same effect on multiple terminals; while "HD" refers to various precision adaptations due to DPR improvement

This article talks about the adaptive scheme and high-definition scheme that the author understands

Conclusion first

adaptive solution

  • rem

    • Adaptation ideas

      • Choose a size as a design and development benchmark
      • Define a set of adaptation rules to automatically adapt to the remaining sizes
      • Special adaptation effects give design effects
    • A historical artifact , CSS viewport units are not supported by major browsers
    • principle

      • Dynamically adjust the font-size value of the root element html according to the width of the window
      • Set the total width to 100 copies, each of which is called a unit x, and set 1rem the unit is 10x
    • shortcoming

      • js script needs to be loaded, and it is calculated according to the window width of the device, which affects performance
    • Influence: Since its birth in 2015, it has occupied a certain proportion in the field of H5 adaptation
    • Related technology libraries: flexible , px2rem
  • vw

    • Adaptation ideas (as above)
    • principle

      • Window using CSS characteristics, the total width 100vw , every unit of a 1vw , disposed 1rem units 10vw
    • shortcoming

      • Because it is calculated based on the width of the view, it is not suitable for tablets and PCs
    • Influence: The plan released in 2018, the current H5 is suitable for the mainstream
    • Related technical library: postcss-px-to-viewport
  • px + calc + clamp

    • Adaptation ideas

      • According to the new features of CSS: css variables, calc() function, clamp(), @container function implementation
    • Features

      • Addresses the fatal flaw of rem, vw layouts: loss of pixel perfection, and once the screen is below or above a certain threshold, there is often a movement of the layout or overflow of the text content
      • Da Mo proposed it in 2021. It is the most advanced, but it has not been used by major manufacturers (the support rate of the clamp function browser is not high for the time being). For details, please refer to this article by Da Mo: How to Build a Perfectly Scaled UI Interface
    • shortcoming

      • Because the program is advanced, I haven't seen it used by major manufacturers.

HD solution

  • 1 pixel problem solution
  • High-definition solutions for pictures under different DPR

To sum up, the adaptive solution is to solve the adaptation problem of each terminal , and the high-definition solution is to solve the detail processing of the Retina screen

write in front

Before talking about the mobile terminal adaptation plan, let's understand some technical concepts

Device Independent Pixel

Device Independent Pixels (DIP) === CSS Pixels === Logical Pixels, see 375*667 directly in Chrome

chrome中查看css像素

Don't panic when you see Device Independent Pixels, it means CSS Pixels, and its width and width are what you find in Chrome. It can be remembered like this, "device-independent pixels", the number of words is long, and the text is just CSS pixels, which are also theoretically artificially given indicators, also called logical pixels.

physical pixel

Physical pixels can be understood as the resolution advertised by mobile phone manufacturers when selling mobile phones, that is, physical pixels = resolution, which represents the number of pixels in the vertical and horizontal

That is to say, there are 1920 pixels in the horizontal direction and 1080 pixels in the vertical direction of the device screen (assuming the screen resolution is 1920*1080), that is, the screen resolution represents physical pixels, which are set at the factory and the unit is pt , 1pt=0.376mm

手机分辨率

Physical pixels, also known as device pixels, means device pixels === physical pixels. Can be remembered in this way, the length that the device can measure in the physical world

DPR (Device Pixel Ratio)

And what is the Device Pixel Ratio (DPR)?

DPR = Device Pixels / Device Independent Pixels, it is usually associated with Retina screens

Take iPhone7 as an example, DPR of iPhone7 = iPhone7 physical pixels / iPhone7 device independent pixels = 2

Width 1334 / 667 = 2

High 750 / 375 = 2

Get the DPR of the iPhone 7 is 2, which is what we often call a retina screen, and that's the marketing term, it's because of technological advancements that make a CSS pixel cram more physical pixels into it

What other marketing terms are there: the porter of nature in Nongfu Spring, the "気" of vitality forest

This is what the author remembers:

  • CSS pixels (device-independent pixels) are like a container. In the past, they were stuffed one-to-one, so the DPR was 1. Later, with technological development, more real pixels (physical pixels) could be stuffed into a container.
  • DPR = Device Pixels / Device Independent Pixels
  • DPR = Physical Pixels (Real) / CSS Pixels (Virtual)

On retina screens, taking DPR = 2 as an example, 4 (2x2) physical pixels are used as a CSS pixel, which makes the screen look sharper (fine), but the size of the element (CSS pixels) itself does not change

DPR对比

With the development of hardware, the DPR of mobile phones such as iPhone13 Pro is already 3, and it will not be a problem to break through 4 in the future

Then again, what's wrong with a DPR of 2 or 3? We write code in CSS as the smallest unit, and it is also displayed on the screen in CSS as the smallest unit. That is to say, when the DPR is 2, we want to simulate 1 单位物理像素 is impossible ( If the browser supports 0.5px CSS, it can be simulated, but if the DPR is 3, use 0.333px ?); and because the device-independent pixel (CSS pixel) of the mobile phone is fixed, use the traditional When static layout (fixed px), there will be a misalignment of styles

iPhone 5/SE: 320*568 DPR: 2

iPhone 6/7/8: 375*667 DPR: 2

iPhone 6/7/8 Plus: 414*736 DPR: 3

iPhone X: 375*812 DPR: 3

Therefore, we need to adapt to the CSS pixels of each terminal and the 1-pixel problem and the high-definition picture problem that occur under different DPRs. With the development of technology, the front-ends got rid of the compatibility of IE and fell into the compatibility swamp of major mobile phone brands.

adaptive solution

Rem layout - second in the world

Introduction: rem is calculated relative to the font-size of the root element html

Associated with rem is em:

When em is used as the font-size unit, it represents the font size of the parent element, and when em is used as another attribute unit, it represents its own font size

When rem acts on a non-root element, it is relative to the font size of the root element, and when rem acts on the font of the root element, it is relative to its initial font size

Essence: proportional scaling , is to simulate the characteristics of vw through JavaScript

Assuming that the screen width is divided into 100 parts, the width of each part is represented by x, x = screen width / 100, if x is used as the unit, the value in front of x represents the percentage of the screen width

 p { width: 50x } /* 屏幕宽度的 50% */

If you want the page elements to change proportionally with the screen width, we need the above x, which is vw, but vw is used on a large scale after the browser supports it. Before that, js + rem can simulate this effect

As I said before, when rem acts on a non-root element, it is relative to the font size of the root element, so after we set the unit of the root element, the non-root element uses rem as the relative unit

 html { font-size: 16px }
p { width: 2rem } /* 32px */

html { font-size: 32px }
p { width: 2rem } /* 64px */

Here comes the problem, we need to get a dynamic root element font-size and change the size of each element accordingly

Interestingly, the current practice of our two projects is to set the root element through media query, which is divided into four files, the default is 16px

The author does not understand this approach. The original developer said that our set has been running for 6 years, and no one has said anything about the UI adaptation. There is a question here, does the UI fit well as he said, can the "media query root element + rem" also fit? Is it perfect?

The author will also show this approach in the demo later.

But how to change the font-size of the root element, it can't always be 16px, which is ok on medium and large screens, but the font is too large on small screens, so its size should also be dynamically obtained. How to make it dynamic, as mentioned above, let the font-size of the root element be equal to 1/100 of the screen width

 html { font-size: width / 100};

How to set the font size of html to be equal to one percent of the screen width? It can be set by js, generally need to be set in the page dom ready, resize and screen rotation

 document.documentElement.style.fontSize = document.documentElement.clientWidth / 100 + 'px';
The flexible source code is written as above

After we set the width of 1%, when writing css, we need to use css processors such as scss/less to compile and process the css. Assuming that the given design image is 750*1334, and one of the elements has a width of 200 px, according to the formula:

width: 200 / 750 * 100 = 26.67 rem

In sass, you need to set the design width for conversion:

 @use 'sass:math';

$width: 750px;

@function px2rem($px) {
  @return #{math.div($px, $width) * 100}rem;
}

After compiling above

 div {width: 26.667rem}

In different sizes it has different widths

model size width
iPhone 5/SE 320*568 170*170
iPhone 6/7/8 375*667 200 * 200
iPhone 6/7/8 Plus 414*736 220.797 * 220.797
iPhone X 375*812 200 * 200

The effect is as follows (specially explained: the figure shows the introduction of the flexible library, and the font-size of its root element is 1/10 of the screen)

rem布局

REM layout (flexible) demo

Advantages: The compatibility of rem can be as low as ios 4.1, android 2.1

shortcoming:

  • Proportional magnification (it can be said that advantages can also be understood as disadvantages, used in different scenarios)

    • There are several starting points for users to choose a large screen. Some people want larger fonts, larger images, some people want more content, and do not want larger icons
  • The font size cannot use rem (usually use media queries to control the font-size size)
  • Browsing the broken phase on the PC side, generally set a maximum width
 var clientWidth = document.documentElement.clientWidth;
clientWidth = clientWidth < 780 ? clientWidth : 780;
document.documentElement.style.fontSize = clientWidth / 100 + 'px';
 body {
    margin: auto;
    width: 100rem;
}
  • What if the user bans js?

    • Add a noscript tag to prompt users
    • <noscript>开启JavaScript,获得更好的体验</noscript>
    • Add a default font size to HTML

Related technical solutions: flexible ( amfe-flexible or lib-flexible ) + postcss-pxtorem

Viewport layout - VW is not born to me, suitable for eternity like a long night

vw is the unit of length based on the Viewport window, where the Viewport refers to the visual area of the browser, and this visual area is the size of window.innerWidth/window.innerHeight

According to CSS Values and Units Module Level 4: vw is equal to 1% of the width of the initial containing block (html element), which is

  • 1vw is equal to 1% of the value of window.innerWidth
  • 1vh is equal to 1% of the value of window.innerHeight

See the picture to understand

屏幕的宽高

When talking about rem layout, I once gave an example of x, x is vw

 /* rem 方案 */
html { font-size: width / 100}
div { width: 26.67rem }

/* vw 方案 */
div { width: 26.67vw }

vw can also be combined with the rem scheme, so that js is not required to calculate the font size of html

 html { font-size: 1vw }
div {width: 26.67rem }

The effect is as follows:

vw适配

vw adaptation is natively supported by CSS, and is currently compatible with most mobile phones. It does not need to load js, and it will not cause performance problems due to js.

vw looks really good, but there are some problems

  • It also can't solve the display problem of 1px border under high-definition screen, you need to deal with it yourself
  • Since the vw scheme is completely proportional, it will be broken on the PC side (same as rem)

Related technical solutions: postcss-px-to-viewport

VW layout demo

px adaptation - one power down ten clubs

Without rem/vw, traditional responsive layouts can also be used in mobile layouts, requiring design specifications

Use css variable adaptation (the reasons for the space will not be introduced in detail, you can directly look at the code )

Usage scenario: news and content-based websites are not suitable for rem, because large-screen users want to see more content, such as Netease News, Zhihu, taptap

PX + CSS variable demo

Media enquiries - can I have a seat?

As mentioned above, our company used media query to adapt the original H5 terminal. The author tried to reproduce it, and I can only say that it is not bad. I can see that media query wants to do this, but I still have more than enough heart lack of strength

Using rem, vw, px and other methods to achieve non-standard size (375 667 design draft), the height of the header is 165.59px , and media because of the large screen, set the root font-size to 17px, the result of the header The height becomes 159.38px (17 9.375rem)

As shown in the GIF below:

媒体查询布局与其他布局对比

So using only media queries is not satisfactory.

Media query layout demo

Comparison of various adaptations

The essence of vw and rem adaptation is proportional scaling, px is directly written, which is better or worse depends on yourself

REM layout VW layout PX + css variable layout
container minimum width support not support support
container maximum width support not support support
HD device 1px border support support support
Container fixed aspect ratio support support support
advantage 1. The old scheme
2. When supporting the 1px border of high-definition devices, you can write directly as usual
1. No need to introduce js
2. Natural support, standard writing
Same as VW
shortcoming 1. Need to import js to set the font-size of html
2. The font size cannot use rem
3. Browsing on the PC side will be broken, generally need to set the maximum width
1. It will be broken on the PC side
2. Does not support old mobile phones
Same as VW

In addition, there are solutions with vw and rem

  • Set the vw unit for the size of the root element that changes with the change of the viewport, and dynamically change the size of each element
  • Limit the maximum and minimum font size of the root element, with the body plus the maximum width and minimum width
 // rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推
$vm_fontsize: 75; // iPhone 6尺寸的根元素大小基准值
@function rem($px) {
     @return ($px / $vm_fontsize ) * 1rem;
}
// 根元素大小使用 vw 单位
$vm_design: 750;
html {
    font-size: ($vm_fontsize / ($vm_design / 2)) * 100vw; 
    // 同时,通过Media Queries 限制根元素最大最小值
    @media screen and (max-width: 320px) {
        font-size: 64px;
    }
    @media screen and (min-width: 540px) {
        font-size: 108px;
    }
}
// body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小
body {
    max-width: 540px;
    min-width: 320px;
}

HD solution

1 pixel problem

1 pixel means display on Retina screen 1单位物理像素

It is well understood that CSS pixels (device independent pixels) are artificially specified by us. When DPR is 1, 1 pixel (referring to the CSS pixel we wrote) is equal to 1 physical pixel; but when DPR is 3, 1 pixel is 3 physical pixel

  • DPR = 1, where 1 physical pixel equals 1 CSS pixel
  • DPR = 2, where 1 physical pixel equals 0.5 CSS pixels

    • border-width: 1px, where 1px is actually 1 CSS pixel width, equal to 2 physical pixels, what the designer actually wants is border-width: 0.5px
  • DPR = 3, where 1 physical pixel equals 0.33 CSS pixels

    • What the designer wants is border-width: 0.33px

1像素问题

Solutions

Use 0.5px . There are limitations, iOS 8 and above, supported by Apple system, but below iOS 8 and Android (some low-end machines), will display ---df6091c7a67bf999c13ffd4a9d896459 0.5px as 0px

Since 1 CSS pixel represents 2 (DPR is 2), 3 (DPR is 3) physical pixels, and the device does not know how to write 0.5px, then draw 1px, and then find a way to reduce the width by half

Program

  • Gradient implementation

    • background-image: linear-gradient(to top, ,,,)
  • Implemented using zoom

    • transform: scaleY(0.333)
  • Use pictures to achieve

    • base64
  • Implemented using SVG

    • Embed background url
  • border-image

    • Poor support on low-end devices

All of the above are achieved through CSS media queries

 @media only screen and (-webkit-min-device-pixel-ratio: 2),
    only screen and (min-device-pixel-ratio: 2) {}
@media only screen and (-webkit-min-device-pixel-ratio: 3),
    only screen and (min-device-pixel-ratio: 3) {
        
}

Image adaptation and optimization

Images usually make up the vast majority of download resources on a web page, and optimizing images can often minimize the number of bytes downloaded from a website and improve website performance

Usually yes, there are some general optimization methods: provide the most suitable picture size for different DPR screens

Adaptation analysis of major manufacturers

I have read a lot of articles, such as: How does the big factory adapt to the mobile terminal?

Major factories, there are rem adaptations, vm adaptations, and vm+rem combination adaptations, as well as pure px solutions.

  • Scenes with more readable content such as news and communities: px+flex+percentage

    • Such as Ctrip, Zhihu, TapTap
  • Mobile pages with more types of visual components and strong dependencies: vw+rem

    • such as e-commerce, forums

Summarize

rem scheme, import amfe-flexible library

Design: The design drawing is 750 * 1334. After the design is cut, upload the blue lake and write px according to the size.

Development:

  • Use the rem scheme

    • import amfe-flexible library
    • Install px to rem tools like px2rem
    • config px2rem
    • Write px in the project, and rem when outputting
    • Suitable for any scene
  • Use vw scheme

    • Install px to vw tools like px2vw
    • config px2vw
    • Write px in the project, and vw when outputting
    • Suitable for any scene
  • Use the px scheme

    • Write as you want, but because of the design plan, the size of the button is fixed, the size of the icon is standard, and the height of the TabBar is also written to death. When everything is standard, it is convenient to write the page.
    • E.g

      • Fixed 100 * 50 on the left, flex layout on the right
      • Fixed 100 * 50 on the left, calc(100% - 100px) on the right (calculated using calc in CSS3)

other

Caniuse website tests the compatibility of CSS properties with browsers

doubt

Q: Why H5 mobile UI library units mostly use px? Wouldn't this be a fitting problem?

In fact, after we have written px, if the project adopts rem to write business, it can be converted by introducing px2rem (which has not been maintained for six years).

In the Youzan vant library, its introduction to browser adaptation is:

Viewport layout

Vant uses px as the style unit by default. If you need to use viewport unit (vw, vh, vmin, vmax), it is recommended to use postcss-px-to-viewport for conversion

postcss-px-to-viewport is a PostCSS plugin for converting px units to vw/vh units

Rem layout

If you need to use rem units for adaptation, the following two tools are recommended:

  • postcss-pxtorem is a PostCSS plugin for converting px units to rem units
  • lib-flexible is used to set the rem base value

demo collection: online demo

References


山头人汉波
394 声望555 粉丝