移动端使⽤rem适配及相关问题
移动端适配⽅案,说多也很多。可以使⽤百分⽐布局,但百分⽐与em都是基于⽗元素进⾏计算的,在实际应⽤中不是很⽅便。使⽤rem不仅可以设置字体⼤⼩,块⼤⼩也可以设置。⽽且可以良好的适配各种终端,所以这⽅案很受欢迎。
rem定义及浏览器⽀持情况
rem(font size of the root element)是指相对于根元素的字体⼤⼩的单位。简单的说它就是⼀个相对单位。看到rem⼀定会想起em单位,em(font size of the element)是指相对于⽗元素的字体⼤⼩的单位。它们之间其实很相似,只不过⼀个计算的规则是依赖根元素⼀个是依赖⽗元素计算。可以先看看rem的浏览器⽀持情况:
1. Chrome 31-34 & Chrome-based Android versions (like 4.4) that occurs when the root element has a percentage-based size.
2. Reportedly does not work on Android 4.3 browser for Samsung Note II or the Samsung Galaxy Tab
2 on Android 4.2.
3. Borders sized in "rem" disappear when the page is zoomed out in Chrome.
4. IE 9, 10 and 11 do not support rem units when used in the "line-height" property when used on :before and :after pseudo elements
(connect.microsoft/IE/feedback/details/776744).
5. Causes content display and scrolling issues on iPhone 4 which typically has Safari 5.1.
可以看到移动端基本⽀持:
document有安卓版吗ios:6.1系统以上⽀持;
android:2.1系统以上都⽀持;
桌⾯端IE⽀持情况不乐观。
⽤法:
现代浏览器,IE9+,FireFox,Safari,Chrome,Opera,默认字体是16px,设置下根元素的字体⼤⼩为16px:
html {
font-size:16px;
}
,然后,如果希望某段⽂字的字体⼤⼩是12px,需要设置:
p {
font-size: 0.75rem; //12÷16=0.75(rem)
}
块⼤⼩的设置是类似的,所以整个布局的关键就是设置根元素的字体⼤⼩了。设置好根元素字体⼤⼩值,布局就可以做到⾃适应了。
块⼤⼩的设置,来个例⼦:
设置根元素字体⼤⼩为37.5px,在iphone6⾥⾯需要⼀个宽100px的块,就是这样了:
<!DOCTYPE html>
<html>
<meta charset="utf-8"></meta>
<head>
<title>vertical-align</title>
<style type="text/css">
html{
font-size:37.5px;
}
#contentBox{
width:2.667rem;
height:2.667rem;
background:pink;
}
</style>
</head>
<body>
<div id="contentBox">
</div>
</body>
</html>
如果在iphone5下想得到⼀个100px的块,需要设置基准值(即根元素字号)为32px。
下⾯专门谈谈rem的基准值设置。
rem基准值设置
想要rem适配不同尺⼨的设备,就需要针对不同设备设置合适的基准值,如上例所⽰。
问题来了,基准值设置成多少合适?
⼀般拿到的设计稿是375px(2倍稿)*2的,也就是iphone6的⼤⼩。那么对于iphone6来说,基准值可以设置为37.5px。即设备宽度/10。这⾥做了⼀个除以10的计算,是因为不希望font-size值太⼤。这样使⽤rem时值也不会太⼤了。
如果是iphone5,基准值就是32px。
问题⼜来了,如何根据设备尺⼨来设置基准值?
有两个⽅法,通过css media query 和js添加基准值:
css media query:
@media (min-device-width : 375px) and (max-device-width : 667px) and (-webkit-min-device-pixel-ratio : 2){
html{font-size: 37.5px;}
}
⽤media query来实现难覆盖到所有设备:
html {
font-size : 20px;
}
@media only screen and (min-width: 401px){
html {
font-size: 25px !important;
}
}
@media only screen and (min-width: 428px){
html {
font-size: 26.75px !important;
}
}
@media only screen and (min-width: 481px){
html {
font-size: 30px !important;
}
}
@media only screen and (min-width: 569px){
html {
font-size: 35px !important;
}
}
@media only screen and (min-width: 641px){
html {
font-size: 40px !important;
}
}
⽽通过js来设置,可以实现覆盖所有设备:
js来设置:
关于⽅案的利弊,其实上⾯的例⼦⾥⾯可以看出,rem为整数的时候,基准值为32px,36px这样的整数,换成px也是整数。但rem带有⼩数,⽐如1.75rem,在32px的基准只下计算得56px。那再看看其他机型的换算值:
代表机型浏览器宽对应尺⼨
iPhone 4/4s/5/5s320px56px
Samsung Note 3, Nexus 5…360px63px
iPhone 6375px65.625px
Google Nexus 6412px72.1px
iPhone 6 Plus414px72.45px
可以看出,有些机型⾥⾯是有⼩数像素值的。⼩数像素可能会带来⼀定的误差,设计的同事像素眼很容易觉察到的。
在可以接受的情况下允许这些误差存在。在安卓机⼦上较多出现这类情况。
下⾯可以具体看下⼩数像素在浏览器⾥⾯的显⽰情况:
设置两组块,第⼀组是1.75rem*1.75rem的,第⼆组是1.85rem*1.85rem的,具体代码如下:
.block{
display:inline-block;
width:1.75rem;
height:1.75rem;
background:rgba(0,0,255, .5);
}
.block:nth-of-type(2n){
background:rgba(255,0,0, .5);
}
.
group2 .block{
widrh:1.85rem;
height:1.85rem;
}
效果图是
看下第⼀组块,在iPhone6下,每个块的尺⼨应该是:1.75*37.5=65.625px;
但实际情况:
是的,浏览器会显⽰为65px或66px,⽽且没有规律的来显⽰。
这看起来有点不可思议,按道理来说,浏览器似乎应该全部舍弃⼩数65px,或者保留到66px,可事实却不是这样的。
到这⾥,可以假设:浏览器所做的渲染处理只是作⽤在元素的渲染尺⼨上,但他们的真实尺⼨仍是原始尺⼨⼤⼩。
举个实际的例⼦来说,就是⼀个元素的尺⼨是0.625px,他的渲染尺⼨是1px,剩下的0.375px由临近元
素填充;同理,如果⼀个元素是0.375px,其渲染尺⼨是0px,但是会占有临近元素0.375px的空间。
然后带着这个假设分析下上⾯的例⼦:
第⼀个块的宽度为 65.625px,根据四舍五⼊的原则其最终渲染尺⼨为 66px,空出的 0.375px 由第⼆个块补上;
第⼆个块向左补进 0.375px,相当于减少了 0.375px,余下 65.25px,根据四舍五⼊的原则其最终渲染尺⼨为 65px,多出的 0.25px 会占⽤第三个⾊的空间;
第三个块被占⽤了 0.25px,相当于增加了 0.25px,等于 65.875px,根据四舍五⼊的原则其最终渲染尺⼨为 66px,空出的 0.125px 由第四个块补上;
第四个块向左补进 0.125px,相当于减少了 0.125px,余下 65.5px,根据四舍五⼊的原则其最终渲染尺⼨为 66px,空出的 0.5px 由第五个块补上;
第五个块向左补进 0.5px,相当于减少了 0.5px,余下 65.125px,根据四舍五⼊的原则其最终渲染尺⼨为 65px,多出 0.125px;
这与浏览器的输出结果是⼀致的,印证了猜想。
更具体的浏览器处理可以看
其他适配⽅案
也可以采⽤固定布局:
1.在viewport meta标签上设置width=320,页⾯的各个元素也采⽤px作为单位。通过⽤JS动态修改标签的initial-scale使得页⾯等⽐缩放,从⽽刚好占满整个屏幕。
<meta name="viewport" content="width=320,user-scalable=no">
<也可以使⽤⾃⼰设置viewport和content的⽅法来适配,以⽅便计算和设置值:
例如:
meta.setAttribute('content', 'initial-scale=' + 1/dpr + ', maximum-scale=' + 1/dpr + ', minimum-scale=' + 1/dpr + ', user-scalable=no');
其中dpr通过window.devicePixelRatio获取,iphone6的值是2.
对于2倍稿,可以直接设置基准值为2倍,这样就不⽤设计稿的值除以2了。
iphone6适配的设计稿750px,基准值设置为75px就可以了。
修改了缩放倍数之后,1px边线的问题也同时解决了。
代码:
<!DOCTYPE html>
<html>
<meta charset="utf-8"></meta>
<meta name="viewport" content="" id="viewMeta">
<head>
<title>vertical-align</title>
<style type="text/css">
html{
font-size:75px;
}
#contentBox{
width:2.667rem;
height:2.667rem;
background:pink;
border:1px solid #000;
}
</style>
</head>
<body>
<div id="contentBox">
</div>
</body>
<script type="text/javascript">
var meta = ElementById('viewMeta');
var dpr = window.devicePixelRatio;
meta.setAttribute('content', 'initial-scale=' + 1/dpr + ', maximum-scale=' + 1/dpr + ', minimum-scale=' + 1/dpr + ', user-scalable=no'); </script>
</html>
图图:
参考:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。