由于日常需求以无线居多,所以可以在业务中做一些尝试,如 rem,刚接触这个特性的时候,曾经一度爱不释手,仿佛在无线开发的坎坷路上寻找到一条捷径。然而随着使用范围的扩大,慢慢的发现了一些使用 rem 带来的问题。

rem

关于 rem 这个单位的介绍,在此就不赘述,有兴趣的同学可以阅读一丝的《响应式十日谈第一日:使用 rem 设置文字大小》,文章对 rem 进行了详细的介绍。

用途

在无线开发中,响应式布局尤为重要,先不说屏幕尺寸越来越多样化的 iPhone,单是安卓就有 N 多种尺寸要适配。

在没有使用 rem 之前,想要按照设计师的想法去适配不同 分辨率1 是一件非常难操作的事情。用了 rem 以后,一切简单了许多,你可以用它来设置元素的宽高、间距…,然后针对不同的分辨率计算并设置相对应的根字体大小,然后元素就好像缩放过一样自动适应了当前的分辨率,大大的降低了适配工作量。

Demo:

上图是同一个页面在 Apple iPhone 5 和 Samsung Galaxy S4 两款机器下的效果,可以看出从 320px 宽的 iPhone 5 到 360px 宽的 S4,图片像是等比放大了一样,我们分析下这个原理:

假定2 width=320px 的分辨率下的根字体大小是 32px,由此推算:

  • width=320px 分辨率下:

    根字体大小是 32px,该分辨率下宽 1rem 的元素在浏览器里的真实宽度就是 1 * 32 = 32px;

  • width=360px 分辨率下:

    如果要达到等比放大的效果,宽 1rem 的元素在浏览器里的真实宽度就应该是 32 * (360/320) = 36px,由此得出 width=360px 分辨率下的根字体大小为 36px;

由此可见等比缩放是通过控制根字体大小来实现的,且根字体大小与屏幕宽度成正比。

小数像素

刚才举的例子里面 1rem 在 width=320px 分辨率下的真实尺寸为 32px,在 width=360px 分辨率下的真实尺寸为 36px,均为整数。

如果是 1.75rem 呢?

代表机型 浏览器宽 对应尺寸
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 x 1.75rem,第二组每个色块的大小为 1.85rem x 1.85rem;

先看第一组色块,在 iPhone 6 下,其在浏览器内的渲染尺寸应该是 1.75 * 37.5 = 65.625px;

但真实渲染尺寸却是另外一种情况:有的宽度是 66px,有的却是 65px,而且顺序上毫无规律。

这一结果让我十分疑惑,如果浏览器统一做四舍五入处理,那么所有的色块尺寸也应该是一样的,不会出现部分向上取整,部分向下取整。

思考许久无果,大胆设想了一下:浏览器在渲染时所做的舍入处理只是应用在元素的渲染尺寸上,其真实占据的空间依旧是原始大小。

也就是说如果一个元素尺寸是 0.625px,那么其渲染尺寸应该是 1px,空出的 0.375px 空间由其临近的元素填充;同样道理,如果一个元素尺寸是 0.375px,其渲染尺寸就应该是 0,但是其会占据临近元素 0.375px 的空间。于是就顺着这个思路验证了以下:

  1. 第一个色块的宽度为 65.625px,根据四舍五入的原则其最终渲染尺寸为 66px,空出的 0.375px 由第二个色块补上;
  2. 第二个色块向左补进 0.375px,相当于减少了 0.375px,余下 65.25px,根据四舍五入的原则其最终渲染尺寸为 65px,多出的 0.25px 会占用第三个色块的空间;
  3. 第三个色块被占用了 0.25px,相当于增加了 0.25px,等于 65.875px,根据四舍五入的原则其最终渲染尺寸为 66px,空出的 0.125px 由第四个色块补上;
  4. 第四个色块向左补进 0.125px,相当于减少了 0.125px,余下 65.5px,根据四舍五入的原则其最终渲染尺寸为 66px,空出的 0.5px 由第五个色块补上;
  5. 第五个色块向左补进 0.5px,相当于减少了 0.5px,余下 65.125px,根据四舍五入的原则其最终渲染尺寸为 65px,多出 0.125px;

上述验证与浏览器输出结果完全一致,表明浏览器在处理小数像素的时候并不是直接舍入处理的,元素依旧占据着应有的空间,只是在计算元素尺寸的时候做了舍入处理(后来在看到LayoutUnit – WebKit 这篇文档后,也印证了之前的假设)。

你可以参考上述原理对第二组色块进行验证,然后比对结果

问题

目前遇到最多的问题就是 background-image 的问题,经常会因为小数像素导致背景图被裁掉一部分。

上图是同一组 icon 在不同机型下的效果,可以看出这些 icon 在 iPhone 5 和 Galaxy S4 下或多或少的会被裁掉一部分,原因就是由于小数像素导致的,这点可以从元素的Computed Style 上看出。

解决

如何避免这种问题呢?以下两点建议:

  • 使用 iconfont
  • 如需使用 background-image,尽量为背景图设置一定的空白间隙,如图:

小结

小数像素产生的问题不单单只有 background-image,还会有其他尚未遇到的坑,然而在了解了浏览器是如何处理小数像素的原理以后,此类问题就变得很好解决,也非常可控。

