1.思路
1)选择一种尺寸作为设计和开发基准
2)定义一套适配规则,自动适配剩下的两种尺寸,其实不止两种
3) 特殊适配效果给出
2.基本概念
1)物理像素
2)设备独立像素 dp 与屏幕密度有关,可以用来辅助区分是否是视网膜设备,
3)css像素 (DPIS) 抽象单位,使用在浏览器上,用来精确度量web页面内容。
4)屏幕密度 (PPI) 一个设备表面上存在的像素数量,以每英寸有多少像素来计算。
5)设备像素比 (dpr)物理像素 / 设备独立像素
-- window.devicePixelRatio 获取当前设备的dpr
-- -webkit-device-pixel-ratio, -webkit-min-device-pixel-ratio, -webkit-max-device-pixel-ratio 进行媒体查询,对不同的dpr做一些适配(只是webkit和webview)
示例:ip6的设备 宽高 375*667,可以理解为设备的独立像素。 它的dpr为2,物理像素为,750pt*1334pt;
某个元素css为
width:200px; height:200px;
不同屏幕上css像素所呈现的物理尺寸是一致的,而不同的是css像素所对应的物理像素不一致。
普通屏幕1个css像素对应1个物理像素
Retina屏幕1个css像素对应四个物理像素
6) viewport meta标签 之后重度依赖
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" >
7) rem
3. 具体方案
大概原理
-- 动态改写 meta 标签 --给html加上data-dpr属性,动态改写data-dpr的值 --给html增加font-size属性,动态改写font-size的值
1)库 lib-flexible
原理:在所有js执行之前加载这个js,会在html标签上增加一个data-dpr 属性,以及一个 font-size 样式,js会根据不同的设备添加不同的dpr,同时给html加上对应的font-size值,这样页面中的所有的元素都可以通过rem来设置,
注意:也可以通过 <meta name="flexible" content="initial-dpr=2" /> 来强制设置dpr,不建议
2)设置dpr的方案
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; }
3)动态改写meta标签
var metaEl = doc.createElement(‘meta‘); var scale = 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 { var wrap = doc.createElement(‘div‘); wrap.appendChild(metaEl); documen.write(wrap.innerHTML); }