移动端页面适配

 Web前端     |      2019-11-21

询问实际的『REM』手提式无线电话机荧屏适配

2016/11/22 · CSS · 4 评论 · 太阳城申博娱乐官网,rem

原稿出处: hbxeagle移动端页面适配。   

rem 作为八个低调的尺寸单位,由于手提式有线电话机端网页的勃兴,在显示屏适配中获得重用。使用 rem 前端开采者能够很方便的在各个显示屏尺寸下,通过等比缩放的主意完结设计图必要的功用。

rem 的合法概念『The font size of the root element.』,即以根节点的字体大小作为基准值举行长度总括。平时以为网页中的根节点是 html 成分,所以利用的点子也是经过安装 html 元素的 font-size 来做荧屏适配,但实际上意况真有这么轻巧吗?

首先我们来拜会使用 rem 完毕手提式无线电话机屏幕适配的常用方案。

以设计稿的大幅度为640px,即:designWidth = 640,同期设定在640px屏宽下 1rem=100px ,即:rem2px = 100

设置 1rem=100px 的帮助和益处显而易见。前端开荒者在切图、重构页面包车型客车时候,通过直接位移小数点的方法,就足以将UI图中测量到的 px 值换算成对应的 rem 值,方便火速。

此外,在 head 中大家还设置了:<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
viewport 的作用十分重大,但不是本文的重要所以不举行,有意思味的同学能够活动物检疫索。

先来看看现实方案:

