移动端使用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适配博客,发现有点绕口,怪自己是个强迫症,啥都要自己去试试结果并从中理解, ...
随机推荐
- FTP上传-封装工具类
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...
- iOS应用之间调用
//// iOS应用之间调用.h// IOS笔记 1.判断系统里是否安装了某个app.比如新浪微博应用注册了URL scheme为@"weibo",我们可以通过[[UIAppl ...
- Ajax在html页面获取后台XML文件资源
一.准备工具 站长吧ASP调试工具.exe,这个工具是为了快速建立asp环境,方便调试. 二.建立文件夹 1.建立网站根文件夹,名字随意,将站长吧ASP调试工具.exe复制到根文件夹: 2.建立xml ...
- [java]wordcount程序
词数统计系统. 作业解析:这次作业的内容是从本地读取一个程序代码,计算出这个程序中的行数,单词数,也可进行拓展. 实现语言:java 编程思路: 程序是由各种单词和符号组成的,单词包括关键字,标识符这 ...
- POI2012
现在才开始写 POI 是不是太弱了? -Rendezvous 怎么说呢,我发现我的代码好长啊-长啊-长啊-长长长长长长长长长长长长长长长长长长长长长长啊- 大概就是在一个内向树上搞一个类似 lca 的 ...
- apk安全测试思路
一: apk安全测试 对于一款android的apk程序,主要进行的测试分两部分: 1) 接口测试 ---接口测试实际上是常见的web安全测试 2) android组件测试 --组件测试实际上是and ...
- j技术方案
采用.net4.0作为基础技术平台,原来是采用.net4.5的,但是后来发现.net4.5不支持Windows Server2003,所以又降为.net4.0. 1.asp.net mvc 4.0 用 ...
- 在ESXi 5.x 和 ESXi 6.0.x 中如何安装第三方供应商开发的驱动程序
在 VMware ESXi 5.x 和 ESXi 6.0.x 中如何下载并安装异步驱动程序 (2076262) Symptoms 免责声明:本文为 How to download and inst ...
- DELL_LCD错误提示代码
代码 文本 原因E1000 Failsafe voltage error. Contact support.(故障保护电压错误.请联络支持人员.) 查看系统事件记录以了解严重故障事件.E1114 Am ...
- 基于Spring Boot/Spring Session/Redis的分布式Session共享解决方案
分布式Web网站一般都会碰到集群session共享问题,之前也做过一些Spring3的项目,当时解决这个问题做过两种方案,一是利用nginx,session交给nginx控制,但是这个需要额外工作较多 ...