简介

工欲善其事必先利其器,今天这篇文章主要讲解移动端H5开发必备的一些基础知识以及移动端适配和布局方案。如果已经看过这篇文章了或者已经掌握了移动端基础的话可以看笔者写的

移动端H5网页开发常见问题汇总

移动端开发必备知识-Hybrid App

像素

像素即一个小方块,它具有特定的位置和颜色。图片、电子屏幕(手机、电脑)就是由指定数个具有特定颜色和特定位置的小方块拼接而成。比如我们的电脑屏幕1920 * 1080的电脑屏幕,横向有1920个像素纵向有1080个像素。

像素单位有设备像素、逻辑像素、CSS 像素 3 种。

设备像素、独立像素、设备像素比、 CSS 像素

设备像素

设备像素也叫物理像素,是屏幕上最小的显示单元,即设备上真实的物理单元,在设备生产的时候就已经定好。(iphone6 750px)一般比独立像素大。

独立像素

独立像素(DP 或 Dip)是一种虚拟像素,是逻辑上衡量像素的单位,不缩放的情况下等于 css 像素。(iphone5 320px iphone6 375px)。

设备像素比

设备像素比 dpr 就是设备像素和独立像素的比例。比如iphone6的dpr就是2,iphone6 Plus的dpr就是3。

在 web 中,浏览器为我们提供了 window.devicePixelRatio 来帮助我们获取 dpr。在 css 中,可以使用媒体查询 min-device-pixel-ratio 获取dpr。在 React Native 中,我们也可以使用 PixelRatio.get()来获取 dpr。

@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {}

设备像素与设备独立像素之间的比例是多少,普遍规律是,屏幕的像素密度越高,就需要更多的设备像素来显示一个设备独立像素。

CSS 像素

在 CSS 中使用的 px 都是指 css 像素,比如 width: 128px。css 像素的大小是很容易变化的,当我们缩放页面的时候,元素的 css 像素数量不会改变,改变的只是每个 css 像素的大小。也就是说 width: 128px 的元素在缩放200% 以后,宽度依然是 128 个 css 像素,只不过每个 css 像素的宽度和高度变为原来的两倍。如果原本元素宽度为 128 个设备独立像素,那么缩放 200% 以后元素宽度为 256 个设备独立像素。

css 像素与设备独立像素的关系

  • 缩放比例就是 css 像素边长/设备独立像素边长;
  • 在缩放比例为 100% 的情况下,1 个 css 像素大小等于 1 个设备独立像素;
  • 在缩放比例为 200% 的情况下,1 个 css 像素大小等于 (2 * 2) 个设备独立像素;

Retina 屏

前面说到了像素和设备像素比,这里我们再说说Retina 屏。所谓Retina是一种显示标准,是把更多的像素点压缩至一块屏幕里,从而达到更高的分辨率,并提高屏幕显示的细腻程度。在正常阅读距离下,人眼无法分辨屏幕上的像素颗粒,使得屏幕显示效果更为细腻平滑。从iPhone4开始, 苹果公司为其产品mac、iPhone以及iPad的屏幕配置了Retina屏幕。

增加分辨率的方式不同

  • 普通屏幕通过增大尺寸来增加分辨率。
  • Retina屏幕通过提升屏幕单位面积内的像素数量(增大PPI),即像素密度来提升分辨率,这样就有了高像素密度屏幕

相同的设备物理尺寸,CSS像素与物理像素的转换不同

  • 普通屏幕: 1px 等于一个物理像素。
  • Retina屏幕:1px 等于四个物理像素。

k 和 p

我们经常见到用 K 和 P 这个单位来形容屏幕:

  • P 代表的就是屏幕纵向的像素个数,1080P 即纵向有 1080 个像素,分辨率为 1920X1080 的屏幕就属于 1080P 屏幕。
  • K 代表屏幕横向有几个像素,一般来讲横向像素超过 2048 就属于 2K 屏,横向像素超过 4096 就属于 4K 屏。

