css3--rem

DPR = 物理像素 / 逻辑像素

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

一,用媒体查询来设置html的font-size:

 

 

@media screen and (min- 320px) {
    html {font-size: 14px;}
}
 
@media screen and (min- 360px) {
    html {font-size: 16px;}
}
 
@media screen and (min- 400px) {
    html {font-size: 18px;}
}
 
@media screen and (min- 440px) {
    html {font-size: 20px;}
}
 
@media screen and (min- 480px) {
    html {font-size: 22px;}
}
 
@media screen and (min- 640px) {
    html {font-size: 28px;}
}

二、利用js来动态设置

 1 !(function(doc, win) {
 2     var docEle = doc.documentElement,
 3         evt = "onorientationchange" in window ? "orientationchange" : "resize",
 4         fn = function() {
 5             var width = docEle.clientWidth;
 6             width && (docEle.style.fontSize = 20 * (width / 320) + "px");
 7         };
 8      
 9     win.addEventListener(evt, fn, false);
10     doc.addEventListener("DOMContentLoaded", fn, false);
11  
12 }(document, window));

三、利用js计算当前设备的DPR,动态设置在html标签上,并动态设置html的font-size,利用css的选择器根据DPR来设置不同DPR下的字体大小( 推荐 )

  1 !function(win, lib) {
  2     var timer,
  3         doc     = win.document,
  4         docElem = doc.documentElement,
  5 
  6         vpMeta   = doc.querySelector('meta[name="viewport"]'),
  7         flexMeta = doc.querySelector('meta[name="flexible"]'),
  8  
  9         dpr   = 0,
 10         scale = 0,
 11  
 12         flexible = lib.flexible || (lib.flexible = {});
 13  
 14     // 设置了 viewport meta
 15     if (vpMeta) {
 16  
 17         console.warn("将根据已有的meta标签来设置缩放比例");
 18         var initial = vpMeta.getAttribute("content").match(/initial-scale=([d.]+)/);
 19  
 20         if (initial) {
 21             scale = parseFloat(initial[1]); // 已设置的 initialScale
 22             dpr = parseInt(1 / scale);      // 设备像素比 devicePixelRatio
 23         }
 24  
 25     }
 26     // 设置了 flexible Meta
 27     else if (flexMeta) {
 28         var flexMetaContent = flexMeta.getAttribute("content");
 29         if (flexMetaContent) {
 30  
 31             var initial = flexMetaContent.match(/initial-dpr=([d.]+)/),
 32                 maximum = flexMetaContent.match(/maximum-dpr=([d.]+)/);
 33  
 34             if (initial) {
 35                 dpr = parseFloat(initial[1]);
 36                 scale = parseFloat((1 / dpr).toFixed(2));
 37             }
 38  
 39             if (maximum) {
 40                 dpr = parseFloat(maximum[1]);
 41                 scale = parseFloat((1 / dpr).toFixed(2));
 42             }
 43         }
 44     }
 45  
 46     // viewport 或 flexible
 47     // meta 均未设置
 48     if (!dpr && !scale) {
 49         // QST
 50         // 这里的 第一句有什么用 ?
 51         // 和 Android 有毛关系 ?
 52         var u = (win.navigator.appVersion.match(/android/gi), win.navigator.appVersion.match(/iphone/gi)),
 53             _dpr = win.devicePixelRatio;
 54  
 55         // 所以这里似乎是将所有 Android 设备都设置为 1 了
 56         dpr = u ? ( (_dpr >= 3 && (!dpr || dpr >= 3))
 57                         ? 3
 58                         : (_dpr >= 2 && (!dpr || dpr >= 2))
 59                             ? 2
 60                             : 1
 61                   )
 62                 : 1;
 63  
 64         scale = 1 / dpr;
 65     }
 66  
 67     docElem.setAttribute("data-dpr", dpr);
 68  
 69     // 插入 viewport meta
 70     if (!vpMeta) {
 71         vpMeta = doc.createElement("meta");
 72          
 73         vpMeta.setAttribute("name", "viewport");
 74         vpMeta.setAttribute("content",
 75             "initial-scale=" + scale + ", maximum-scale=" + scale + ", minimum-scale=" + scale + ", user-scalable=no");
 76  
 77         if (docElem.firstElementChild) {
 78             docElem.firstElementChild.appendChild(vpMeta)
 79         } else {
 80             var div = doc.createElement("div");
 81             div.appendChild(vpMeta);
 82             doc.write(div.innerHTML);
 83         }
 84     }
 85  
 86     function setFontSize() {
 87         var winWidth = docElem.getBoundingClientRect().width;
 88  
 89         if (winWidth / dpr > 540) {
 90             (winWidth = 540 * dpr);
 91         }
 92  
 93         // 根节点 fontSize 根据宽度决定
 94         var baseSize = winWidth / 10;
 95  
 96         docElem.style.fontSize = baseSize + "px";
 97         flexible.rem = win.rem = baseSize;
 98     }
 99  
100     // 调整窗口时重置
101     win.addEventListener("resize", function() {
102         clearTimeout(timer);
103         timer = setTimeout(setFontSize, 300);
104     }, false);
105  
106      
107     // 这一段是我自己加的
108     // orientationchange 时也需要重算下吧
109     win.addEventListener("orientationchange", function() {
110         clearTimeout(timer);
111         timer = setTimeout(setFontSize, 300);
112     }, false);
113  
114  
115     // pageshow
116     // keyword: 倒退 缓存相关
117     win.addEventListener("pageshow", function(e) {
118         if (e.persisted) {
119             clearTimeout(timer);
120             timer = setTimeout(setFontSize, 300);
121         }
122     }, false);
123  
124     // 设置基准字体
125     if ("complete" === doc.readyState) {
126         doc.body.style.fontSize = 12 * dpr + "px";
127     } else {
128         doc.addEventListener("DOMContentLoaded", function() {
129             doc.body.style.fontSize = 12 * dpr + "px";
130         }, false);
131     }
132   
133     setFontSize();
134  
135     flexible.dpr = win.dpr = dpr;
136  
137     flexible.refreshRem = setFontSize;
138  
139     flexible.rem2px = function(d) {
140         var c = parseFloat(d) * this.rem;
141         if ("string" == typeof d && d.match(/rem$/)) {
142             c += "px";
143         }
144         return c;
145     };
146  
147     flexible.px2rem = function(d) {
148         var c = parseFloat(d) / this.rem;
149          
150         if ("string" == typeof d && d.match(/px$/)) {
151             c += "rem";
152         }
153         return c;
154     }
155 }(window, window.lib || (window.lib = {}));
原文地址:https://www.cnblogs.com/drop-in-ocean/p/7448062.html