之前没做过移动端web开发,最近接手的一个小项目是做微信公众号,需要考虑手机适配。UI给出的设计稿是一般是基于iphone手机做的(15年之后是基于ipone6),我们的UI是基于iphone6来做的(iphone6手机的分辨率是1334 * 750)。开发过程中主要有几个疑问:
1、如何将设计稿的尺寸转换到开发尺寸?
2、如何实现自适应?
3、如何调试在手机中的展示效果
下面会针对这几个问题展开讲解。讲解之前,要先讲下移动端开发的基础知识。

一、基础知识

1、屏幕尺寸

即我们通常说的尺寸是多少多少英寸啦,指的是屏幕对角线的长度。比如iphone6的屏幕尺寸是4.7英寸

px,pixel,像素,电子屏幕上组成一幅图画或image的基本单元。
pt, point,点,印刷行业常用单位,等于1/72英寸。
ppi,pixel per inch,每英寸像素数,值越高,屏幕越细腻。
dpi, dot per inch,每英寸多少点,该值越高,则图片越细腻。
dp,dip, Density-independent pixel,安卓开发用的长度单位。以160ppi为标准,和iPhone的scale差不多的意思。安卓用dp适配,系统会自动将dp转换为px。当屏幕像素点密度为160ppi时,1dp=1px。

2、屏幕分辨率
屏幕上的像素总数。常用的表现形式如:1280x720, 1920x1080等。这个像素指的是物理像素
3、pt和px

pt:pixel,像素,电子屏幕上组成一幅图画或image的基本单元。
pt:point,点,印刷行业常用单位,等于1/72英寸。
但是你想知道的pt可能并不是指这里的pt,而是IOS系统的pt,请往下看
4、 ios pt 和 px
1)px:
像素,电子屏幕上组成一幅图画或image的基本单元。
2)pt
iOS 开发中用到的单位 pt 是独立像素的意思。和安卓中的单位dp本质上是一个概念。

它是绝对长度,不随屏幕像素密度变化而变化(和我们日常用到的毫米、厘米是一个意思,只是它要小得多)。
在非视网膜的 iPhone 上(iPhone 3G),苹果规定 1px=1pt,也就是说 pt 和像素点是一一对应的。但随着 iPhone 4 的到来,高分屏出现了(视网膜屏),这个时候 1pt 对应 2px。

出现了所以用固定长度 pt 作为开发单位的好处是:这样可以统一图形在同一种类不同型号设备上图形的大小。而如果用像素作为单位的话,就乱了套了,因为在不同像素密度的屏幕里面,像素本身大小是不一样的。

5、PPI和DPI

1)PPI

设备像素密度(pixel per inch),一般手机参数中会给出ppi的值。表示每英寸像素数,值越高,屏幕越细腻。在购买手机时,ppi的值是用户关注的数据。

比如iphone 6的分辨率是1334 * 750,那PPI = (1334 ^ 2 + 750 ^ 2) ^ 1/2

通常把超过300ppi的显示屏成为retina屏。当一个显示屏像素密度超过300ppi时,人眼就无法区分出单独的像素。这也是讲:显示设备清晰度已达到人视网膜可分辨像素的极限。因此手持平板类电器显示器的像素密度达到或高于300ppi就不会再出现颗粒感。

另外观视距离及显示器尺寸的大小或许可改变上述像素密度超过300ppi的定义,因为人的观视距离在2米开外显示器像素密度只要超过200ppi也无法区分出单独的像素。
2)DPI

DPI(Dots Per Inch)最初用于衡量打印无上每英寸的点数密度,就是说你的打印机可以在一英寸内打多少个点。DPI值越小,图片越不惊喜。
当DPI的概念用在计算机屏幕上时候,和PPI是一样的。一般在IOS和Android中提到的DPI和PPI指的是同一个值

2、物理像素、设备独立像素、设备像素比

1)物理像素(physical pixel)
一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。屏幕分辨率指的就是物理像素。

2)设备独立像素(density-independent pixel)
设备独立像素(也叫密度无关像素、逻辑分辨率),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。
设备独立像素就是对应前端在开发时使用的像素单位。
所以说,物理像素和设备独立像素之间存在着一定的对应关系,这就是接下来要说的设备像素比。

3)设备像素比(device pixel ratio )
设备像素比(简称dpr,也叫倍率)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到:

设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向

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

综合上面几个概念,一起举例说明下,以iphone6为例:
设备宽高为375×667,可以理解为设备独立像素(或css像素)。
dpr为2,根据上面的计算公式,其物理像素就应该×2,为750×1334。

