以前發過一篇文章《移動端應該如何動態設置字體大小?》,主要說了移動web端佈局的一些解決方法,本文再一次把這個問題提出來,並分別對安卓和IOS設備的屏幕瞭解作出本身的分享,在進入正文以前最好先了解:物理像素、邏輯像素、DPR和Rem。html
那麼進入正文,不廢話,直接把本身瞭解到的和一些見解說出來。android
首先是屏幕問題,如今主流的移動設備以安卓和IOS爲主,咱們在製做移動端頁面也是以兼容這兩種設備去佈局。git
首先說iPhone,不得不說iPhone的屏幕考慮到了咱們開發者的難處,從而給出iPhone屏幕的dpr都是整數值,在6plus出現以前,iphone的dpr始終是2(物理像素/邏輯像素=2),即便是6plus出現了,iphone到底其實也就只有2,3這兩個dpr。其實6plus的實際dpr並非整數,而是2.87左右,不過,爲了方便開發者來開發,iphone6plus對其作了一個調整,將dpr調整爲3,而後在對屏幕進行了一個縮放。因此咱們很容易對其作到兼顧。github
而安卓的dpr值,並不像iphone那樣就只有兩個值。安卓的dpr是千奇百怪的,多是1.5,2,3,4,2.5等等的都有。(甚至我還看到了1.7之類的,安卓的各個設備商,玩的真尼瑪high啊。怎麼高興怎麼來。)web
那麼如今開始說說移動端怎麼佈局以及字體該怎麼設置,由於有各類各樣的解決方式,我就不一一贅述,直接說手淘的解決方案:flexible.jssegmentfault
我爲何又一次把這個拿出來講,主要有兩點緣由:1.我以爲它好用,解決方式簡單粗暴。2.它通過了比較長時間的考驗,現在手淘還在用它。app
具體的使用方法本身能夠去flexible.js看看,這裏我簡單說說它的方案以及我的對它的改良。iphone
咱們UI在製做移動端頁面時,主流的寬度有640、750或者還有其餘尺寸,這裏咱們用640作爲例子,那麼手淘的作法就是將640的寬度分爲10份,每份是64,那麼1個rem=64px,也就是說此時 html{font-size:64px;}
,好比設計稿中有個元素寬64px,高128px,那麼這個div的寬用rem表示就是:64(設計稿元素的寬)/64(1rem爲64px)=該元素計算出的rem值
,同理高度從px換成rem就是128/64=2rem
樣式就是div{width:1rem;height:2rem;}
。而後再配上flexible.js的代碼段:佈局
function refreshRem(){ var width = docEl.getBoundingClientRect().width; if (width / dpr > 540) { width = 540 * dpr; } var rem = width / 10;//看到了嗎 看到了嗎 這句話 分紅10份哦 docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem; }
對於佈局,咱們可使用rem去結局,那麼字體呢?字體
你們知道,如今PC端主流的字體大小都是相似12px、14px、16px,幾乎沒有1三、1五、17這樣的數字出現,至於爲何,請進穿越門瞭解。若是咱們用rem作爲字體單位,那麼轉成px的時候,勢必會出現奇數或者小數的狀況,爲了不這種狀況,咱們仍是要用px作爲字體的單位。那麼又如何用px去看成字體大小呢?
首先看這段代碼:
div { width: 1rem; height: 0.4rem; font-size: 12px; // 默認寫上dpr爲1的fontSize } [data-dpr="2"] div { font-size: 24px; } [data-dpr="3"] div { font-size: 36px; }
沒有錯,手淘的解決方案就是默認寫個dpr爲1時的字體大小,而後根據不一樣dpr下的值去匹配不一樣的字體大小。
flexible會獲取設備的dpr值,而後在html標籤上自定義data-dpr屬性,並放入dpr值,後面的font-size就是動態設置一個rem單位的大小。
其實我以爲這種方案挺噁心的,每一個牽扯到字體的大小就必須多些幾套去兼容,但這也算是個方案。
最後就是對flexible.js的見解,話很少說上代碼:
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) {//只對iPhone作了處理!!!! // 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; }
能夠看出,flexible中動態設置dpr時,只對iPhone進行了處理,徹底沒有把安卓放在眼裏,那安卓怎麼辦?這裏我又想吐槽安卓那些廠商,真尼瑪瞎搞,dpr設置成各類非主流數值,玩死咱們這些碼農了,連flexible都不想管了。吐槽到此爲止,那麼該怎麼改良它,讓它能對安卓手機也能動態設置dpr呢?咱們將這段代碼改一下:
if (!dpr && !scale) { //devicePixelRatio這個屬性是能夠獲取到設備的dpr var devicePixelRatio = win.devicePixelRatio; //判斷dpr是否爲整數 var isRegularDpr = devicePixelRatio.toString().match(/^[1-9]\d*$/g) if (isRegularDpr) { // 對因而整數的dpr,對dpr進行操做 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 對於其餘的dpr,人採用dpr爲1的方案 dpr = 1; } scale = 1 / dpr; }
咱們對這裏作了一點點修改,即來判斷dpr是不是規則的,也就是是不是咱們常見的1,2,3等,而後,咱們只對規則的dpr,來進行一個字體的處理。這樣,iphone依然仍是用以前的匹配方案。而其實目前安卓,不少的設備仍是比較常見的dpr了,因此咱們這裏,將以前對設備的判斷,轉變成對dpr是不是整數的一個判斷。其餘地方不變,能夠解決對安卓dpr的部分匹配。