英寸

一般用英寸描述屏幕的物理大小,如电脑显示器的 17、22,手机显示器的 4.8、5.7 等使用的单位都是英寸。需要注意尺寸都是屏幕对角线的长度。1 英寸 = 2.54 厘米。

PPI

PPI(Pixel Per Inch):每英寸包括的像素数。

PPI 可以用于描述屏幕的清晰度以及一张图片的质量。使用 PPI 描述图片时,PPI 越高,图片质量越高,使用 PPI 描述屏幕时,PPI 越高,屏幕越清晰。

计算方式 水平像素点数平方与垂直像素点数平方的和的平方根除以屏幕英寸(屏幕对角线长度)。

DPI

DPI(Dot Per Inch):即每英寸包括的点数。

平时你可能会看到使用 DPI 来描述图片和屏幕,这时的 DPI 应该和 PPI 是等价的,DPI 最常用的是用于描述打印机,表示打印机每英寸可以打印的点数。

所以,打印机的 DPI 越高,打印图像的精细程度就越高,同时这也会消耗更多的墨点和时间。

em

em 相对于元素自身的 font-size,1em就等于该元素font-size的大小。由于font-size具有继承性,所以就算本元素没设置font-size大小,也会继承父元素的font-size,如果父元素也没有,会沿着 DOM 树一直向上查找,直到根元素 html,根元素的默认字体大小为 16px。

rem

有了em的基础,rem就更简单了,rem只与根元素html的font-size大小有关,大小固定不变,1rem 就等于根元素 html 的字体大小。

视口(viewport)

布局视口(layout viewport)

布局视口,在移动端显示网页时,由于移动端的屏幕尺寸比较小,如果网页使用移动端的屏幕尺寸进行布局的话,那么整个页面的布局都会显示错乱。所以移动端浏览器提供了一个 layout viewport 布局视口的概念,使用这个视口来对页面进行布局展示,一般 layout viewport 的大小默认为 980px,这保证 PC 的网页可以在手机浏览器上呈现,但是非常小,用户可以手动对网页进行放大。我们可以通过调用 document.documentElement.clientWidth / clientHeight 来获取布局视口大小。布局视口可理解为你网页的宽度。

视觉视口(visual viewport)

视觉视口,visual viewport 指的是移动设备上我们可见的区域的视口大小,一般为设备独立像素大小。visual viewport 和 layout viewport 的关系,就像是我们通过窗户看外面的风景,视觉视口就是窗户,而外面的风景就是布局视口中的网页内容。我们可以通过调用 window.innerWidth / innerHeight 来获取视觉视口大小。视觉视口可以理解为设备独立像素大小。

理想视口(ideal viewport)

理想视口,由于 layout viewport 一般比 visual viewport 要大,所以想要看到整个页面必须通过拖动和缩放才能实现。所以又提出了 ideal viewport 的概念,ideal viewport 下用户不用缩放和滚动条就能够查看到整个页面,并且页面在不同分辨率下显示的内容大小相同。ideal viewport 其实就是通过修改 layout viewport 的大小,让它等于设备的宽度,这个宽度可以理解为是设备独立像素,因此根据 ideal viewport 设计的页面,在不同分辨率的屏幕下,显示应该相同。我们可以通过调用 screen.width / height 来获取理想视口大小,返回的是设备独立像素。理想视口可理解为布局视口与视觉视口相等。

利用 meta 标签对 viewport 进行控制

移动设备默认的 viewport 是 layout viewport,也就是那个比屏幕要宽的 viewport,默认宽度是980px。所以我们经常使用meta标签对viewport进行控制,一般我们设置width=device-width也就是让布局视口和视觉视口相等,即达到理想视口。

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