用一张图来表现,就是这样(图为盗图):

上图中可以看出,对于这样的css样式:

width: 2px;
height: 2px;

在不同的屏幕上(普通屏幕 vs retina屏幕),css像素所呈现的大小(物理尺寸)是一致的,不同的是1个css像素所对应的物理像素个数是不一致的。

在普通屏幕下,1个css像素 对应 1个物理像素(1:1)。 在retina 屏幕下,1个css像素对应 4个物理像素(1:4)。

如果对于设备相似比有疑问,可以参考谢泽的网络日志viewport手机逻辑像素与物理像素原理(附完整手机各版本尺寸)

二、常见手机尺寸和分辨率

iphoone手机部分是学UI网萌小秘整理的。

设备名称 屏幕尺寸 PPI Asset 竖屏点(point) 物理分辨率(px) 设计分辨率(px)
iPhone X 5.8 in 458 @3x 375 x 812 1125 x 2436 1125 x 2436
iPhone 8+, 7+, 6s+, 6+ 5.5 in 401 @3x 414 x 736 1080x1920 1242 x 2208
iPhone 8, 7, 6s, 6 4.7 in 326 @2x 375 x 667 750 x 1334 750 x 1334
iPhone SE, 5, 5S, 5C 4.0 in 326 @2x 320 x 568 640 x 1136 640 x 1136
iPhone 4, 4S 3.5 in 326 @2x 320 x 480 640 x 960 640 x 960
iPhone 1, 3G, 3GS 3.5 in 163 @1x 320 x 480 320 x 480 320 x 480
iPad Pro 12.9 12.9 in 264 @2x 1024 x 1366 2048 x 2732 2048 x 2732
iPad Pro 10.5 10.5 in 264 @2x 834 x 1112 1668 x 2224 1668 x 2224
iPad Pro, iPad Air 2, Retina iPad 9.7 in 264 @2x 768 x 1024 1536 x 2048 1536 x 2048
iPad Mini 4, iPad Mini 2 7.9 in 326 @2x 768 x 1024 1536 x 2048 1536 x 2048
iPad 1, 2 9.7 in 132 @1x 768 x 1024 768 x 1024 768 x 1024
andriod   120 @0.75x 240*320 120  
andriod   160 @1x 320*480 160  
andriod   240 @1.5x 480*800 240  
andriod   320 @2x 640*960 320  
andriod   360 @1.5x 540*960 360  
andriod   360 @2x 720*1280 360  
andriod   360 @3x 1080*1920 360  

屏幕尺寸、PPI(像素密度)、分辨率这些是可以在网上商店查询,直接查询手机的参数,比如通过中关村在线查询到的iphone6参数:

另外screen sizes网站收集了常见手机的尺寸、屏幕分辨率、PPI等数据。

但是Asset(倍率)、竖屏点(逻辑分辨率)这些通过中关村在线是查询不到的。可以通过苹果官网查看倍率、逻辑分辨率。
倍率也可以根据PPI来推算

三、根据拿到设计稿如何实现自适应

上面说过我们拿到的UI稿是基于iphone 6 (1334 * 750),设备独立像素比是2。其实对应CSS像素就是把UI稿给的宽度除2。比如设计稿的宽度是200 * 100,那么CSS像素就是 100 * 50。

但是不同型号手机的CSS像素数也不同,如何做到兼容?
在介绍方案之前,要先引入rem的概念。
1、px、em、rem

  • px:相对固定单位,字号大小直接被定死,所以用户无法根据自己设置的浏览器字号而缩放。
  • em:相对单位,表示相当于父元素font-size的大小。比如父元素font-size:16px,1em就表示16px。但em是相对于它的父元素的font-size,页面层级越深,em的换算就越复杂。
  • rem:相对单位。表示相对于根元素(<html>)的font-size大小。比如<html>字号是16px,1rem表示就等于16px。这就避开了很多层级关系。移动端新型浏览器对rem的兼容很好,可以放心使用。

2、rem如何实现自适应
2.1 设置字题大小

首先先给页面根元素设置字体大小,可以通过js动态设置的:

var designWidth = 750, //设计稿基准手机的物理像素clientWidth = document.documentElement.clientWidth,designFontSize = 100, //规定设计稿基准手机下1rem等于多少物理像素,这个值最好设置整十被倍数,更加便于计算的值。如100、1000等ratio = clientWidth / designWidth, //逻辑像素宽度和设计稿物理像素宽度比值,不同手机值不一样fontSize = (ratio * designFontSize); //计算1rem等于多少逻辑像素document.documentElement.style.fontSize = fontSize; //在iphone6下,计算出来是50px。即1rem = 50px。

