移动端使用rem适配及相关问题
移动端适配方案,说多也很多。可以使用百分比布局,但百分比与em都是基于父元素进行计算的,在实际应用中不是很方便。使用rem不仅可以设置字体大小,块大小也可以设置。而且可以良好的适配各种终端,所以这方案很受欢迎。
rem定义及浏览器支持情况
rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem一定会想起em单位,em(font size of the element)是指相对于父元素的字体大小的单位。它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。可以先看看rem的浏览器支持情况:
- Chrome 31-34 & Chrome-based Android versions (like 4.4) have a font size bug that occurs when the root element has a percentage-based size.
- Reportedly does not work on Android 4.3 browser for Samsung Note II or the Samsung Galaxy Tab 2 on Android 4.2.
- Borders sized in "rem" disappear when the page is zoomed out in Chrome.
- 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 (https://connect.microsoft.com/IE/feedback/details/776744).
- Causes content display and scrolling issues on iPhone 4 which typically has Safari 5.1.
可以看到移动端基本支持:
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来设置:
document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
关于方案的利弊,其实上面的例子里面可以看出,rem为整数的时候,基准值为32px,36px这样的整数,换成px也是整数。但rem带有小数,比如1.75rem,在32px的基准只下计算得56px。那再看看其他机型的换算值:
代表机型 | 浏览器宽 | 对应尺寸 |
---|---|---|
iPhone 4/4s/5/5s | 320px | 56px |
Samsung Note 3, Nexus 5… | 360px | 63px |
iPhone 6 | 375px | 65.625px |
Google Nexus 6 | 412px | 72.1px |
iPhone 6 Plus | 414px | 72.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;
这与浏览器的输出结果是一致的,印证了猜想。
更具体的浏览器处理可以看http://trac.webkit.org/wiki/LayoutUnit
其他适配方案
也可以采用固定布局:
1.在viewport meta标签上设置width=320,页面的各个元素也采用px作为单位。通过用JS动态修改标签的initial-scale使得页面等比缩放,从而刚好占满整个屏幕。
<meta name="viewport" content="width=320,user-scalable=no">
2.rem也可以使用自己设置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 = document.getElementById('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>
图图:
参考:
移动端使用rem适配及相关问题的更多相关文章
- 前端移动端的rem适配计算原理
rem是什么? rem(font size of the root element)是指相对于根元素的字体大小的单位.简单的说它就是一个相对单位.看到rem大家一定会想起em单位,em(font si ...
- 移动端的rem适配
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Vue-cli4.xPC端项目Rem适配
适配准备 安装 (amfe-flexible) 和(postcss-px2rem) 1, 安装依赖并在main.js中引入该依赖 npm i amfe-flexible import "am ...
- 移动端rem适配屏幕
九月已成历史,十月如期而至...可能是九月工作比较清闲,周记就没怎么写,十月决不能这么堕落,立贴为证,至少保证5篇博客!!!如果没学到什么新知识,就对以往的那些工作中常用到的知识点做个总结...话不多 ...
- 自动改变html font-size,实现移动端rem适配
移动端采用rem适配非常方便 比如在iphone6尺寸下,将html font-size 设置为 100px,那么写css时,只要将尺寸/100 + rem 即可. 在iphone6Plus尺寸下,h ...
- 移动端页面开发适配 rem布局原理
主题 HTML移动端页面开发适配 rem布局原理 什么是适配,为什么要适配 我们拿到的设计图一般是以640,750,1080分辨率为基准设计的,而现在的手机终端各式各样,分辨率不同,逻辑像素不同 ,适 ...
- 基于REM的移动端响应式适配方案
视口 在前一段时间,我曾经写过一篇关于viewport的文章.最近由于在接触移动端开发,对viewport有了新的理解.于是,打算重新写一篇文章,介绍移动端视口的相关概念. 关于这篇文章说到的所有知识 ...
- H5 端 rem 适配方案与 viewport 适配
H5 端 rem 适配方案与 viewport 适配 rem rem 是 CSS3 新增的一个相对单位(root em,根 em) 只根据当前页面 HTML 页面的 font-size 设置,如果根目 ...
- 谈谈我的移动端rem适配方案
最近有点怀疑人生,毕竟一个人写前端,有时候会怀疑自己理解的一些东西包括用法有没有符合标准.趁着这阵子闲下来,翻了翻别人的rem适配博客,发现有点绕口,怪自己是个强迫症,啥都要自己去试试结果并从中理解, ...
随机推荐
- alpha 发布评论
1.飞天小女警:礼物挑选小工具. 这一组的项目是个人最为感兴趣的,核心功能的实现比较有实际意义,希望所能挑选的礼物范围尽量足够大,界面期待完善后的效果. 2.nice!:约跑app.这一款面向喜爱运动 ...
- python之列表、字典、集合
列表 name = ["Alex","Eenglan","Eric"] print(name[0]) print(name[1]) prin ...
- Angular2学习之开发环境构建
一.主要资料 http://blog.csdn.net/cz_jjq/article/details/50425206 http://www.tuicool.com/articles/mi6rmuB ...
- VS高效开发快捷键
Ctrl + Tab 标签切换 Ctrl + '-'向后导航 Ctrl + Shift+'-'向前导航 Ctrl +Shift +空格 提示函数参数 Ctrl +F4 退出本标签 Ctrl+F 查找 ...
- winform中button的image属性无法更改
在开发一个winform程序的时候,界面中的button的image本来有一个贴图A.后来我觉得不合适,打算换成贴图B. 但是这时问题出现了:虽然我改成了贴图B,在IDE中的预览也是贴图B,但是每次编 ...
- nsq
官网:http://nsq.io (1)描述 都是message broker,rabbitmq久经考验,nsq则是后起之秀.rabbitmq是erlang编写,nsq是golang. 安装:http ...
- iOS NSTimer使用详解 开启、关闭、移除
定时器定时器详解ios定时器关闭定时器NSTimer 一,要使用一个定时器首先要定义一个定时器: @property (strong, nonatomic) NSTimer *myTimer;//定时 ...
- python-program
程序需要一步步改进,解决bug,尽量从源头判断,并给出处理措施. 1.客户端执行一次,程序就退出, 2.客户端空值,错误命令,程序会死掉 3.收发缓冲区大小,即recv(1024)的问题,如果收一个1 ...
- crontab服务详解(任务计划)
crontab是一个很方便的在unix/linux系统上定时(循环)执行某个任务的程序使用cron服务,用 service crond status 查看 cron服务状态,如果没有启动则 servi ...
- [Linux] - Docker制作nginx+php
使用Docker制作nginx+php的镜像,这里的镜像是centos + nginx 1.9.7 + php 5.6.14 首先下载到nginx和php: nginx-1.9.5.tar.gz 下载 ...