天天看點

android 布局 字型大小,移動端頁面布局及字型大小該如何設定

之前發過一篇文章《移動端應該如何動态設定字型大小?》,主要說了移動web端布局的一些解決方法,本文再一次把這個問題提出來,并分别對安卓和IOS裝置的螢幕了解做出自己的分享,在進入正文之前最好先了解:實體像素、邏輯像素、DPR和Rem。

那麼進入正文,不廢話,直接把自己了解到的和一些看法說出來。

首先是螢幕問題,現在主流的移動裝置以安卓和IOS為主,我們在制作移動端頁面也是以相容這兩種裝置去布局。

首先說iPhone,不得不說iPhone的螢幕考慮到了我們開發者的難處,進而給出iPhone螢幕的dpr都是整數值,在6plus出現之前,iphone的dpr始終是2(實體像素/邏輯像素=2),即使是6plus出現了,iphone到底其實也就隻有2,3這兩個dpr。其實6plus的實際dpr并不是整數,而是2.87左右,不過,為了友善開發者來開發,iphone6plus對其做了一個調整,将dpr調整為3,然後在對螢幕進行了一個縮放。是以我們很容易對其做到兼顧。

而安卓的dpr值,并不像iphone那樣就隻有兩個值。安卓的dpr是千奇百怪的,可能是1.5,2,3,4,2.5等等的都有。(甚至我還看到了1.7之類的,安卓的各個裝置商,玩的真尼瑪high啊。怎麼高興怎麼來。)

那麼現在開始說說移動端怎麼布局以及字型該怎麼設定,因為有各種各樣的解決方式,我就不一一贅述,直接說手淘的解決方案:flexible.js

我為什麼又一次把這個拿出來說,主要有兩點原因:1.我覺得它好用,解決方式簡單粗暴。2.它經過了比較長時間的考驗,如今手淘還在用它。

具體的使用方法自己可以去flexible.js看看,這裡我簡單說說它的方案以及個人對它的改良。

我們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,幾乎沒有13、15、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下的值去比對不同的字型大小。

android 布局 字型大小,移動端頁面布局及字型大小該如何設定

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的部分比對。