viewport的属性

  • width 正整数或 device-width 以 pixels(像素)为单位, 定义布局视口的宽度。
  • height 正整数或 device-height 以 pixels(像素)为单位, 定义布局视口的高度。
  • initial-scale0.0 - 10.0 定义页面初始缩放比率。
  • minimum-scale0.0 - 10.0 定义缩放的最小值;必须小于或等于 maximum-scale 的值。
  • maximum-scale0.0 - 10.0 定义缩放的最大值;必须大于或等于 minimum-scale 的值。
  • user-scalable 一个布尔值(yes 或者 no)如果设置为 no,用户将不能放大或缩小网页。默认值为 yes

适配方案

移动端手机各种各样,手机屏幕也五花八门,所以做移动端H5开发必须要了解适配方案。也就是我们一套代码能兼容各种类型的手机。移动端适配的方案主要有@media媒体查询方案rem方案vw vh方案,下面我们逐一介绍。

使用 css 的媒体查询 @media

通过媒体查询来适配不同的屏幕,这里不具体介绍媒体查询感兴趣的可以自行学习。

@media *mediatype* and|not|only *(media feature)*  {CSS-Code;
}
@media screen and (min-width: 375px) { .box { width : 160px; } }@media screen and (min-width: 750px) { .box { width : 320px; } }

媒体查询虽然能解决适配问题但是使用媒体查询的缺点也很明显

  1. 页面上所有的元素都得在不同的 @media 中定义一遍不同的尺寸,代码冗余多。
  2. 如果再多一种屏幕尺寸,就得多写一个 @media 查询块。
  3. 媒体查询块的书写顺序也很有讲究,后面的会覆盖前面的,很容易出错。

使用 rem

前面我们已经介绍过rem了,1rem的大小就是html元素font-size的大小。所以使用rem布局的核心就是动态设置根元素html的字体大小。在rem适配方案中比较流行的是淘系的lib-flexibleamfe-flexible方案。

lib-flexibleamfe-flexible这两种移动端适配方案都是基于rem实现的。下面我们具体介绍下使用方式,不过官方文档也说了,由于viewport单位得到众多浏览器的兼容,lib-flexibleamfe-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方。

lib-flexible

感兴趣的可以看看lib-flexible的源码,这个版本会自动生成viewport meta标签

核心代码:

// 根元素字体的大小是布局视口大小/10。
function refreshRem(){var width = docEl.getBoundingClientRect().width;if (width / dpr > 540) {width = 540 * dpr;}var rem = width / 10;docEl.style.fontSize = rem + 'px';flexible.rem = win.rem = rem;
}
// 动态生成 viewport meta标签
if (!metaEl) {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);} else {var wrap = doc.createElement('div');wrap.appendChild(metaEl);doc.write(wrap.innerHTML);}
}

注意点:

// 如果是苹果手机,才会根据dpr进行缩放,其余的都不做缩放处理
// 我觉得这里的设计应该主要是解决1px的问题吧,在amfe-flexible方案中已经放弃了
if (!dpr && !scale) {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;
}

lib-flexible的使用方式:

// 安装
npm install lib-flexible --save-dev// 引用
import 'lib-flexible/flexible.js'

这样就会给我们的index.html页面自动生成viewport meta标签,比如<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

有了lib-flexible的配置,这样就能适配不同的手机屏幕了。我们只需要记住计算公式某元素css尺寸 = 某元素设计稿尺寸/(设计稿宽度/10)。比如设计师的设计稿是375的,假设某元素在设计稿上的高度是75px,我们就需要在代码里面设置该元素的高度为75/(375/10) = 2rem

如果觉得手动计算特别累,我们可以使用postcss-pxtorem插件自动给我们进行计算。

postcss-pxtorem插件的核心是需要我们设置rootValue,如果我们的设计稿是375的我们只需要设置rootValue为37.5,如果我们的设计稿是750的我们只需要设置rootValue为75。这样我们在css中只需要按设计给元素设置px大小,该插件在打包的时候会自动给我们把rem的值计算好,是不是非常棒呢。

