当前位置: 首页 > news >正文

flexable-页面自适应方案

痛点

虽然H5的页面与PC的Web页面相比简单了不少,但让我们头痛的事情是要想尽办法让页面能适配众多不同的终端设备。

前端开发完成终端适配方案

拿到设计师给的设计图之后,剩下的事情是前端开发人员的事了。而手淘经过多年的摸索和实战,总结了一套移动端适配的方案——flexible方案。

一些基本概念

视窗 viewport

简单的理解,viewport是严格等于浏览器的窗口。在桌面浏览器中,viewport就是浏览器窗口的宽度高度。但在移动端设备上就有点复杂。
移动端的viewport太窄,为了能更好为CSS布局服务,所以提供了两个viewport:虚拟的viewport(visualviewport)和布局的viewport(layoutviewport)

物理像素(physical pixel)

物理像素又被称为设备像素,他是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。正是这些设备像素的微小距离欺骗了我们肉眼看到的图像效果。

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

设备独立像素也称为密度无关像素,可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素),然后由相关系统转换为物理像素。

CSS像素

CSS像素是一个抽像的单位,主要使用在浏览器上,用来精确度量Web页面上的内容。一般情况之下,CSS像素称为设备独立像素(device-independent pixel),简称DIPs。

屏幕密度

屏幕密度是指一个设备表面上存在的像素数量,它通常以每英寸有多少像素来计算(PPI)。

设备像素比(device pixel ratio)

设备像素比简称为dpr,其定义了物理像素和设备独立像素的对应关系。它的值可以按下面的公式计算得到:

设备像素比 = 物理像素 / 设备独立像素

在JavaScript中,可以通过window.devicePixelRati获取到当前设备的dpr。而在CSS中,可以通过-webkit-device-pixel-ratio-webkit-min-device-pixel-ratio-webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)。

dip或dp,(device independent pixels,设备独立像素)与屏幕密度有关。dip可以用来辅助区分视网膜设备还是非视网膜设备。

众所周知,iPhone6的设备宽度和高度为375pt * 667pt,可以理解为设备的独立像素;而其dpr为2,根据上面公式,我们可以很轻松得知其物理像素为750pt * 1334pt

meta标签

<meta>标签有很多种,而这里要着重说的是viewport的meta标签,其主要用来告诉浏览器如何规范的渲染Web页面,而你则需要告诉它视窗有多大。在开发移动端页面,我们需要设置meta标签如下:

<metaname="viewport"content="width=device-width, initial-scale=1, maximum-scale=1">

代码以显示网页的屏幕宽度定义了视窗宽度。网页的比例和最大比例被设置为100%。

CSS单位rem

在W3C规范中是这样描述rem的:

font size of the root element.

简单的理解,rem就是相对于根元素<html>font-size来做计算。而我们的方案中使用rem单位,是能轻易的根据<html>的font-size计算出元素的盒模型大小。而这个特色对我们来说是特别的有益处。

前端实现方案

了解了前面一些相关概念之后,接下来我们来看实际解决方案。在整个手淘团队,我们有一个名叫lib-flexible的库,而这个库就是用来解决H5页面终端适配的。

flexible.js是什么?

flexible.js适配方案采用rem布局,根据屏幕分辨率大小不同,调整根元素htmlfont-size,从而达到每个元素宽高自动变化,适配不同屏幕

Vue中怎么用

安装:cnpm i lib-flexible -S
引入:import 'lib-flexible/flexible'(在main.js你懂得)
执行这个JS后,会在<html>元素上增加一个data-dpr属性,以及一个font-size样式。JS会根据不同的设备添加不同的data-dpr值,比如说2或者3,同时会给html加上对应的font-size的值。

如此一来,页面中的元素,都可以通过rem单位来设置。他们会根据html元素的font-size值做相应的计算,从而实现屏幕的适配效果。

除此之外,在引入lib-flexible需要执行的JS之前,可以手动设置meta来控制dpr值,如:

<metaname="flexible"content="initial-dpr=2"/>

其中initial-dpr会把dpr强制设置为给定的值。如果手动设置了dpr之后,不管设备是多少的dpr,都会强制认为其dpr是你设置的值。在此不建议手动强制设置dpr,flexible.js首先会获取设备型号,然后根据不同设备添加不同的data-dpr值,实际上只对iOS设备进行dpr的判断,对于Android系列,始终认为其dpr1

