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 is10x
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 a1vw
, disposed1rem
units10vw
- Window using CSS characteristics, the total width
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
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
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)
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 ofwindow.innerWidth
-
1vh
is equal to 1% of the value ofwindow.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 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
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
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.
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
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
- import
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
- Install px to vw tools like
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 useviewport
unit (vw, vh, vmin, vmax), it is recommended to use postcss-px-to-viewport for conversionpostcss-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
- Overview of front-end basics -- compatibility and adaptation of screens, images, fonts and layouts for mobile development
- Principle Analysis of Rem Layout
- Let's talk about the solution of 1px under Retina
- Let's talk about the adaptation of mobile pages
- How to use vw in Vue project to achieve mobile adaptation
- In detail, the classic REM layout and the rookie VW layout of the mobile terminal
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。