// 这里是postcss-pxtorem插件的默认配置
{rootValue: 16,unitPrecision: 5,propList: ['font', 'font-size', 'line-height', 'letter-spacing'],selectorBlackList: [],replace: true,mediaQuery: false,minPixelValue: 0,exclude: /node_modules/i
}// 一般我们只需要修改rootValue即可
{rootValue: 37.5,
}

amfe-flexible

感兴趣的可以看看amfe-flexible 的源码。这个版本代码更加简洁并且不会自动生成viewport meta标签

核心代码:

// set 1rem = viewWidth / 10
function setRemUnit () {var rem = docEl.clientWidth / 10docEl.style.fontSize = rem + 'px'
}

使用方式:

// 安装
npm install amfe-flexible --save-dev// 引用
import 'amfe-flexible/index.js'// 在index.html页面添加  viewport meta标签
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">

amfe-flexible方案中没有了dpr没有了自动生成viewport meta标签,没有了页面的缩放,变的更加简洁了。

lib-flexible使用方式类似,有了amfe-flexible的配置,这样就能适配不同的手机屏幕了。我们只需要记住计算公式某元素css尺寸 = 某元素设计稿尺寸/(设计稿宽度/10)。比如设计师的设计稿是375的,假设某元素在设计稿上的高度是75px,我们就需要在代码里面设置该元素的高度为75/(375/10) = 2rem

如果觉得手动计算特别累,我们可以使用postcss-pxtorem插件自动给我们进行计算。

postcss-pxtorem插件的核心是需要我们设置rootValue,如果我们的设计稿是375的我们只需要设置rootValue为37.5,如果我们的设计稿是750的我们只需要设置rootValue为75。这样我们在css中只需要按设计稿给元素设置px大小,该插件在打包的时候会自动给我们把rem的值计算好,是不是非常棒呢。

// 这里是postcss-pxtorem插件的默认配置
{rootValue: 16,unitPrecision: 5,propList: ['font', 'font-size', 'line-height', 'letter-spacing'],selectorBlackList: [],replace: true,mediaQuery: false,minPixelValue: 0,exclude: /node_modules/i
}// 一般我们只需要修改rootValue即可
{rootValue: 37.5,
}

使用 vw vh

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MMIMb2P3-1668602484737)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7a8115dc49f94892964ae1913e4818ec~tplv-k3u1fbpfcp-watermark.image?)]

  • vw:是 viewport’s width 的简写,屏幕宽度=100vw。
  • vh:和 vw 类似,是 viewport’s height 的简写,屏幕高度=100v。
  • vmin:vmin 的值是当前 vw 和 vh 中较小的值。
  • vmax:vmax 的值是当前 vw 和 vh 中较大的值。

使用vw和vh的适配方式相较于rem方式更简单,我们只需要设置viewport meta标签后就可以直接使用了。

使用方式:

// 在index.html页面添加  viewport meta标签
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />

跟上面的lib-flexibleamfe-flexible使用方式类似,这样就能适配不同的手机屏幕了。我们只需要记住计算公式某元素css尺寸 = 某元素设计稿尺寸/(设计稿宽度/100) vw。比如设计师的设计稿是375的,假设某元素在设计稿上的高度是75px,我们就需要在代码里面设置该元素的高度为75/(375/100) = 20vw。这里需要注意的是我们宽高都只能用vw为单位。

如果觉得手动计算特别累,我们可以使用postcss-px-to-viewport插件自动给我们进行计算。

postcss-px-to-viewport插件的核心是需要我们设置viewportWidth也就是设计稿的宽度(这点是跟postcss-pxtorem的区别),如果我们的设计稿是375的我们只需要设置viewportWidth为375,如果我们的设计稿是750的我们只需要设置viewportWidth为750。这样我们在css中只需要按设计稿给元素设置px大小,该插件在打包的时候会自动给我们把vw的值计算好,是不是非常棒呢。