if(!dpr&&!scale){varisAndroid=win.navigator.appVersion.match(/android/gi);varisIPhone=win.navigator.appVersion.match(/iphone/gi);vardevicePixelRatio=win.devicePixelRatio;if(isIPhone){// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案if(devicePixelRatio>=3&&(!dpr||dpr>=3)){dpr=3;}elseif(devicePixelRatio>=2&&(!dpr||dpr>=2)){dpr=2;}else{dpr=1;}}else{// 其他设备下,仍旧使用1倍的方案dpr=1;}scale=1/dpr;}

屏幕尺寸不同,随着rem也不一样,如果盒子为150px,则转换成15rem

varwidth=docEl.getBoundingClientRect().width;varrem=width/10;

快速转换插件

VS code中可以下载一个插件cssrem

flexible的实质

flexible实际上就是能通过JS来动态改写meta标签,代码类似这样:

varmetaEl=doc.createElement('meta');varscale=isRetina?0.5:1;metaEl.setAttribute('name','viewport');metaEl.setAttribute('content','initial-scale='+scale+', maximum-scale='+scale+', minimum-scale='+scale+', user-scalable=no');if(docEl.firstElementChild){document.documentElement.firstElementChild.appendChild(metaEl);}else{varwrap=doc.createElement('div');wrap.appendChild(metaEl);document.write(wrap.innerHTML);}

事实上他做了这几样事情:

  • 动态改写<meta>标签
  • <html>元素添加data-dpr属性,并且动态改写data-dpr的值
  • <html>元素添加font-size属性,并且动态改写font-size的值

把视觉稿中的px转换成rem

读到这里,大家应该都知道,我们接下来要做的事情,就是如何把视觉稿中的px转换成rem。在此花点时间解释一下。

首先,目前日常工作当中,视觉设计师给到前端开发人员手中的视觉稿尺寸一般是基于640px750px以及1125px宽度为准。

正如文章开头显示的示例设计稿,他就是一张以750px为基础设计的。那么问题来了,我们如何将设计稿中的各元素的px转换成rem

目前Flexible会将视觉稿分成100份(主要为了以后能更好的兼容vhvw),而每一份被称为一个单位a。同时1rem单位被认定为10a。针对我们这份视觉稿可以计算出:

1a=7.5px 1rem=75px

那么我们这个示例的稿子就分成了10a,也就是整个宽度为10rem<html>对应的font-size75px

这样一来,对于视觉稿上的元素尺寸换算,只需要原始的px值除以rem基准值即可。例如此例视觉稿中的图片,其尺寸是176px * 176px,转换成为2.346667rem * 2.346667rem

文本字号不建议使用rem

前面大家都见证了如何使用rem来完成H5适配。那么文本又将如何处理适配。是不是也通过rem来做自动适配?

显然,我们在iPhone3G和iPhone4的Retina屏下面,希望看到的文本字号是相同的。也就是说,我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏手机上看到更多文本,以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px和24px,所以我们不希望出现13px和15px这样的奇葩尺寸。
如此一来,就决定了在制作H5的页面中,rem并不适合用到段落文本上。所以在Flexible整个适配方案中,考虑文本还是使用px作为单位。只不过使用[data-dpr]属性来区分不同dpr下的文本字号大小。

div{width:1rem;height:0.4rem;font-size:12px;// 默认写上dpr为1的fontSize}[data-dpr="2"] div{font-size:24px;}[data-dpr="3"] div{font-size:36px;}
http://www.jsqmd.com/news/1142783/

相关文章:

  • GHelper:拯救华硕笔记本性能的轻量级控制神器
  • 跨平台CAD 2026看图工具:免费轻量无广告,手机电脑皆可畅享
  • 2026跨境社媒运营避坑指南:这些被忽略的长尾流量玩法帮你低成本获客
  • 毕设开源 深度学习yolo11水稻病害检测识别系统(源码+论文)
  • 云南高原山地安防监控集成落地实践:本土集成商云南凯尊科技全流程技术纪实
  • 山东中小学高性价比电子阅卷企业
  • 2026跨境电商新手必看:避开9个隐形坑 赚美金的实操干货全整理
  • easyMarkets平台:以投教内容为核心的平台服务观察
  • NAU8224与STM32F031C6音频系统设计与优化
  • 如何用AML启动器彻底解决XCOM模组管理难题
  • 观澜:一个 AI 驱动的不良资产尽职调查系统实践
  • TS2007FC音频放大器与PIC32MX675F256L微控制器集成设计
  • Agent的物种分化——豆包千问同日下线智能体背后,一场被误读的产业地震
  • 从模糊到高清:如何用Anime4K让你的动漫观看体验瞬间升级
  • 105-基于51单片机智能衣鞋柜【Proteus仿真+Keil程序+报告+原理图】
  • Termux+Kali打造移动渗透测试环境:从原理到实战
  • 不止看裸车价:全生命周期成本视角下的购车决策逻辑
  • 一键打印6种证件类型,智能排版身份证工具轻松导出图片
  • 3个步骤掌握英雄联盟本地化工具箱的终极实战指南
  • Burp Suite Intruder 4种攻击模式对比:Sniper与Cluster Bomb实战效率分析
  • Havenlon|AI 时代的执行控制(四):AI 真正危险的不是会思考,而是能执行
  • Three.js 罗盘教程
  • 【北京联合大学本科毕业论文】基于SpringBoot的校园二手体育器材交易平台设计与实现
  • STM32智能窗帘系统
  • 界面控件DevExpress WPF v26.1新版亮点 - Data Grid功能全新增强
  • IQ-TREE终极指南:革命性的高效系统发育分析工具
  • 2026物联网公司推荐:选型标准与D-coding落地评估
  • 机缘、收获与憧憬:一个运维开发者的创作自述
  • 从Scaling Law bug学调优:开发者必避的三大陷阱与实操指南
  • Wwise音频容器解析工具:3步掌握游戏音频资源管理与替换