This article belongs to the original article, reprint please note — fromTaoyuan small hope to talk about technology
The first article about flexible is “Using Flexible to achieve terminal adaptation of Mobile H5 page” by Da Mo. Please read this article before you come back.
When I saw it three years ago, I thought it was Perfect and there was such a magical operation. However, when I went deeper into the principle, I could not understand it clearly. When I recommended it to other students, I could not explain some details clearly. It’s because I don’t have a deep understanding of the question “Why is this solution happening?” .
How is REM calculated?
This solution is inspired by the unit vw, where 100vw equals the width of the device, regardless of the specific pixel, something like 100 percent. But percentages don’t solve the aspect ratio problem.
Rem unit is based on font size of the root node, so you can hack the vw effect by dynamically calculating the font size of the root node by dividing it by 100 pieces according to the width of the device.
1vw = (ClietWidth/100)= htmlFontSize = 1rem
Copy the code
Flexible splits the page into 10 pieces, why not 100 pieces like vw units? Take iPhone4 for example, the width is 320px, if it is 100, 1rem=3.2px. Currently, most browsers do not support font sizes below 12px, so 320/12=26.67, the page can be divided into 26 portions at most, which is convenient to calculate the integer 10, 1rem=(320/10)=32px.
What does DPR do?
Take a look at the actual pixels of the device versus the CSS pixels.
Before the iphone4 there was no retina screen, and one device pixel was equal to one CSS pixel. The first mobile sites were designed to be 240px or 320px, and the iphone3GS was 320px, so at 640px on the iPhone4, half of the site would look weird. Even if manufacturers automatically scale the entire site to fit the screen, it won’t solve the problem of fixed pixels.
Considering this impact, iPhone4’s physical pixel ratio (devicePixelRatio) is DPR =2, which doubles the width and height of a pixel. The phone has enlarged the display of the website at the bottom, so that the screen is still 320px for the original website.
What can a viewport change do?
This is the key code for calculating REM
var docEl = document.documentElement
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
Copy the code
ClientWidth is the visible width of the root element, if viewPort scale=1.0 then for iPhone4 clientWidth=320px, if scale=0.5 then clientWidth=640px, No matter how you change the viewPort value, REM is equal to 1/10 of the visible width of the root node.
There is a paragraph in the old version 0.3.2.
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// On iOS, use 2x for 2 and 3 screens, and 1x for the rest
if (devicePixelRatio >= 3&& (! dpr || dpr >=3)) {
dpr = 3;
} else if (devicePixelRatio >= 2&& (! dpr || dpr >=2)) {
dpr = 2;
} else {
dpr = 1; }}else {
// For other devices, use the same 1 times scheme
dpr = 1;
}
scale = 1 / dpr;
Copy the code
Dynamically calculating the scale does not affect rem calculations. The advantage is that it solves the 1px problem. The disadvantage is that it destroys CSS media. Older versions of Android don’t support HD solutions, which is a bug.
In the new version 2.0, the dynamic calculation of scale is removed. Instead, the feature of 0.5px is checked and the class name hairlines is added to make it compatible
/ / detect 0.5 px supports
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
Copy the code
What is the connection between effect drawing and REM calculation?
1rem=clientWidth/10 in CSS, the common correlation between renderings and device pixel calculation is that the screen is divided into 10 parts, so 1rem=(640/10)=64px in iphone4 renderings. So CSS conversion base is always width/10.
conclusion
This article is mainly a record of thinking about why this is done. I hope there are more questions to ponder.
Now Taobao home has also upgraded the adaptation plan to embrace the real VW. Refer to Desert’s later article “Retalking about the adaptation of mobile Terminal pages”