關于Html5使用js+sass+compass實現高清適配
手機適配問題,已經是移動前端老話常談的主題了,繁星UED上也寫過了關于rem的使用文章(wangfajing大神),然而在繁星移動前端的頁面中卻沒有把這一套適配方案使用起來,Amfe阿里無線前端團隊雙11技術連載分享中也提到了手淘的H5頁面是如何實現多終端適配,于是本人借鑒阿里的方案,在繁星移動前端進行實踐踩坑。
一、多屏適配問題
適配各種手機屏幕大小,目前最好方案莫過于使用相對單位rem。
rem的原理是根據html根元素的font-size值對元素進行大小設置,比如在根元素設定font-size = 16px,那么一個div寬度為1rem,實際即1*16px。
根據這個原理,我們針對不同手機的屏幕寬度,動態改變根節點html的font-size,就可以等比例的放大縮小頁面各個元素,從而達成適配。
1.了解viewport
viewport不局限于瀏覽器的可視區域大小,它可能比瀏覽器的可視區域要大,也可能比瀏覽器的可視區域要小。一般來講,移動設備上的viewport都是要大于瀏覽器可視區域的,這是因為考慮到移動設備的分辨率相對于桌面電腦來說都比較小,所以為了能在移動設備上正常顯示那些傳統的為桌面瀏覽器設計的網站,移動設備上的瀏覽器都會把自己默認的viewport設為980px或1024px。這也是手機上看電腦網頁為什么縮小的原因。因此加下面一段代碼可以讓viewport等于手機屏幕寬度。這時候看電腦的網頁,會出現左右滑動,因為頁面的元素css寬度超過了viewport。
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
2.提取基準:
document.documentElement.style.fontSize = clientWidth / 10 + 'px';
除以10,是為了取整,方便計算,理論上可以是任何值。clientWidth為移動設備上的viewport寬度。
2.計算rem(sass+compass)
由于rem是寫在css里面的,但每個元素大小的值都要計算得出,需要在css里面寫函數計算,這時sass登場了。參考 sass十分鐘入門
先安裝ruby,再安裝sass以及compass,compass是把sass文件.scss編譯成css文件,這里需要手動敲命令編譯,暫時沒自動化。
gem install sass gem install compass
新建index.scss
$uiWidth:360px;//UI效果圖的寬度一半
@function pxToRem($px){
@return 10*$px/$uiWidth/2*1rem;
}
div{
width:pxToRem(100px);
} 執行編譯操作就得到想要的index.css
sass --watch index.scss:index.css
3.舉個例子驗證
一個720px的UI圖(一般UI會放大兩倍畫圖),其中一個div100px,在320px寬的手機上該div應該顯示多少?典型等比例計算:
手機css寬度=320*100/720=(320*100*10)/(720*10)=(320*100*10)/(360*2*10)=((100*10)/(360*2)) * (320/10) 手機css寬度=rem * font-size ((100*10)/(360*2))作為rem數值,100即$px,360即uiWidth,于是把10*$px/$uiWidth/2*1rem作為pxToRem函數的返回值,只要在UI圖上測量多少,代入$px,自動算出對應的rem值多少; (320/10)作為基準賦予font-size,320即clientWidth
二、retina下border:1px問題
在retina屏幕中1px的border會顯得粗一點,解決辦法是根據設備像素比dpr,對頁面中的所有的border: 1px都縮小1/dpr倍,從而達到高清效果。注意:放大兩倍viewport,對于px為單位的元素其實就縮小了兩倍。
<meta name="viewport" content="width=device-width, initial-scale=1/dpr, minimum-scale=1/dpr, maximum-scale=1/dpr, user-scalable=no">
三、圖片高清和文字大小問題
1.retina屏幕需要高清圖片,然而普通屏幕加載高清圖片卻浪費資源耗帶寬,因此根據不同手機dpr加載不同的圖片可以解決這問題。
@mixin img-dpr(){
background-image: url(image.jpg);//默認
[data-dpr="2"] & {
background-image: url(image@2x.jpg);//兩倍高清
}
[data-dpr="3"] & {
background-image: url(image@3x.jpg);//三倍高清
}
}
.content{
@include img-dpr();
} 2.使用了rem之后,頁面元素會隨著屏幕的增大而等比例放大,但是某些內容我們不愿意被放大,例如正文段落,而是為顯示更多的文字,這時文字則不使用rem作為單位,而是用px。但由于在解決border:1px問題的時候對頁面進行了縮放scale,因此設置字體需要乘上dpr,否則字體會變得很小。
@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;
}
}
.content{
@include font-dpr(12px);
} 注意:別忘了在html設置data-dpr屬性,css hack用。document.documentElement.setAttribute('data-dpr', dpr);由于android酷狗內嵌頁對于縮放scale不支持,因此dpr始終為1,即忽略border:1px問題,而且這個影響不大,反正個人覺得厚一點的border也沒那么難看。
四、總結
如有理解錯誤,歡迎糾正。以上陳述都傾向直接運用,如果需要了解詳細的概念,參考以下地址:
http://www.html-js.com/article/3041
http://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html //淘寶方案
來自: http://ued.fanxing.com/guan-yu-html5shi-yong-jssasscompassshi-xian-gao-qing-gua-pei/