// 这里是postcss-px-to-viewport插件的默认配置
{unitToConvert: 'px',viewportWidth: 320,unitPrecision: 5,propList: ['*'],viewportUnit: 'vw',fontViewportUnit: 'vw',selectorBlackList: [],minPixelValue: 1,mediaQuery: false,replace: true,exclude: undefined,include: undefined,landscape: false,landscapeUnit: 'vw',landscapeWidth: 568
}
// 一般我们只需要改viewportWidth即可
{viewportWidth: 375,
}

我们还可以使用postcss-px-to-viewport 插件的 Ignoring 特性,标注不需要转换的属性

  • /* px-to-viewport-ignore */ 当前行不进行转换
  • /* px-to-viewport-ignore-next */ 下一行不进行转换
.box {/* px-to-viewport-ignore-next */width: 10px;height: 10px;padding: 10px; /* px-to-viewport-ignore */
}

布局方案

说完了移动端的适配,接下来我们说说移动端的布局方案,移动端布局方案有很多,笔者推荐大家看看 移动端布局教程这篇文章,这里面介绍了移动端常见的布局方案,笔者就不再赘述了。

在这么多布局中,笔者觉得我们必须要掌握的是flex布局和grid布局,因为在日常H5开发中,这两个布局基本上是离不开的。关于flex布局grid布局的教程有很多,这里我就不班门弄斧了,我推荐大家读阮一峰老师的 Flex 布局教程、Grid 网格布局教程。掌握了这两套心法,我觉得在移动端H5开发布局这方面已经没有什么能难得住你了。

扩展

关于窗口大小的常见API

screen.width 获取屏幕的宽度 跟浏览器无关
screen.height 获取屏幕的高度 跟浏览器无关
screen.availWidth 获取屏幕有效宽度 如果任务栏设置在左右两侧的话,去除任务栏宽度
screen.availHeight 获取屏幕有效高度 去除任务栏高度window.outerWidth 获取浏览器宽度 包括浏览器所有包括侧边栏、窗口镶边和调正窗口大小的边框。
window.outerHeight 获取浏览器高度 包括浏览器所有包括侧边栏、窗口镶边和调正窗口大小的边框。
window.innerWidth:获取浏览器视觉视口宽度(包括滚动条)。
window.innerHeight:获取浏览器视觉视口高度(包括滚动条)。
document.documentElement.clientWidth:获取浏览器布局视口宽度。不包括滚动条。
document.documentElement.clientHeight:获取浏览器布局视口高度。不包括滚动条。dom.clientWidth:获取元素的宽度 包括内容和内边距
dom.clientHeight:获取元素的高度 包括内容和内边距
dom.offsetWidth:获取元素的宽度 包括内容、内边距、滚动条、边框。
dom.offsetHeight:获取元素的高度 包括内容、内边距、滚动条、边框。
dom.scrollWidth:获取元素内容实际的宽度 包括内边距。
dom.scrollHeight:获取元素内容实际的高度 包括内边距。dom.clientTop:获取元素上边框高度
dom.clientLeft:获取元素左边框宽度
dom.offsetTop:获取元素距离页面顶部高度
dom.offsetLeft:获取元素距离页面左边的宽度
dom.scrollTop:获取元素滚动条在垂直方向上滚动的距离
dom.scrollLeft:获取元素滚动条在水平方向上滚动的距离

后记

本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个赞~~