rem 产生的小数像素问题的更多相关文章

  1. 使用rem设计移动端自适应页面一(转载)

    1.困扰多时的问题 在这之前做Web App开发的的时候,在自适应方面一般都是宽度通过百分比,高度以iPhone6跟iPhone5之间的一个平衡值写死,我们的设计稿都是iPhone5的640 * 11 ...

  2. 移动端Web App自适应布局探索

    1.困扰多时的问题 在这之前做Web App开发的的时候,在自适应方面一般都是宽度通过百分比,高度以iPhone6跟iPhone5之间的一个平衡值写死,我们的设计稿都是iPhone5的640 * 11 ...

  3. 移动端使用rem适配及相关问题

    移动端适配方案,说多也很多.可以使用百分比布局,但百分比与em都是基于父元素进行计算的,在实际应用中不是很方便.使用rem不仅可以设置字体大小,块大小也可以设置.而且可以良好的适配各种终端,所以这方案 ...

  4. 使用rem设计移动端自适应页面二(转载)

    由于日常需求以无线居多,所以可以在业务中做一些尝试,如 rem,刚接触这个特性的时候,曾经一度爱不释手,仿佛在无线开发的坎坷路上寻找到一条捷径.然而随着使用范围的扩大,慢慢的发现了一些使用 rem 带 ...

  5. 说说css中pt、px、em、rem都扮演了什么角色

    前段时间,终于仔仔细细的把pt.px.em.rem了解了一遍,简单整理了一下做个记录. pt.px.em.rem都是什么 pt单位名称为点(Point),绝对长度单位.现在网页中出现得很少甚至不出现, ...

  6. 解决移动端1px的问题,设备像素比devicePixelRatio的应用

    本文主要针对移动端1物理像素问题展开 解决这个问题先要了解一下概念: CSS像素(CSS Pixel):(通俗说:样式中写的值)就是我们在样式代码中常写的逻辑像素,是一个抽象概念,实际并不存在 设备独 ...

  7. 1px像素问题(移动端经典问题)

    1.物理像素:移动设备出厂时,不同设备自带的不同像素,也称硬件像素: 逻辑像素:即css中记录的像素 在开发中,为什么移动端CSS里面写了1px,实际上看起来比1px粗:了解设备物理像素和逻辑像素的同 ...

  8. css - rem和vw

    css - rem和vw 物理像素 物理像素在不同的设备中1px里可以容纳的像素颗粒是不相同的,所以1px这个单位其实也是有N个像素颗粒填充的.同一尺寸屏幕的每个像素点所能容纳的像素颗粒越多显示效果越 ...

  9. 何时使用 Em 与 Rem

    原文  http://www.w3cplus.com/css/when-to-use-em-vs-rem.html   你可能已经很熟练使用这两个灵活的单位,但你可能不完全了解何时使用rem,何时使用 ...

随机推荐

  1. Tomcat在Linux上的安装与配置

    以下使用的Linux版本为: Redhat Enterprise Linux 6.5 x86_64,Tomcat版本为tomcat-7.0.54. 1.下载JDK与Tomcat.    jdk下载地址 ...

  2. ASP.NET Web API 使用Swagger生成在线帮助测试文档

    Swagger-UI简单而一目了然.它能够纯碎的基于html+javascript实现,只要稍微整合一下便能成为方便的API在线测试工具.项目的设计架构中一直提倡使用TDD(测试驱动)原则来开发,sw ...

  3. 攻城狮在路上(肆)How tomcat works(二) 一个简单的servlet容器

    该节在上一节的基础上增加了所谓对静态资源和动态资源访问的不同控制流程.示例里面采用的是对路径“/servlet/”进行了特殊处理. 一. 主要还是从HttpServer1中的main方法开始,先解析出 ...

  4. wp8 入门到精通 数据库更新字段(一)

    public class UserInfoDB : BaseDB { public UserInfoDB() : base(@"Data Source=isostore:\MakeLove\ ...

  5. wp8 入门到精通 Utilities类 本地存储+异步

    public class CCSetting { public async static void AddOrUpdateValue<T>(string key, T value) { t ...

  6. 第十篇:扩展SOUI的控件及绘图对象(ISkinObj)

    尽管SOUI已经内置了大部分常用的控件,很显然内置控件很难满足各种应用的形式各异的需求. 因此只有提供足够的扩展性才能满足真实应用场景. 除了将系统尽可能的组件化外,SOUI在控件自绘(SWindow ...

  7. 使用Aspose.Cell.dll导出Excel总结

    这两天项目上用Aspose导出Excel来着.开始感觉挺简单的,但是实际操作起来还是挺复杂的,调试占的时间很长.主要是动态生成列.合并单元格.调样式占了很长时间,还是总结一下吧. 基础操作: //EX ...

  8. Codeforces Testing Round #12 C. Subsequences 树状数组

    C. Subsequences     For the given sequence with n different elements find the number of increasing s ...

  9. checkbox全选和子选

    用jq: $(function() { var $subBox = $("input[name='subBox']"); $("#checkAll").clic ...

  10. 在Android上用AChartEngine轻松绘制图表

    本文由 伯乐在线 - LeonHover 翻译.未经许可,禁止转载!英文出处:jaxenter.欢迎加入翻译组. Android发布不久的2008年底,开发者们已经开始寻找制表.制图.绘图的工具库.当 ...