Due to the particularity of the mobile terminal, this article describes how to use rem to achieve self-adaptation, or the rem responsive layout. By using a script, you can use rem adaptive, there is no need to worry about how to implement self-adaptation for different device widths.
Rem is relative to the root element
Implementation method:
JavaScript is used to adjust the html font size, while the preparation in the page uses the rem unit for production. The key code is as follows:
; (Function (win, lib ){
Var doc = win.doc ument;
Var docEl = doc.doc umentElement;
Var metaEl = doc. querySelector ('meta [name = "viewport"] ');
Var flexibleEl = doc. querySelector ('meta [name = "flexible"] ');
Var dpr = 0;
Var scale = 0;
Var tid;
Var flexible = lib. flexible | (lib. flexible = {});
If (metaEl ){
Console. warn ('The scaling ratio will be set based on the existing meta tags ');
Var match = metaEl. getAttribute ('content'). match (/initial \-scale = ([\ d \.] + )/);
If (match ){
Scale = parseFloat (match [1]);
Dpr = parseInt (1/scale );
}
} Else if (flexibleEl ){
Var content = flexibleEl. getAttribute ('content ');
If (content ){
Var initialDpr = content. match (/initial \-dpr = ([\ d \.] + )/);
Var maximumDpr = content. match (/maximum \-dpr = ([\ d \.] + )/);
If (initialDpr ){
Dpr = parseFloat (initialDpr [1]);
Scale = parseFloat (1/dpr). toFixed (2 ));
}
If (maximumDpr ){
Dpr = parseFloat (maximumDpr [1]);
Scale = parseFloat (1/dpr). toFixed (2 ));
}
}
}
If (! Dpr &&! Scale ){
Var isAndroid = win. navigator. appVersion. match (/android/gi );
Var isIPhone = win. navigator. appVersion. match (/iphone/gi );
Var devicePixelRatio = win. devicePixelRatio;
If (isIPhone ){
// For iOS screens 2 and 3, use a 2x scheme, and the rest use a 1x scheme.
If (devicePixelRatio >=3 &&(! Dpr | dpr> = 3 )){
Dpr = 3;
} Else if (devicePixelRatio> = 2 &&(! Dpr | dpr> = 2 )){
Dpr = 2;
} Else {
Dpr = 1;
}
} Else {
// The solution is doubled for other devices.
Dpr = 1;
}
Scale = 1/dpr;
}
DocEl. setAttribute ('data-dpr', dpr );
If (! MetaEl ){
MetaEl = doc. createElement ('meta ');
MetaEl. setAttribute ('name', 'viewport ');
MetaEl. setAttribute ('content', 'initial-scale = '+ scale +', maximum-scale = '+ scale +', minimum-scale = '+ scale + ', user-scalable = no ');
If (docEl. firstElementChild ){
DocEl. firstElementChild. appendChild (metaEl );
} Else {
Var wrap = doc. createElement ('div ');
Wrap. appendChild (metaEl );
Doc. write (wrap. innerHTML );
}
}
Function refreshRem (){
Var width = docEl. getBoundingClientRect (). width;
If (width/dpr & gt; 540 ){
Width = 540 * dpr;
}
Var rem = width/10;
DocEl. style. fontSize = rem + 'px ';
Flexible. rem = win. rem = rem;
}
Win. addEventListener ('resize', function (){
ClearTimeout (tid );
Tid = setTimeout (fig, 300 );
}, False );
Win. addEventListener ('pageshow ', function (e ){
If (e. persisted ){
ClearTimeout (tid );
Tid = setTimeout (fig, 300 );
}
}, False );
If (doc. readyState = 'complete '){
Doc. body. style. fontSize = 12 * dpr + 'px ';
} Else {
Doc. addEventListener ('domainloaded', function (e ){
Doc. body. style. fontSize = 12 * dpr + 'px ';
}, False );
}
RefreshRem ();
Flexible. dpr = win. dpr = dpr;
Flexible. refreshRem = refreshRem;
Flexible. rem2px = function (d ){
Var val = parseFloat (d) * this. rem;
If (typeof d ==== 'string' & d. match (/rem $ /)){
Val + = 'px ';
}
Return val;
}
Flexible. px2rem = function (d ){
Var val = parseFloat (d)/this. rem;
If (typeof d ==== 'string' & d. match (/px $ /)){
Val + = 'REM ';
}
Return val;
}
}) (Window, window ['Lib'] | (window ['Lib'] = {}));
The above code mainly changes the font-size of dpx and document. The size is docEl. getBoundingClientRect (). width/10 + 'px ';
If the design draft width is 640, the html font size is set to 64px, which is equivalent to 1rem = 64px.
For example, if the width of an element is PX, we can use percentages to achieve self-adaptation. If we use a responsive method, we may need to set multiple elements, for example, in 320px, the output is 80 px, the output is 160px in 640px.
With the above rem method, you only need to output 2.5rem to achieve unification, as shown in the following table:
Device width
320px
360px
414px
640px
Html font size
32px
36px
41.4px
64px
Actual output
1rem
1rem
1rem
1rem
Scale the design draft
80px
90px
103.5px
160px
Actual output
2.5rem
2.5rem
2.5rem
2.5rem
How is the above 2.5rem obtained?
160/64 (1rem base is 64px) = 2.5rem; according to the official statement (750px example)
Flexible divides the visual draft into 100 parts (mainly for better compatibility with the VWs and VWs in the future), and each part is called a unit. At the same time, 1 rem unit is identified as 10a. For our visual draft, we can calculate the following:
1a = 7.5px
1rem = 75px
In this example, the article is divided into 10a, that is, the entire width is 10rem, and the font-size corresponding to
In this way, for the element size conversion on the visual draft, you only need to divide the original px value by the rem reference value. For example, the size of the image in this visual draft is 176px * 176px, which is converted to 2.346667rem * 2.346667rem.
In addition, Damo also wrote a detailed article: using Flexible to implement terminal adaptation to the H5 page of Shoutao introduces several methods to quickly convert rem to px, you can check out the children's shoes you are interested in.
You can also read this article: Sass function-rem to px
Another pitfall for adaptive processing is css sprite. The author suggests using svg, icon font, base64, and other solutions.
In addition, when dpr = 2, small images may be blurred. We recommend that you use the largest image to cut the image.
Px is recommended for font.
In the author's opinion, we recommend that you use px for descriptive fonts. If there are slogan and other fonts larger than 48px, you can use rem because rem is used in different fonts in iPhone 5 and iPhone 6, 13 PX and 15 PX may appear in the dot matrix font.
Obviously, we want to see the same text font size under the Retina screen of iPhone 3G and iPhone 4. That is to say, we do not want the text to shrink under the Retina screen. In addition, we want to see more text on the big screen mobile phone, and most of the font files now have their own lattice sizes, it is usually 16px and 24px, so we do not want a wonderful size like 13px and 15px.
As a result, it is determined that rem is not suitable for paragraph text on the H5 page. Therefore, in the Flexible adaptation scheme, the text should be taken as the unit of px. Only the [data-dpr] attribute is used to distinguish the text font size under different dpr.
Div {
Width: 1rem;
Height: 0.4rem;
Font-size: 12px; // fontSize with dpr 1 is written by default.
}
[Data-dpr = "2"] div {
Font-size: 24px;
}
[Data-dpr = "3"] div {
Font-size: 36px;
}
To better facilitate development, we can customize an Sass hybrid macro like font-dpr () in actual development:
@ Mixin font-dpr ($ font-size ){
Font-size: $ font-size;
[Data-dpr = "2"] & {
Font-size: $ font-size * 2;
}
[Data-dpr = "3"] & {
Font-size: $ font-size * 3;
}
}
With such a hybrid macro, you can directly use it in development as follows:
@ Include font-dpr (16px );
Of course, this is only for descriptive text, such as paragraph text. However, sometimes the text font size also needs to be divided into different scenarios. For example, if there is an slogan in the project, the business side hopes that the slogan can be adapted based on different terminals. In such a scenario, rem can be used to make measurement units for slogan.