基本概念
基本概念来自于网上的博文,非原创,主要用于收藏,会在文末附上链接。在项目应用中目录中总结了日常用到过的适配方法。
三个基本概念
- 布局视口 :布局视口是网页布局的基准窗口,在PC浏览器上,布局视口就等于当前浏览器的窗口大小(不包括borders 、margins、滚动条)。
在移动端,布局视口被赋予一个默认值,大部分为980px,这保证PC的网页可以在手机浏览器上呈现,但是非常小,用户可以手动对网页进行放大。
我们可以通过调用document.documentElement.clientWidth / clientHeight来获取布局视口大小。
2. 视觉视口 :用户通过屏幕真实看到的区域。
视觉视口默认等于当前浏览器的窗口大小(包括滚动条宽度)。
当用户对浏览器进行缩放时,不会改变布局视口的大小,所以页面布局是不变的,但是缩放会改变视觉视口的大小。
例如:用户将浏览器窗口放大了200%,这时浏览器窗口中的CSS像素会随着视觉视口的放大而放大,这时一个CSS像素会跨越更多的物理像素。
所以,布局视口会限制你的CSS布局而视觉视口决定用户具体能看到什么。
我们可以通过调用window.innerWidth / innerHeight来获取视觉视口大小。
3.理想视口 :网站页面在移动端展示的理想大小。理想视口并没有一个固定的尺寸,不同的设备拥有有不同的理想视口。是最适合移动设备的viewport,理想视口的宽度等于移动设备的屏幕宽度,只要在css中把某一元素的宽度设为理想视口的宽度(单位用px),那么这个元素的宽度就是设备屏幕的宽度了,也就是宽度为100%的效果。理想视口 的意义在于,无论在何种分辨率的屏幕下,那些针对理想视口而设计的网站,不需要用户手动缩放,也不需要出现横向滚动条,都可以完美的呈现给用户。
我们可以通过调用screen.width / height来获取理想视口大小。
一个meta 标签
元素表示那些不能由其它HTML元相关元素之一表示的任何元数据信息,它可以告诉浏览器如何解析页面。value | 可能值 | 描述 |
---|---|---|
width | 正整数或device-width | 以像素为单位,定义布局视口的宽度 |
height | 正整数或device-height | 以像素为单位,定义布局视口的高度 |
initial-scale | 0.0-10.0 | 定义页面初始缩放率 |
minimum-scale | 0.0-10.0 | 定义缩放的最小值,必须小于等于maximum-scale的值 |
maximum-scale | 0.0-10.0 | 定义缩放的最大值,必须大于等于minimum-scale的值 |
user-scalable | 一个布尔值(yes或no) | no,用户将不能放大或缩小网页,默认值为yes |
如何适配移动端
1.固定高度,宽度自适应。
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
如果网页垂直方向使用固定的值,水平方向使用弹性布局,元素采用定值、百分比、flex布局等。可以采用这种方案。
如果网页采用其他的布局方式,宽度过宽,则可能会被压缩比较严重,字体会很小,影响识别,不推荐此方案。
2.固定布局视口宽度,使用viewport进行缩放。
此方案比较适合设计稿和页面本来尺寸与移动端的尺寸相差不大的情况,这样在缩放的时候不会导致过大或者过于小。例如设计稿和页面的最大宽度是640px,则像下面代码那样固定在640px,这样不会出现很想滚动条,在480px或者700px左右的设备上面显示缩放的时候也基本都能适应。
同上,若是页面宽度过宽,再压缩时则可能会被压缩比较严重,字体会很小,影响识别,不推荐此方案。
代码示例:
荔枝的代码:
if(/Android (\d+\.\d+)/.test(navigator.userAgent)){
var version = parseFloat(RegExp.$1);
if(version>2.3){
var phoneScale = parseInt(window.screen.width)/640;
if(/MZ-M571C/.test(navigator.userAgent)){
document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
}else if(/M571C/.test(navigator.userAgent)&&/LizhiFM/.test(navigator.userAgent)){
document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
}else{
document.write('<meta name="viewport" content="width=640, minimum-scale = '+ phoneScale +', maximum-scale = '+ phoneScale +', target-densitydpi=device-dpi">');
}
}else{
document.write('<meta name="viewport" content="width=640, target-densitydpi=device-dpi">');
}
}else{
document.write('<meta name="viewport" content="width=640, user-scalable=no, target-densitydpi=device-dpi">');
}
网易应用:
var win = window,
width = 640,
iw = win.innerWidth || width,
ow = win.outerHeight || iw,
sw = win.screen.width || iw,
saw = win.screen.availWidth || iw,
ih = win.innerHeight || width,
oh = win.outerHeight || ih,
ish = win.screen.height || ih,
sah = win.screen.availHeight || ih,
w = Math.min(iw, ow, sw, saw, ih, oh, ish, sah),
ratio = w / width,
dpr = win.devicePixelRatio;
if (ratio = Math.min(ratio, dpr), 1 > ratio) {
var ctt = ",initial-scale=" + ratio + ",maximum-scale=" + ratio,
metas = document.getElementsByTagName("meta");ctt += "";
for (var i = 0, meta; i < metas.length; i++) meta = metas[i], "viewport" == meta.name && (meta.content += ctt)
}
3.上面的方式,在放大缩小的时候字体都会跟随放大缩小,有时候会过于小,影响识别,若需要字体自适应,可以使用rem。
由于rem是相对于根元素的单位,阿里团队开源过一个lib-flexible.js的库,主要通过根据设备屏幕的大小,自动的调整根元素的font-size的大小,以此来动态调整rem的大小,实现自适应。不过css的单位需要用rem。
有兴趣可以移步: lib-flexible.js.
最后补充一点:当width=640, initial-scale=1 两个同时设置的时候,取较大值。
例如:若设备的理想视口宽度是375px,因为:375 / 视觉视口 = 1,得视觉视口为375 < 640,那么布局视口和视觉视口取值是640px。若设备的理想视口是760px,因为:760 / 视觉视口 = 1,得视觉视口为760 > 640, 所以最终布局视口和视觉视口都是760px
文章来源:移动端页面适配———多方案解析