通过上面设置后,在iphone6下,1rem = 50px逻辑像素 = 100px物理像素。

1) 为什么是clientWidth / 750?为什么要乘以100?

A.是因为这里是作为一个基础数值,换个方向去想,这里先不乘以100以免产生误解。
例如:设计稿宽度是640px,有一个元素设计稿上的宽度是50px,设备物理宽度是320px,那么我们在页面上应该设置宽度为 width:50rem,相当于宽度是:50*(320/640)=25px;这里能正确算出在320px的设备上刚好占一半,其实可以想象为 rem=(320/640)。

B.一般浏览器的最小字体是12px,如果html的font-size=(320/640)px,相当于font-size=0.5px,那么这个数值就小于12px,会造成一些计算的错误,和一些奇怪的问题,*100后,font-size是50px,就可以解决这种字体小于12px的问题。

C. 为了计算方便   我们后面把比率乘以了100,(320/640)*100,那么相对应这个元素在设置数值的时候就需要除以100了(50/100),这样可以保证最后出来的数值不变.

2)其他设置字体大小方案:
当然字体大小也可以通过媒体查询来设置。比如有些地方把html的font-size设置为625%,这样1rem = 100px。然后通过媒体查询设置不同屏幕下的的字号大小。但是这种方案的缺陷就是比较麻烦,要挨个设置。

(为什么是625%?因为大多数浏览器的默认字号是16px,因此1rem=16px,这样不方便我们px和rem转换。要让1rem = 10px,font-size应该等于10px = 16px * 62.5%。但是10px在chrome浏览器无法显示,为了兼容将font-size调整为625%。这样1rem = 100px。)。

@media screen and (min-width:360px) and (max-width:374px) and (orientation:portrait) {html { font-size: 703%; }
}
@media screen and (min-width:375px) and (max-width:383px) and (orientation:portrait) {html { font-size: 732.4%; }
}
@media screen and (min-width:384px) and (max-width:399px) and (orientation:portrait) {html { font-size: 750%; }
}
@media screen and (min-width:400px) and (max-width:413px) and (orientation:portrait) {html { font-size: 781.25%; }
}
@media screen and (min-width:414px) and (max-width:431px) and (orientation:portrait){html { font-size: 808.6%; }
}
@media screen and (min-width:432px) and (max-width:479px) and (orientation:portrait){html { font-size: 843.75%; }
}

2.2 将设计稿尺寸全部转换为rem
通过上面设置后,在iphone6下,1rem = 50px逻辑像素 = 100px物理像素。
因此1px物理像素 = 1 / 100 rem = 0.01rem。也就意味着设计稿给出的1px等于0.01rem。
如何将设计稿的尺寸都转换为rem呢?

交代下我们项目的背景,项目是vue框架,基于vue-cli2搭建起来。
1)方案一、scss添加转换函数px2rem

可以通过scss 的混合函数来实现。

@baseFontSize: 100;//1rem相当于多少视觉稿的物理像素
@function px2rem(@px){@return  @px / @baseFontSize * 1rem;
}button {width: px2rem(100px);
}

但是这种方案是不是觉得麻烦极了,每个用到的地方都要手动调用函数。别急,还有更简单的方法。

2)方案二、通过px2rem-loader实现
首先,将px2rem-loader安装到项目中。通过npm install px2rem-loader --save-dev。
px2rem-loader配置教程请参考github px2rem-loader,css样式如何控制转换规则请参考github px2rem。

找到build/utils.js,在postcss-loader前面加上px2rem-loader的设置。注意px2rem-loader是放置在sass-loader前面的,即比sass-loader后执行。

  const px2remLoader = {loader: 'px2rem-loader',options: {remUnit: 100}}const postcssLoader = {loader: 'postcss-loader',options: {sourceMap: options.sourceMap}}function generateLoaders (loader, loaderOptions) {const loaders = options.usePostCSS ? [cssLoader, postcssLoader, px2remLoader] : [cssLoader, px2remLoader]...}

px2rem-loader已经可以实现自动转换了。如果不需要转换,在样式后面加上/*no*/即可。如果需要根据不同的设备像素比,添加不同的px,则在样式后面加上/*px*/。比如:

.selector {width: 150px;height: 64px; /*px*/font-size: 28px; /*px*/border: 1px solid #ddd; /*no*/
}

处理后的结果如下:

.selector {width: 2rem;border: 1px solid #ddd;
}
[data-dpr="1"] .selector {height: 32px;font-size: 14px;
}
[data-dpr="2"] .selector {height: 64px;font-size: 28px;
}
[data-dpr="3"] .selector {height: 96px;font-size: 42px;
}

当然,根据不同设备像素比设置不同的值,这个需要配合js使用。要先给元素设置不同的dpr值。这个可以利用淘宝的lib-flexible来实现,有兴趣的可以看下大漠的使用Flexible实现手淘H5页面的终端适配。大漠的文章需要付费观看,也可以看下csdn上转载的大漠文章。

px2rem-loader缺陷:
px2rem-loader有一个问题,它没有办法排除某个目录。我们项目中引入了三方模块weui,用了px2rem-loader页面就全乱了。我们想把三方模块排除在外,但是px2rem-loader并不支持。
本来想要loader自带的exclude功能,但是把px2-rem放到所有css loader前面或者后面,都会提示missing property,缺失 : 或者 }

3)postcss-px2rem-exclude
postcss-px2rem-exclude可以解决上面说的问题。
首先安装postcss-px2rem-exclude

npm  install postcss-px2rem-exclude --save

然后在项目根目录下的postcss.config.js文件或.postcssrc.js配置postcss-px2rem-exclude,如果你的项目没有生成这个独立文件,就需要在你的package.json里设置。
.postcssrc.js:

module.exports = {plugins: {autoprefixer: {},"postcss-px2rem-exclude": {remUnit: 75,exclude: /node_modules|folder_name/i}}
};

package.json:

"postcss": {"plugins": {"autoprefixer": {},"postcss-px2rem-exclude":{"remUnit": 75,"exclude":"/node_modules|floder_name/i"}}}

postcss-px2rem-exclude在webpack配置文件中设置无法起作用(我自己没有实践过在配置文件中添加)。具体说明请查看博客园 石耳的《vue-cli3.0结合lib-flexible、px2rem实现移动端适配,完美解决第三方ui库样式变小问题》,主要看postcss-px2rem-exclude使用部分的说明。

自适应方案也可以参考淘宝flex.js方案,引入flex.js,会根据设备像素分辨率设置根元素的字体,即1rem的大小。可以参考大漠的使用Flexible实现手淘H5页面的终端适配 。

四、手机网站

大家可以看下互联网大佬们如何实现移动端自适应:
手机网易网:http://3g.163.com/touch/#/
手机淘宝网:https://h5.m.taobao.com/
手机京东:https://m.jd.com/

五、模拟、查看手机端效果

1、浏览器调试

我们打开手淘网,登陆自己的淘宝账号。然后按F12 打开chrome开发者工具,按照途中的标准顺序号进行设置后,就可以开始调试了。
即:先选择手机调试模式--->选择要调试的设备-->选择显示百分比(显示宽度为实际手机宽度的百分多少)

2、浏览器新增调试设备

如果调试设备不满足自己要求,可以自行添加需要调试的设备。点击开发者工具右上角的更多-->设置,或按F1打开设置界面

要注意分辨率填写的是逻辑像素数。比如iphone6填写的应是375、667,而不是750、1334。

chrome设备手机模式调试能够看出大致的效果,但是有一些是模拟不出来的。比如逻辑像素1px在设备像素比高的设备看起来比较粗,字体展示效果也可能不一样。
在正式发布前,还是需要在手机端进行调试。我们做的是微信公众号,直接在手机微信中输入链接地址,就能开始调试了。

参考文章:
1、【原创】移动端高清、多屏适配方案:http://www.html-js.com/article/Mobile-terminal-H5-mobile-terminal-HD-multi-screen-adaptation-scheme%203041
2、移动端界面设计之尺寸篇(更新):http://www.xueui.cn/tutorials/app-tutorials/mobile-ui-design-size.html (含各种iphone手机尺寸)
3、前端页面适配的rem换算:https://www.cnblogs.com/liangxuru/p/6970629.html
4、一步步教你使用rem适配不同屏幕的移动设备:https://www.cnblogs.com/dannyxie/p/6640903.html (解释如何设置基准fontSize)

5、移动前端自适应适配布局解决方案和比较:http://caibaojian.com/mobile-responsive-example.html

