H5 高清适配

问题的由来

手机屏幕的分辨率差异很大。

iphone4:320×480

iphone6:375×667

H5 网页必须自动适应这些屏幕,包含以下三部分的工作。

布局的缩放

字体的大小

图片的适配

retina 屏幕

有些设备是高清屏(retina),物理像素在水平方向和垂直方向各压缩 50% 显示。

这时,CSS 里面的 1 个像素会对应 4 个物理像素。

width: 20px;height: 20px;

retina 设备中,一张 40 x 40 像素的图片,会占据 20 x 20 的屏幕空间。如果图像比 40 x 40 像素小,就会显得比较模糊。

所以,图片往往需要准备非 retina 和 retina 两个版本。比如,200×300 的图片,还要准备 400×600 的版本。

SASS 的写法。

@mixinimg-dpr(){background-image: url(image.jpg);//默认[data-dpr="2"]&{background-image: url([email protected]);//两倍高清}      [data-dpr="3"] & {background-image: url([email protected]);//三倍高清}}.content{@includeimg-dpr(); }

dpr

高清屏的物理像素与实际像素的关系,可以用下面的公式表示。

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

“设备像素比”(device-pixel-ratio)简称为dpr。

iPhone4~iPhone6:dpr = 2

iPhone 6+:dpr = 3

对于 dpr 等于 2 的设备,视觉稿的画布水平/垂直大小会是基准的2倍,也就是说像素点个数是原来的4倍。比如,对于 iphone6 而言来说,屏幕大小是 375×667,视觉稿就是 750×1334。

脚本中可以使用window.devicePixelRatio得到dpr。

console.log(window.devicePixelRatio)// 2

高清屏的 CSS 设置

使用 CSS 的 Media Query,可以针对不同的屏幕设置不同的 CSS 规则。

@media(-webkit-min-device-pixel-ratio:2),        (min-resolution:2dppx),        (min-resolution:192dpi)  {/* 高清屏的 CSS 规则 */}

区分 retina 屏幕和屏幕宽度的 CSS 设置,完整写法如下。

@mediaonly screen and (min-width:320px) {/* 非 retina 的小屏幕 */}@mediaonly screen and (-webkit-min-device-pixel-ratio:2)      and (min-width:320px),only screen and (  min--moz-device-pixel-ratio:2)      and (min-width:320px),only screen and (    -o-min-device-pixel-ratio:2/1)    and (min-width:320px),only screen and (        min-device-pixel-ratio:2)      and (min-width:320px),only screen and (                min-resolution:192dpi) and (min-width:320px),only screen and (                min-resolution:2dppx)  and (min-width:320px) {/* 小屏幕的 retina 屏 */}@mediaonly screen and (min-width:700px) {/* 中等的非 retina 屏 */}@mediaonly screen and (-webkit-min-device-pixel-ratio:2)      and (min-width:700px),only screen and (  min--moz-device-pixel-ratio:2)      and (min-width:700px),only screen and (    -o-min-device-pixel-ratio:2/1)    and (min-width:700px),only screen and (        min-device-pixel-ratio:2)      and (min-width:700px),only screen and (                min-resolution:192dpi) and (min-width:700px),only screen and (                min-resolution:2dppx)  and (min-width:700px) {/* 中等屏幕的 retina 屏 */}@mediaonly screen and (min-width:1300px) {/* 大屏幕的非 retina 屏 */}@mediaonly screen and (-webkit-min-device-pixel-ratio:2)      and (min-width:1300px),only screen and (  min--moz-device-pixel-ratio:2)      and (min-width:1300px),only screen and (    -o-min-device-pixel-ratio:2/1)    and (min-width:1300px),only screen and (        min-device-pixel-ratio:2)      and (min-width:1300px),only screen and (                min-resolution:192dpi) and (min-width:1300px),only screen and (                min-resolution:2dppx)  and (min-width:1300px) {/* 大屏幕的 retina 设备 */}

页面 Scale

页面如何缩放,才能适应屏幕的大小?

宽度自适应

rem 方法

宽度自适应方法

网页元素的宽度设成百分比或vw单位,或者采用 flex 布局。

视口自动缩放,使得宽度自动适应网页大小。

width=device-width,

initial-scale=1.0,

minimum-scale=1.0,

maximum-scale=1.0,

user-scalable=no

">

缺点:宽度可以自适应,但是没法规定高度,容器会有一定程度的变形。

rem 方法

另一种方法是使用rem单位,所有网页元素的宽度和高度都设成rem单位,因此不会有变形问题。

视口不用缩放,只需要指定根元素的font-size大小。然后,根据不同网页的宽度,动态改变根元素的font-size,来调节容器的大小。

比如,设计稿的默认宽度是 750 px,为了便于计算,对应的font-size指定为1rem = 100px。如果设备的宽度是 375 px,就用脚本将font-size改为1rem = 50px。那么,某个网页元素的宽度是0.5rem,在 750px 设备下是50px,在 375px 设备下是25px。

下面就是脚本改写font-size的例子。

(function(doc, win){vardocEl = doc.documentElement;varresizeEvt ='orientationchange'inwindow?'orientationchange':'resize';varrecalc =function(){varclientWidth = docEl.clientWidth;if(!clientWidth)return;    docEl.style.fontSize =100* (clientWidth /750) +'px';  };  win.addEventListener(resizeEvt, recalc,false);  doc.addEventListener('DOMContentLoaded', recalc,false);})(document,window);

不使用 JS,单纯使用 CSS 也可以设置font-size的大小。

@media screen and (min-width:320px) {html {font-size:100px;}}@media screen and (min-width:360px) {html {font-size:112.5px;}}@media screen and (min-width:400px) {html {font-size:125px;}}@media screen and (min-width:440px) {html {font-size:137.5px;}}@media screen and (min-width:480px) {html {font-size:150px;}}

为了解决1px的 border 的问题(见后文),可以指定页面宽度,然后将页面放大dpr倍,再缩小为1/dpr,脚本代码如下。

vardpr, rem, scale;vardocEl =document.documentElement;varfontEl =document.createElement('style');varmetaEl =document.querySelector('meta[name="viewport"]');dpr =window.devicePixelRatio ||1;rem = docEl.clientWidth * dpr /10;scale =1/ dpr;// 设置viewport,进行缩放,达到高清效果metaEl.setAttribute('content','width='+ dpr * docEl.clientWidth    +',initial-scale='+ scale    +',maximum-scale='+ scale    +', minimum-scale='+ scale    +',user-scalable=no');

比如,对于iphone5(dpr=2),meta标签如下。

然后,结合屏幕宽度和 dpr 后算出 font-size (基准为 32px)。

320px 屏幕, dpr=1 ,font-size=32px

320px 屏幕, dpr=2 ,font-size=64px

375px 屏幕, dpr=2 ,font-size=75px

414px 屏幕, dpr=3, font-size=124.2px

计算规则:(屏幕宽度 * dpr ) / 10

“屏幕宽度”可以用document.documentElement.clientWidth得到。乘以dpr,是因为页面有可能为了实现1pxborder页面会缩放(scale)1/dpr倍(如果没有,则dpr=1)。

字体大小

使用了rem单位之后,页面元素会随着屏幕的增大而等比例放大,但是某些内容我们不愿意被放大,例如正文段落,而是为显示更多的文字,这时文字不使用rem作为单位,而是用px。

font-size:16px;[data-dpr="2"] input {  font-size:32px;}

上面代码中,默认字体大小是 16px,retina 设备就是 32px。

举例: iphone6 的屏幕适配

一个针对 iphone6 的高清视觉稿 750×1334

在psd文件中量出:宽高 750×300px 的div,那么如何转换成rem单位呢?

公式如下:

rem = px / 基准值;

对于一个iphone6的视觉稿,它的基准值就是75(之前有提到)。

转成 HTML 就是如下。

width: 10rem; // -> 750px

height: 4rem; // -> 300px

最后因为dpr为2,页面scale了0.5,所以在手机屏幕上显示的真实宽高应该是375×150px,就刚刚好。

1px 边框问题

高清屏下,border: 1px会显得太宽,但是安卓设备的border又不能设成 0.5 px,可以参考下面的链接。

mobile web retina下1px解决方案升级版

移动端高清屏适配方案

你可能感兴趣的:(H5 高清适配)