下边八个方案来自同事分享,原理都以使用等比缩放的不二秘诀 —— 获得目的显示器宽度和设计稿宽度的比,作为 rem 的基值(缩放全面卡塔 尔(英语:State of Qatar),设置为html标签的字体大小。分歧的只是在于质量取舍和书写习贯。

谈到活动端适配可能会有过多适配方案。

方案1

JavaScript

@media screen and (min-width: 320px) {html{font-size:50px;}} @media screen and (min-width: 360px) {html{font-size:56.25px;}} @media screen and (min-width: 375px) {html{font-size:58.59375px;}} @media screen and (min-width: 400px) {html{font-size:62.5px;}} @media screen and (min-width: 414px) {html{font-size:64.6875px;}} @media screen and (min-width: 440px) {html{font-size:68.75px;}} @media screen and (min-width: 480px) {html{font-size:75px;}} @media screen and (min-width: 520px) {html{font-size:81.25px;}} @media screen and (min-width: 560px) {html{font-size:87.5px;}} @media screen and (min-width: 600px) {html{font-size:93.75px;}} @media screen and (min-width: 640px) {html{font-size:100px;}} @media screen and (min-width: 680px) {html{font-size:106.25px;}} @media screen and (min-width: 720px) {html{font-size:112.5px;}} @media screen and (min-width: 760px) {html{font-size:118.75px;}} @media screen and (min-width: 800px) {html{font-size:125px;}} @media screen and (min-width: 960px) {html{font-size:150px;}}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@media screen and (min-width: 320px) {html{font-size:50px;}}
@media screen and (min-width: 360px) {html{font-size:56.25px;}}
@media screen and (min-width: 375px) {html{font-size:58.59375px;}}
@media screen and (min-width: 400px) {html{font-size:62.5px;}}
@media screen and (min-width: 414px) {html{font-size:64.6875px;}}
@media screen and (min-width: 440px) {html{font-size:68.75px;}}
@media screen and (min-width: 480px) {html{font-size:75px;}}
@media screen and (min-width: 520px) {html{font-size:81.25px;}}
@media screen and (min-width: 560px) {html{font-size:87.5px;}}
@media screen and (min-width: 600px) {html{font-size:93.75px;}}
@media screen and (min-width: 640px) {html{font-size:100px;}}
@media screen and (min-width: 680px) {html{font-size:106.25px;}}
@media screen and (min-width: 720px) {html{font-size:112.5px;}}
@media screen and (min-width: 760px) {html{font-size:118.75px;}}
@media screen and (min-width: 800px) {html{font-size:125px;}}
@media screen and (min-width: 960px) {html{font-size:150px;}}

最开的适配方案回看:

方案2

JavaScript

@media screen and (min-width: 320px) {html{font-size:312.5%;}} @media screen and (min-width: 360px) {html{font-size:351.5625%;}} @media screen and (min-width: 375px) {html{font-size:366.211%;}} @media screen and (min-width: 400px) {html{font-size:390.625%;}} @media screen and (min-width: 414px) {html{font-size:404.2969%;}} @media screen and (min-width: 440px) {html{font-size:429.6875%;}} @media screen and (min-width: 480px) {html{font-size:468.75%;}} @media screen and (min-width: 520px) {html{font-size:507.8125%;}} @media screen and (min-width: 560px) {html{font-size:546.875%;}} @media screen and (min-width: 600px) {html{font-size:585.9375%;}} @media screen and (min-width: 640px) {html{font-size:625%;}} @media screen and (min-width: 680px) {html{font-size:664.0625%;}} @media screen and (min-width: 720px) {html{font-size:703.125%;}} @media screen and (min-width: 760px) {html{font-size:742.1875%;}} @media screen and (min-width: 800px) {html{font-size:781.25%;}} @media screen and (min-width: 960px) {html{font-size:937.5%;}}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@media screen and (min-width: 320px) {html{font-size:312.5%;}}
@media screen and (min-width: 360px) {html{font-size:351.5625%;}}
@media screen and (min-width: 375px) {html{font-size:366.211%;}}
@media screen and (min-width: 400px) {html{font-size:390.625%;}}
@media screen and (min-width: 414px) {html{font-size:404.2969%;}}
@media screen and (min-width: 440px) {html{font-size:429.6875%;}}
@media screen and (min-width: 480px) {html{font-size:468.75%;}}
@media screen and (min-width: 520px) {html{font-size:507.8125%;}}
@media screen and (min-width: 560px) {html{font-size:546.875%;}}
@media screen and (min-width: 600px) {html{font-size:585.9375%;}}
@media screen and (min-width: 640px) {html{font-size:625%;}}
@media screen and (min-width: 680px) {html{font-size:664.0625%;}}
@media screen and (min-width: 720px) {html{font-size:703.125%;}}
@media screen and (min-width: 760px) {html{font-size:742.1875%;}}
@media screen and (min-width: 800px) {html{font-size:781.25%;}}
@media screen and (min-width: 960px) {html{font-size:937.5%;}}

1.if(/Android (d+.d+)/.test(navigator.userAgent)){

*                var version = parseFloat(RegExp.$1);*

*                if(version>2.3){*

*                                var phoneScale = parseInt(window.screen.width) / 640;*

*                                document.write('');*

*               }else{*

*                                  document.write('');*

*             }*

}else{

*            document.write('');*

}

方案3

JavaScript

var designWidth = 640, rem2px = 100; document.documentElement.style.fontSize = ((window.innerWidth / designWidth) * rem2px) + 'px';

1
2
3
var designWidth = 640, rem2px = 100;
document.documentElement.style.fontSize =
  ((window.innerWidth / designWidth) * rem2px) + 'px';

上面包车型大巴这种艺术辛亏,让开采者能够符合规律以px单位去写移动端。假诺您用火狐测量试验就能发掘,因为userAgent检测不到Android的时候你写的东西在火狐测量检验上会乱掉。

方案4

JavaScript

var designWidth = 640, rem2px = 100; document.documentElement.style.fontSize = ((((window.innerWidth / designWidth) * rem2px) / 16) * 100) + '%';

1
2
3
var designWidth = 640, rem2px = 100;
document.documentElement.style.fontSize =
  ((((window.innerWidth / designWidth) * rem2px) / 16) * 100) + '%';

为了轮更制度止精晓上的混乱,笔者在地方js的代码中加了 ( ) ,实际代码中是没有必要的。

详细分析一下,rempx 直接的转变公式能够写为:

JavaScript

1rem = 1 * htmlFontSize

1
1rem = 1 * htmlFontSize

htmlFontSizehtml 成分的字体大小。

第一来看方案1中,在屏宽为640px动静下的装置:

JavaScript

@media screen and (min-width: 640px) {html{font-size:100px;}}

1
@media screen and (min-width: 640px) {html{font-size:100px;}}

能够很显著的变现出那一点 1rem = 1 * 100px ,同大家开始时期的设定。那么我们要获取任何显示器大小的 htmlFontSize 值要怎么做。很简单如方案3,因为大家的施用等比缩放的章程适配,所以测算目的显示器宽度和设计稿的宽度的比就可以:

JavaScript

window.innerWidth / designWidth * rem2px + 'px'

1
window.innerWidth / designWidth * rem2px + 'px'

由于浏览器暗中认可字体大小为 16px,所以当大家选取比例作为根节点 html 的字体大时辰,即html元素的font-size值设置为三个百分比率,rem 的乘除办法就能改为:

JavaScript

defaultFontSize = 16px 1rem = 1 * htmlFontSize * defaultFontSize

1
2
defaultFontSize = 16px
1rem = 1 * htmlFontSize * defaultFontSize

如方案第22中学,在屏宽为640px情状下的设置:

JavaScript

@media screen and (min-width: 640px) {html{font-size:625%;}}

1
@media screen and (min-width: 640px) {html{font-size:625%;}}

应用方面包车型地铁公式:

JavaScript

1rem = 1 * 625% * 16px 其中:625% * 16 = 6.25 * 16 = 100 所以:1rem = 1 * 100px

1
2
3
1rem = 1 * 625% * 16px
其中:625% * 16 = 6.25 * 16 = 100
所以:1rem = 1 * 100px

平等的能够赢得全部显示器尺寸下,htmlfont-size 值的计算公式,即为方案4:

JavaScript

window.innerWidth / designWidth * rem2px / 16 * 100 + '%'

1
window.innerWidth / designWidth * rem2px / 16 * 100  + '%'

经过方案3和方案4的公式,就可以异常低价的变动方案1和方案第22中学的css。

此地只交付了方案3和方案4对应辨证页面(方案1和方案2是它们的变形卡塔 尔(英语:State of Qatar): scheme3.html, scheme4.html

如上面两张图,是在屏宽为360px下的效果与利益,通过总括指标为:1rem = 56.25px。方案3设置值为:56.25px,方案4设置值为:351.5625%

方案3 方案4

到近些日子甘休貌似很圆满的减轻了难点,实际处境当然是出现了奇异。在某个Android 手提式有线电话机上,浏览器或 webview 的默许字体是随着系统设置的书体制改过变的。那样就能导致暗许字体大于或小于 16px

修正暗中同意字体大小后,大家再看方案3和方案4。

相同在屏宽为360px下,大家调大要系字体大小,如上边包车型客车功能

设置前 html 成分的书体大小的计算值18px ,设置后的计算值65px ,由于荧屏宽度未有退换,大家的目的值,即我们在 html 成分上安装的 font-size 值也并未变动任然为 56.25px,而最终计算值出现了错误。

方案3 方案4

浅析偏差前,先来看在360px屏宽下,方案3和方案4的酌量进度:

方案3:

JavaScript

document.documentElement.style.fontSize = 56.25px htmlFontSize = 56.25px 1rem = 1 * htmlFontSize = 56.25px 实际为: 1rem = 64.6875px

1
2
3
4
5
document.documentElement.style.fontSize = 56.25px
htmlFontSize = 56.25px
1rem = 1 * htmlFontSize = 56.25px
实际为:
1rem = 64.6875px

方案4:

JavaScript

document.documentElement.style.fontSize = 351.5625% htmlFontSize = 351.5625% defaultFontSize = 18px 1rem = 1 * htmlFontSize * defaultFontSize = 351.5625% * 18px = 63.28125px 351.5625% * 18 = 63.28125 实际为: 1rem = 64.6875px

1
2
3
4
5
6
7
document.documentElement.style.fontSize = 351.5625%
htmlFontSize = 351.5625%
defaultFontSize = 18px
1rem = 1 * htmlFontSize * defaultFontSize = 351.5625% * 18px = 63.28125px
351.5625% * 18 = 63.28125
实际为:
1rem = 64.6875px

相像方案4的乘除结果很相符实效,而方案3偏差相当大。再来相比方案3和方案4的总计公式:

JavaScript

// 方案3 document.documentElement.style.fontSize = window.innerWidth / designWidth * rem2px + 'px'; // 方案4 document.documentElement.style.fontSize = window.innerWidth / designWidth * rem2px / 16 * 100 + '%';

1
2
3
4
5
6
7
// 方案3
document.documentElement.style.fontSize =
  window.innerWidth / designWidth * rem2px + 'px';
 
// 方案4
document.documentElement.style.fontSize =
  window.innerWidth / designWidth * rem2px / 16 * 100 + '%';

方案4较于方案3实际多除了一个16,可以推论浏览器在计算 rem 的具体值时,尽管 html 设置的 font-sizepx 值时会先除以 16 ,然后再乘以 htmlFontSize

JavaScript

1rem = 1 * (56.25px / 16) * 18 1 * (56.25 / 16) * 18 = 63.28125

1
2
1rem = 1 * (56.25px / 16) * 18
1 * (56.25 / 16) * 18 = 63.28125

方案4留慰劳题,是因为系统的暗许字体制改正为了 18px ,不过我们在测算比例是时候,照旧以 16px 为基准值实行计算,所以现身谬误(总括值和实际值之间还应该有一点差错这么些在前面会涉及卡塔 尔(英语:State of Qatar)。

而在方案3中,大家其实是不思虑浏览器默许字体大小的,但在实质上运用的经过中,浏览器照旧除了 16 ,而那时暗许字体大小为 18px。得出如下在 htmlfontSize 设置为 px 的图景下 rem 的总括公式为:

JavaScript

1rem = 1 * (htmlFontSize / 16) * defaultFontSize

1
1rem = 1 * (htmlFontSize / 16) * defaultFontSize

在系统安装的字体大小爆发变动时,defaultFontSize 会跟着变动,而 16 不会转移。所以方案3尽管外表上不考虑暗许字体大小的变动,只关注显示屏与设计稿之间的幅度比,但在实际计算中如故选择到了暗中同意字体大小,而且还可能有叁个不改变的 16 在添乱,引致方案3未果。

所谓的「root element」其实不是想象的那么,一个是16,一个是18,到底取的是十一分 root element 的字体大小。

ok,rem 的总结的时候,px 的主意会有多少个16不随系统字体大小退换,所以大家接收百分比的方案,绕开那几个标题。

利用百分比的方案4因为在测算时写死了暗中同意字体大小 16px。所以它的差错在于未能动态的拿到私下认可字体大小。更新如下:

方案4.1

JavaScript

var designWidth = 640, rem2px = 100; var h = document.getElementsByTagName('html')[0]; var htmlFontSize = parseFloat(window.getComputedStyle(h, null) .getPropertyValue('font-size')); document.documentElement.style.fontSize = window.innerWidth / designWidth * rem2px / htmlFontSize * 100 + '%';

1
2
3
4
5
6
7
var designWidth = 640, rem2px = 100;
var h = document.getElementsByTagName('html')[0];
var htmlFontSize = parseFloat(window.getComputedStyle(h, null)
                                    .getPropertyValue('font-size'));
 
document.documentElement.style.fontSize =
  window.innerWidth / designWidth * rem2px / htmlFontSize * 100 + '%';

功能如下图:

16px 的图中,设置后的 htmlfont-size1rem 的实在值有差错,同失常间 6.4rem 的计算值也可能有错误。通过翻看代码发现htmlfont-size行使的是: getPropertyValue('font-size')1rem 使用的是getPropertyValue('width'),偏差出在计算 font-size 的时候浏览器举行了四舍五入。rem 定义中的另三个因素「font size」也不可能按字面意思使用,发表失守。

18px 中的偏差,以致上文中方案4在 18px 实际值和计算值现身的错误都以同等的标题。所以基准值还索要改善。

16px 18px

在更新意气风发版,方案4.2:

JavaScript

var designWidth = 640, rem2px = 100; var d = window.document.createElement('div'); d.style.width = '1rem'; d.style.display = "none"; var head = window.document.getElementsByTagName('head')[0]; head.appendChild(d); var defaultFontSize = parseFloat(window.getComputedStyle(d, null).getPropertyValue('width')); d.remove(); document.documentElement.style.fontSize = window.innerWidth / designWidth * rem2px / defaultFontSize * 100 + '%';

1
2
3
4
5
6
7
8
9
10
var designWidth = 640, rem2px = 100;
var d = window.document.createElement('div');
d.style.width = '1rem';
d.style.display = "none";
var head = window.document.getElementsByTagName('head')[0];
head.appendChild(d);
var defaultFontSize = parseFloat(window.getComputedStyle(d, null).getPropertyValue('width'));
d.remove();
document.documentElement.style.fontSize =
  window.innerWidth / designWidth * rem2px / defaultFontSize * 100 + '%';

效果与利益如下图:

16px 18px

到此甘休,rem 在暗许字体不是 16px 的意况下的管理已经清除,思谋到还应该有设计显示器旋转,最终手提式有线电话机端的施工方案为:

JavaScript

function adapt(designWidth, rem2px){ var d = window.document.createElement('div'); d.style.width = '1rem'; d.style.display = "none"; var head = window.document.getElementsByTagName('head')[0]; head.appendChild(d); var defaultFontSize = parseFloat(window.getComputedStyle(d, null).getPropertyValue('width')); d.remove(); document.documentElement.style.fontSize = window.innerWidth / designWidth * rem2px / defaultFontSize * 100 + '%'; var st = document.createElement('style'); var portrait = "@media screen and (min-width: "+window.innerWidth+"px) {html{font-size:"+ ((window.innerWidth/(designWidth/rem2px)/defaultFontSize)*100) +"%;}}"; var landscape = "@media screen and (min-width: "+window.innerHeight+"px) {html{font-size:"+ ((window.innerHeight/(designWidth/rem2px)/defaultFontSize)*100) +"%;}}" st.innerHTML = portrait + landscape; head.appendChild(st); return defaultFontSize }; var defaultFontSize = adapt(640, 100);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function adapt(designWidth, rem2px){
  var d = window.document.createElement('div');
  d.style.width = '1rem';
  d.style.display = "none";
  var head = window.document.getElementsByTagName('head')[0];
  head.appendChild(d);
  var defaultFontSize = parseFloat(window.getComputedStyle(d, null).getPropertyValue('width'));
  d.remove();
  document.documentElement.style.fontSize = window.innerWidth / designWidth * rem2px / defaultFontSize * 100 + '%';
  var st = document.createElement('style');
  var portrait = "@media screen and (min-width: "+window.innerWidth+"px) {html{font-size:"+ ((window.innerWidth/(designWidth/rem2px)/defaultFontSize)*100) +"%;}}";
  var landscape = "@media screen and (min-width: "+window.innerHeight+"px) {html{font-size:"+ ((window.innerHeight/(designWidth/rem2px)/defaultFontSize)*100) +"%;}}"
  st.innerHTML = portrait + landscape;
  head.appendChild(st);
  return defaultFontSize
};
var defaultFontSize = adapt(640, 100);

回过头来再看 rem 的定义,『The font size of the root element.』。我们以为的 root element —— html 其实还会有个黑影在肇事,而作者辈以为的 font-size 其实是个雷同值。

1 赞 9 收藏 4 评论

太阳城申博娱乐官网 1

2.因此media 去 调节不一样荧屏宽度下的根成分的大小。若是设计稿的肥瘦是375,media中设置的根成分为18px,则只要多少个成分在设计稿中width为180px,则180/18=10rem

@media screen and (min-width: 320px) {

        html {

              font-size: 16px;

         }

}

@media screen and (min-width: 375px) {

            html {

                    font-size: 18px;

            }

}

@media screen and (min-width: 414px) {

       html {

              font-size: 20px;

        }

}

@media (min-width: 750px) {

      html {

          font-size: 36px;

        }

}

除此而外上述那二种方案 可能还应该有众多。下面介绍生龙活虎种非常粗大略的适配方案

假诺设计稿的肥瘦为375(iphone6),则375/100=3.75, 除以100是为着换算rem的时候轻易些

//依据JS设置根成分大小

document.documentElement.style.fontSize = deviceWidth /3.75 + 'px';

根成分如下:

太阳城申博娱乐官网 2

设若设计稿中多少个成分宽度为100px 则在编排css的时候她的 width:1rem(因为要除以100);就这样推算。在编写css的时候单位换来rem须要除以100。