移动web开发入门—基础知识、自适应布局、调试相关推荐

  1. 好程序员web前端教程分享web前端入门基础知识

    好程序员web前端教程分享web前端入门基础知识,作为合格的Web前端工程师必须得掌握HTML.CSS和JavaScript.只懂其中一两个还不行,必须对这三门语言都要熟悉.下面我们一起来看一看吧! ...

  2. JSP WEB开发入门基础到高手进阶教程002

    JSP WEB开发入门基础到高手进阶教程 -------开发入门 JSP与微软的Active Server Pages 兼容,但它是使用类似HTML的卷标以及Java程序代码段而不是VBScript. ...

  3. 音视频开发入门基础知识(视频入门篇)

    RTSP实时音视频开发实战课程:<RTSP实时音视频开发实战> 音视频开发入门基础知识(音频入门篇) 目录 一.前言 二.视频采集和显示 三.视频常见的格式 四.RGB转YUV和YUV转R ...

  4. 音视频开发入门基础知识(音频入门篇)

    RTSP实时音视频开发实战课程:<RTSP实时音视频开发实战> 音视频开发入门基础知识(音频入门篇) 目录 前言 音频的采集和播放 音频常见的格式 音频的编码 前言 在音视频开发入门基础知 ...

  5. 网页编程从入门到精通 杨凡_干货 | web前端入门基础知识

    一名合格的web前端工程师必须得掌握HTML.CSS和JavaScript. 只懂其中一个或两个还不行,你必须对这三门语言都很熟悉. 也不是说必须对这三门语言都非常精通,但你至少要能够运用它们完成大多 ...

  6. 一、web安全入门基础知识

    一.基础入门-概念名次 域名发现对应网安的意义? 一个网站的域名和他的子域名可能绑定于同一个IP地址,当我们进行漏洞扫描的时候他的主站没有找到漏洞那么我们就可以通过他子域名的网站绑定于同一个IP地址这 ...

  7. 移动端开发入门--基础知识

    1.一些概念 dp, pt device-independent pixels 设备无关像素, 基于设备内的坐标系统测量的物理单位, 代表了一个可以由程序使用的虚拟像素, 然后由底层系统转换成逻辑像素 ...

  8. Java Web基础入门第八讲 Java Web开发入门——初始WEB服务器

    WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源.Internet上供外界访问的Web资源分为: 静态web资源(如html页面):指we ...

  9. 《Java Web开发入门很简单》学习笔记

    <Java Web开发入门很简单>学习笔记 1123 第1章 了解Java Web开发领域 Java Web主要涉及技术包括:HTML.JavaScript.CSS.JSP.Servlet ...

最新文章

  1. 提升Kaggle模型的实用小技巧!
  2. CTO丢给我《技术Leader的30条军规》:照着做,做不好滚回去写代码!
  3. 数据流通实现“可用不可见”?腾讯巧夺“天工”
  4. only SOY MILK IS NOT ENOUGH FOR BREAKFAST
  5. sas数据集怎么导出_利用SAS中的ODS导出程序结果数据集
  6. 深入解读首个万亿级语言模型 Switch Transformer
  7. 以色列:新发明大幅提高太阳能发电效率
  8. java 该改变request url_如何在Java中使用servlet过滤器来更改传入的servlet请求URL?...
  9. kettle的乱码和null值无法插入
  10. 想学习C语言,学习路线是什么?
  11. BZOJ 3173: [Tjoi2013]最长上升子序列 [splay DP]
  12. Android及其他平台音频开源库介绍
  13. 通达信交易接口分时做T的指标公式分享
  14. 机器学习之Python Sklearn——线性回归
  15. 图像质量评估指标(3) 特征相似度FSIM
  16. python中del什么意思_python del函数是什么以及如何使用?
  17. 2022-04-07 西安 javaSE(04) 方法可变参数、重载、递归,数组、冒泡排序、二分查找、动态操作,二维数组、jvm内存区域划分
  18. 2013 年度回忆录
  19. Android开发— Android API Levels
  20. Python学习手册--第六部分(类)

热门文章

  1. 实习一个月后,我看到了不想成为的人
  2. 10秒钟获取16进制颜色
  3. excel两张表格数据整合
  4. nginx服务器的根目录在哪
  5. eclipse设置断点调试
  6. 路飞学城python电子书闲鱼_路飞学城Python-Day21(practise)
  7. 试题 算法训练 学做菜
  8. C语言:表达式求值详解
  9. 【lrzsz】安装lrzsz工具实现Linux和Windows系统之间文件便捷上传与下载
  10. YOLOv5烟草项目