移动端H5网页开发必备知识相关推荐

  1. 移动端H5网页开发常见问题汇总

    简介 这篇文章主要是总结下移动端开发常见问题,帮助大家一起避坑.如果已经看过这篇文章了的话也可以看看笔者写的 移动端H5网页开发必备知识 移动端开发必备知识-Hybrid App HTML方面 调用系 ...

  2. 【前端三件套——CSS基础】网页开发必备知识

    文章目录

  3. 移动端开发必备知识-Hybrid App

    简介 面试的时候小伙伴们有没有被问到过Hybrid App呢?不得不说了解Hybrid App是我们前端面试中的一个加分项.今天就跟随笔者的步伐让你彻底弄懂Hybrid App,让你就算没做过也能对面 ...

  4. 移动端webapp开发必备知识

    转载自:移动终端开发必备知识 转载自:移动端webapp开发必备知识 请尊重版权,转载请注明来源,多谢~~ 移动设备的用户越来越多,每天android手机的激活量都已经超过130万台,所以我们面向移动 ...

  5. 移动终端开发必备知识(转载)

    移动设备的用户越来越多,每天android手机的激活量都已经超过130万台,所以我们面向移动终端的WebAPP也开始跟进了.本文主要介绍webapp的开发与调试的相关知识和经验,以及给出几种可选的解决 ...

  6. WCF分布式开发必备知识(4):Web Service(转)

    今天继续我们的WCF分布式开发必备知识系列文章的第4节:Web Service.前3节我们分别介绍了MSMQ消息队列/.Net Remoting/Enterprise Services三个相关的技术. ...

  7. 移动端H5混合开发设置复盘与总结

    此篇接上一篇: 移动端H5混合开发,Touch触控,拖拽,长按, 滑屏 实现方案 https://www.cnblogs.com/buoge/p/9346699.html app 场布设置已经上线了, ...

  8. html网页的主题标签是什么6,HTML标签及标签属性大全(网页制作必备知识)

    html标签及标签属性大全(网页制作必备知识) 总类(所有html文件都有的) ------------------------------------------------------------ ...

  9. H5网页开发新手入门-H5网页如何适应不同手机屏幕分辨率?

    一.问题汇总 手机网页怎么制作? 怎么让网页适应不同手机屏幕? H5网页设计到底该设计多大尺寸? rem怎么自适应布局? H5一屛页面如何自适应屏幕? viewport该怎么写? width=devi ...

最新文章

  1. CSS将长文字换行的方法 (转)
  2. Observer Pattern分析
  3. go mongodb排序查询_【赵强老师】MongoDB中的索引(下)
  4. 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 修改 7zr 交叉编译脚本 Android.mk | 交叉编译 lib7zr.so 动态库 )
  5. 利用Win32 Debug API打造自己的调试器Debugger
  6. ceph——rgw服务启不起来
  7. [php]apache虚拟主机配置
  8. 探讨TensorRT加速AI模型的简易方案 — 以图像超分为例
  9. vscode设置中文,设置中文不成功问题
  10. oracle数据库配置助手来初始化参数,使用服务器参数文件(SPFILE)管理初始化参数...
  11. 删库不跑路,详解MySQL数据恢复
  12. 计算机图形设计论文 真实图形生成技术的发展,绘制技术论文,关于计算机图形图像绘制技术的现状应用相关参考文献资料-免费论文范文...
  13. Python——如何获得字符串的唯一编码
  14. linux添加自定义的命令!
  15. kickstart注意事项
  16. 算法 判断多个点是否在同一圆周线上_广州灵活计费自动出盘机技术方案大盘点...
  17. 计算机软件 已录制 是指啥,录像软件是什么?怎么录制电脑屏幕视频?
  18. 十二烷基-β-D-麦芽糖苷/CAS号: 69227-93-6
  19. op 消除 消除自激振荡
  20. 前端框架Vue(11)——Vue+表单验证 VeeValidate 实践

热门文章

  1. EasyCVR视频融合平台基于宇视SDK进行二次开发的详细步骤
  2. 大学物理质点动力学思维导图_高中物理力学思维导图高中物理知识点总结大全...
  3. goLang 操作windows注册表
  4. 华为笔记本适合计算机网络系学生,适合学生党笔记本电脑,MateBook D系列Windows锐龙版你pick了吗...
  5. 信号盒子连接服务器,【当贝市场】简单4步解决电视盒子没信号问题
  6. 【计算机程序设计思想与方法】2 什么是计算思维?
  7. vulhub靶场thinkphp漏洞复现
  8. spring-banner
  9. js---javascript DOM
  10. 2022年山东省安全员C证特种作业证考试题库及在线模拟考试