H5移動(dòng)端適配 Flexible方案
一、移動(dòng)端一些概念
視覺(jué)稿 (選取一款手機(jī)的屏幕寬高作為基準(zhǔn))
在前端開(kāi)發(fā)之前,視覺(jué) MM會(huì)給我們一個(gè)psd文件,稱之為視覺(jué)稿。
對(duì)于移動(dòng)端開(kāi)發(fā)而言,為了做到頁(yè)面高清的效果,視覺(jué)稿的規(guī)范往往會(huì)遵循以下兩點(diǎn):
1)首先,選取一款手機(jī)的屏幕寬高作為基準(zhǔn)(以前是iPhone4 的320×480,現(xiàn)在更多的是iphone6的 375×667)。
2)對(duì)于retina 屏幕(如: dpr=2),為了達(dá)到高清效果,視覺(jué)稿的畫(huà)布大小會(huì)是基準(zhǔn)的2 倍,也就是說(shuō)像素點(diǎn)個(gè)數(shù)是原來(lái)的 4倍(對(duì) iphone6而言:原先的 375×667,就會(huì)變成 750×1334)。
問(wèn)題:
對(duì)于 dpr=2的手機(jī),為什么畫(huà)布大小×2,就可以解決高清問(wèn)題?
對(duì)于 2倍大小的視覺(jué)稿,在具體的 css編碼中如何還原每一個(gè)區(qū)塊的真實(shí)寬高(也就是布局問(wèn)題)?
標(biāo)注稿
移動(dòng)端尺寸
物理像素(physical pixel)
一個(gè)物理像素是顯示器(手機(jī)屏幕)上最小的物理顯示單元,在操作系統(tǒng)的調(diào)度下,每一個(gè)設(shè)備像素都有自己的顏色值和亮度值。
設(shè)備獨(dú)立像素(density-independent pixel)
設(shè)備獨(dú)立像素(也叫密度無(wú)關(guān)像素),可以認(rèn)為是計(jì)算機(jī)坐標(biāo)系統(tǒng)中得一個(gè)點(diǎn),這個(gè)點(diǎn)代表一個(gè)可以由程序使用的虛擬像素(比如: css像素),然后由相關(guān)系統(tǒng)轉(zhuǎn)換為物理像素。
設(shè)備像素比(device pixel ratio)
設(shè)備像素比(簡(jiǎn)稱 dpr)定義了物理像素和設(shè)備獨(dú)立像素的對(duì)應(yīng)關(guān)系,它的值可以按如下的公式的得到: 設(shè)備像素比 =物理像素 /設(shè)備獨(dú)立像素 //在某一方向上,x方向或者 y方向。
在Javascript 中,可以通過(guò)window.devicePixelRatio獲取到當(dāng)前設(shè)備的dpr。
在css 中,可以通過(guò)-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio進(jìn)行媒體查詢,對(duì)不同 dpr的設(shè)備,做一些樣式適配(這里只針對(duì) webkit內(nèi)核的瀏覽器和 webview)。
在普通屏幕下,1個(gè) css像素 對(duì)應(yīng) 1個(gè)物理像素(1:1)。 在 retina屏幕下,1個(gè) css像素對(duì)應(yīng) 4個(gè)物理像素(1:4)。
例:width: 2px;height: 2px; 如下
位圖像素
一個(gè)位圖像素是柵格圖像(如:png, jpg, gif等)最小的數(shù)據(jù)單元。每一個(gè)位圖像素都包含著一些自身的顯示信息(如:顯示位置,顏色值,透明度等)。
retina 下圖片的展示情況?
理論上,1個(gè)位圖像素對(duì)應(yīng)于 1個(gè)物理像素,圖片才能得到完美清晰的展示。
在普通屏幕下是沒(méi)有問(wèn)題的,但是在 retina屏幕下就會(huì)出現(xiàn)位圖像素點(diǎn)不夠,從而導(dǎo)致圖片模糊的情況。
如上圖:對(duì)于 dpr=2的 retina屏幕而言,1個(gè)位圖像素對(duì)應(yīng)于 4個(gè)物理像素,
由于單個(gè)位圖像素不可以再進(jìn)一步分割,所以只能就近取色,從而導(dǎo)致圖片模糊(注意上述的幾個(gè)顏色值)。
所以,對(duì)于圖片高清問(wèn)題,比較好的方案就是兩倍圖片(@2x)。如:200×300(css pixel)img標(biāo)簽,就需要提供 400×600的圖片。
如此一來(lái),位圖像素點(diǎn)個(gè)數(shù)就是原來(lái)的 4倍,在 retina屏幕下,位圖像素點(diǎn)個(gè)數(shù)就可以跟物理像素點(diǎn)個(gè)數(shù)形成 1 : 1的比例,圖片自然就清晰了(這也解釋了之前留下的一個(gè)問(wèn)題,為啥視覺(jué)稿的畫(huà)布大小要×2?)。
這里就還有另一個(gè)問(wèn)題,如果普通屏幕下,也用了兩倍圖片,會(huì)怎樣呢?
很明顯,在普通屏幕下,200×300(css pixel)img標(biāo)簽,所對(duì)應(yīng)的物理像素個(gè)數(shù)就是 200×300個(gè),而兩倍圖片的位圖像素個(gè)數(shù)則是 200×300*4,所以就出現(xiàn)一個(gè)物理像素點(diǎn)對(duì)應(yīng) 4個(gè)位圖像素點(diǎn),
所以它的取色也只能通過(guò)一定的算法(顯示結(jié)果就是一張只有原圖像素總數(shù)四分之一,我們稱這個(gè)過(guò)程叫做 downsampling),肉眼看上去雖然圖片不會(huì)模糊,但是會(huì)覺(jué)得圖片缺少一些銳利度,或者是有點(diǎn)色差(但還是可以接受的)。
Retina 下,圖片高清問(wèn)題
所以最好的解決辦法是:不同的dpr下,加載不同的尺寸的圖片。
不管是通過(guò) css媒體查詢,還是通過(guò) javascript條件判斷都是可以的。那么問(wèn)題來(lái)了,這樣的話,不就是要準(zhǔn)備兩套圖片了嘛?(@1x和@2x)
我想,做的好的公司,都會(huì)有這么一個(gè)圖片服務(wù)器,通過(guò) url獲取參數(shù),然后可以控制圖片質(zhì)量,也可以將圖片裁剪成不同的尺寸。
所以我們只需上傳大圖(@2x),其余小圖都交給圖片服務(wù)器處理,我們只要負(fù)責(zé)拼接 url即可。
Retina 下,border: 1px 問(wèn)題
設(shè)計(jì)師想要的 retina下 border: 1px;,其實(shí)就是 1物理像素寬,對(duì)于 css而言,可以認(rèn)為是 border:0.5px;,這是retina 下(dpr=2)下能顯示的最小單位。
然而,無(wú)奈并不是所有手機(jī)瀏覽器都能識(shí)別 border: 0.5px;,ios7以下,android等其他系統(tǒng)里, 0.5px 會(huì)被當(dāng)成為0px 處理,那么如何實(shí)現(xiàn)這0.5px 呢?
方案一: 最簡(jiǎn)單的一個(gè)做法就是這樣(元素scale):
.scale{ position: relative;}
.scale:after {content:""; position: absolute; bottom:0px; left:0px; right:0px; border-bottom:1px solid #ddd; -webkit-transform:scaleY(.5); -webkit-transform-origin:0 0;}
方案一問(wèn)題:
通過(guò) transform: scaleY(.5)縮小 0.5倍來(lái)達(dá)到 0.5px的效果,但是這樣 hack實(shí)在是不夠通用(如:圓角等)。
方案二:頁(yè)面scale的方案,是比較通用的,幾乎滿足所有場(chǎng)景。
對(duì)于 iphone5(dpr=2),添加如下的 meta標(biāo)簽,設(shè)置 viewport(scale 0.5):
頁(yè)面 scale,必然會(huì)帶來(lái)一些問(wèn)題:
1)字體大小會(huì)被縮放
2)頁(yè)面布局會(huì)被縮放(如: div 的寬高等)
二、多屏適配布局問(wèn)題
Flexible方案
1) 下載bower下載lib-flexible
將flexible_css.js,flexible.js文件加載到項(xiàng)目中:
<script src="lib/flexible.js"></script> <script src="lib/flexible_css.js"></script>
或直接加載阿里CDN的文件:
2).flexible 實(shí)際上作用
就是能過(guò)JS來(lái)動(dòng)態(tài)改寫(xiě) meta 標(biāo)簽,代碼類似這樣:
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); }
事實(shí)上他做了這幾樣事情:
添加<meta>標(biāo)簽,并動(dòng)態(tài)改寫(xiě) <meta> 標(biāo)簽
給 <html> 元素添加 data-dpr 屬性,并且動(dòng)態(tài)改寫(xiě) data-dpr 的值
給 <html> 元素添加 font-size 屬性,并且動(dòng)態(tài)改寫(xiě) font-size 的值
3. 布局(以scss為例)
1)基本布局:rem
將視覺(jué)稿中的px單位轉(zhuǎn)換成rem單位 :
html元素尺寸 = 視覺(jué)稿px值 / rem基準(zhǔn)值
例如:視覺(jué)稿寬度750px,則html中的縮放倍率就是750 / 10 = 75,然后以這個(gè)為基準(zhǔn)值,如果視覺(jué)稿中某塊小內(nèi)容寬度是150px,則html中這塊內(nèi)容寬度就是 150 / 75 = 2rem
2)字號(hào):px
字號(hào)用px單位,并根據(jù)情況用[data-dpr]屬性來(lái)區(qū)分不同dpr下的文本字號(hào)大小。
為了能更好的利于開(kāi)發(fā),在實(shí)際開(kāi)發(fā)中,我們可以定制一個(gè) font-dpr()Sass混合宏:
@mixin font-dpr($font-size){ font-size: $font-size; [data-dpr="2"] & { font-size: $font-size * 2; } [data-dpr="3"] & { font-size: $font-size * 3; } }
設(shè)置混合宏之后,在開(kāi)發(fā)中可以直接這樣使用:@include font-dpr(24px);
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Vue移動(dòng)端用淘寶彈性布局lib-flexible插件做適配的方法
- flexible.js實(shí)現(xiàn)移動(dòng)端rem適配方案
- vue-cli配置flexible過(guò)程詳解
- 詳解vue.js移動(dòng)端配置flexible.js及注意事項(xiàng)
- 基于vue-cli配置lib-flexible + rem實(shí)現(xiàn)移動(dòng)端自適應(yīng)
- 基于 flexible 的 Vue 組件:Toast -- 顯示框效果
- js中flexible.js實(shí)現(xiàn)淘寶彈性布局方案
- 同步文件備份工具 Super Flexible File Synchronizer Pro v4
- Flexible.js可伸縮布局實(shí)現(xiàn)方法詳解
相關(guān)文章
uniapp開(kāi)發(fā)APP之強(qiáng)制更新和熱更新的實(shí)現(xiàn)
使用uni-app開(kāi)發(fā),可將代碼編譯到iOS、Android、微信小程序等多個(gè)平臺(tái),升級(jí)時(shí)也需考慮多平臺(tái)同步升級(jí),下面這篇文章主要給大家介紹了關(guān)于uniapp開(kāi)發(fā)APP之強(qiáng)制更新和熱更新的相關(guān)資料,需要的朋友可以參考下2022-12-12Bootstrap富文本組件wysiwyg數(shù)據(jù)保存到mysql的方法
這篇文章主要為大家詳細(xì)介紹了Bootstrap富文本組件wysiwyg數(shù)據(jù)保存到mysql的方法,感興趣的小伙伴們可以參考一下2016-05-05常用Javascript函數(shù)與原型功能收藏(必看篇)
下面小編就為大家?guī)?lái)一篇常用Javascript函數(shù)與原型功能收藏(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10絕對(duì)經(jīng)典的滑輪新聞顯示(javascript+css)實(shí)現(xiàn)
這篇文章主要介紹了絕對(duì)經(jīng)典的滑輪新聞顯示(javascript+css)實(shí)現(xiàn),需要的朋友可以參考下2007-03-03JS限制input框只能輸入0~100的正整數(shù)的兩種方法
本文給大家分享兩種方法實(shí)現(xiàn)JS限制input框只能輸入0~100的正整數(shù),方法二是直接通過(guò)設(shè)置三個(gè)屬性,type、min、max即可,就可以設(shè)置0~100的整數(shù),感興趣的朋友跟隨小編一起看看吧2024-02-02用javascript實(shí)現(xiàn)畫(huà)圖效果的代碼
用javascript實(shí)現(xiàn)畫(huà)圖效果的代碼...2007-07-07帶參數(shù)的function 的自運(yùn)行效果代碼
這篇文章介紹了帶參數(shù)的function 的自運(yùn)行效果,通過(guò)實(shí)例對(duì)比展示了帶參數(shù)與不帶參數(shù)function自運(yùn)行效果,需要的朋友可以參考一下2007-12-12