0

0

移动端页面开发适配 rem布局原理

高洛峰

高洛峰

发布时间:2016-11-21 17:41:31

|

1649人浏览过

|

来源于php中文网

原创

移动端页面开发适配 rem布局原理

什么是适配,为什么要适配

我们拿到的设计图一般是以640,750,1080分辨率为基准设计的,而现在的手机终端各式各样,分辨率不同,逻辑像素不同 ,视口不同,所以为了让我们的页面在每个设备上都可以良好的展示,那么就需要为这些设备做统一的处理,这个过程就称为移动端适配。

需要知道的一些概念:

物理像素(physical pixel)

一个物理像素是显示器(手机屏幕)上最小的物理显示单元,可以理解为我们平时说的分辨率。

设备独立像素(density-independent pixel)

设备独立像素(也叫密度无关像素),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素,在这里可以理解为我们说的视觉视口的大小;

所以说,物理像素和设备独立像素之间存在着一定的对应关系,这就是接下来要说的设备像素比。

设备像素比(device pixel ratio)

设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到:设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向

设备像素比也是设备生产的时候设置好的,在javascript中,可以通window.devicePixelRatio获取到当前设备的dpr。

视口(viewport)

pc端视口指浏览器窗口内的内容区域,不包含工具条,滚动条.

移动浏览器中视口分为几种情况:

中content所设置的视口,称为布局视口,最大值由浏览器厂商规定 ,可以document.documentElement.clientWidth获取其宽度.

而我们看到的浏览器的窗口,网页区域的大小,称为视觉视口,用css像素表示(设备逻辑像素)

rem

rem是css3 的一个长度单位 ,相对文档跟元素 html;比如设置html font-size=100px;那么1rem=100px;之后的所有元素都可以用这个基准值来设置大小;

常用的方案:

固定高度,宽度自适应(百分比,em)

使用 rem布局

下面总结了网易 淘宝首页使用rem的方案

网易的做法:

1) 将布局适口设置为视觉视口,不进行缩放,即理想视口。

Difeye-敏捷的轻量级PHP框架
Difeye-敏捷的轻量级PHP框架

Difeye是一款超轻量级PHP框架,主要特点有: Difeye是一款超轻量级PHP框架,主要特点有: ◆数据库连接做自动主从读写分离配置,适合单机和分布式站点部署; ◆支持Smarty模板机制,可灵活配置第三方缓存组件; ◆完全分离页面和动作,仿C#页面加载自动执行Page_Load入口函数; ◆支持mysql,mongodb等第三方数据库模块,支持读写分离,分布式部署; ◆增加后台管理开发示例

下载
document.documentElement.style.fontSize =document.documentElement.clientWidth / 6.4 + ‘px’

5) 通过mediaQuery 设置字体大小,字体大小不可以使用rem,原因是误差太大。

以640的设计稿为例最终的设置html font-size代码如下,布局时拿设计稿标注的尺寸除以100,就是rem的值,相当简单啊

var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 640) deviceWidth = 640;
document.documentElement.style.fontSize = deviceWidth / 6.4 + 'px';

这里if(deviceWidth > 640) deviceWidth = 640; 是因为当deviceWidth大于640时物理分辨率已经大于1280(取决于dpr),应该去访问pc的网站;

淘宝的做法:

原理

1) 通过dpr设置缩放比,实现布局视口大小,

var scale = 1 / devicePixelRatio;  
 document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale='+ scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

2) 动态计算html的font-size

document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + ‘px’;

这里的意思是,clientWidth / 10 得到是布局视口下的rem基准值(以iphone6为例 1rem=75px),那么设计稿正好也是 750,所以对应的关系 clientWidth / 10==设计稿的尺寸/x, 那么x=设计稿的尺寸/rem基准值。如果是iphone6 plus rem基准值等于clientWidth / 10 等于124124.2,那么x=750/124124.2。

关于具体的实现 淘宝提供了一个开源的方案lib-flexible:https://github.com/amfe/lib-flexible

具体逻辑 :

1)判断head中是否设置了viewport,如果有设置,按照已有viewport 设置缩放比;

if (metaEl) {
        console.warn('将根据已有的meta标签来设置缩放比例');
        var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
        if (match) {
            scale = parseFloat(match[1]);
            dpr = parseInt(1 / scale);
        }
    }

2)如果没有设置meta viewport,判断是否设置dpr,如果有,通过dpr计算缩放scale。

        var content = flexibleEl.getAttribute('content');
        if (content) {
            var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
            var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);//maximum 设置最大值,与initial的值比较,取最小值;
            if (initialDpr) {
                dpr = parseFloat(initialDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));    
            }
            if (maximumDpr) {
                dpr = parseFloat(maximumDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));    
            }
        }

3)如果 dpr &scale都没有设置,那么就通过设备的dpr设置起缩放 scale,

if (!dpr && !scale) {//meta[name="viewport"]&&meta[name="flexible"]都不存在。
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
        // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
            dpr = 3;
        } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
            dpr = 2;
        } else {
            dpr = 1;
        }
    } else {
        // 其他设备下,仍旧使用1倍的方案
        dpr = 1;
    }
    scale = 1 / dpr;
}

4)得到scale之后 ,如果meta 的viewport不存在,那么就创建一meta[name=“viewport”],将scale配置进去。

    metaEl = doc.createElement('meta');
    metaEl.setAttribute('name', 'viewport');
    metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

    if (docEl.firstElementChild) {

        docEl.firstElementChild.appendChild(metaEl);
         
    }

5)动态改写html的font-size

    var width = docEl.getBoundingClientRect().width;//获取html的宽度
    if (width / dpr > 540) {//判断屏幕逻辑像素大于540时,取540
        width = 540 * dpr;
    }
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;

总结:

使用rem布局,实质都是通过动态改写html的font-size基准值,来实现不同设备下的良好统一适配;

网易与淘宝不同 的地方是 ,网易将布局视口设置成了 视觉视口,淘宝将布局视口设置成了物理像素大小,通过 scale缩放嵌入了 视觉视口中;

容器元素的字体大小都不使用rem,需要额外的media查询;

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

12

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

4

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

18

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

19

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

HTML5/CSS3/JavaScript/ES6入门课程
HTML5/CSS3/JavaScript/ES6入门课程

共102课时 | 6.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号