背景:
- 開發移動端H5頁面
- 一套設計圖
- 不同尺寸的手機
- 不同分辨率的手機
方案:使用rem作為單位解決一套設計圖適應不同分辨率,不同尺寸的手機。
概念:
- REM(font size of the root element). 相對於<html>的font-size的計算方式。
- dpr(device pixel ratio).設備像素比;i5,6 = 2;i6plus=3;
- <meta content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0" name="viewport" />
- ve,vh:Length units representing 1% of the viewport size for viewport width (vw), height (vh), the smaller of the two (vmin), or the larger of the two (vmax).“視區”所指為瀏覽器內部的可視區域大小,即
window.innerWidth/window.innerHeight
大小.vw單位巧妙實現滾動條出現頁面不跳動
思路:a,相同的rem,只需要更改頁面根元素的font-size;
- 通過媒體查詢根據屏幕區間,更改html的font-size.把與元素尺寸有關的css,如width,height,line-height,margin,padding等都以rem作為單位,這樣頁面在不同設備下就能保持一致的網頁布局。;
- 布局
@media screen and (max-width: 320px) { html{font-size: 14px;} } @media screen and (min-width: 321px) and (max-width: 413px) { html{font-size: 16px;} } @media screen and (min-width: 414px) and (max-width: 639px) { html{font-size: 17px;} } @media screen and (min-width: 640px) { html{font-size: 18px;} }
- 布局
- 通過js庫,動態更改html的font-size;(lib-dlexiable);
常見問題:
- 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(); }
- 字體會隨着屏幕自由變化
@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); }
- border:1px 的做法(有好的做法,請推薦,謝謝)
@mixin border-dpr($side,$size,$color){
border-#{$side}: $size solid $color;
[data-dpr="2"] & {
border-#{$side}: $size * 2 solid $color;
}
[data-dpr="3"] & {
border-#{$side}: $size * 3 solid $color;
}
} - 雪碧圖錯位問題:a,先放大100倍,提高圖片精度,找到圖片位置,再縮小100倍;b,最好是使用字體圖標;c,單個背景
.icon-fix { background: none; position: relative; overflow: hidden; } .icon-fix:after { content: ''; display: block; width: 10000%; height: 10000%; position: absolute; left: 0; top: 0; background-image: url(sprite.png); background-repeat: no-repeat; background-size: 140rem; -webkit-transform-origin: 0 0; -webkit-transform: scale(.01); transform-origin: 0 0; transform: scale(.01); } .icon3:after { background-position: 0 -280rem; }
- 設計稿px轉成rem:640的設計稿$base:40;750的設計稿$base:75.
@function pxToRem($px, $base: 40) {
@return ($px / $base) * 1rem;
}
#demo{with:pxToRem(30)} - flexible使用文檔說明:詳情文檔查考:http://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html
- <head>中添加對應的flexible_css.js和flexible.js文件。一定是要在head中先引入。
- 執行這個JS后,會在
<html>
元素上增加一個data-dpr
屬性,以及一個font-size
樣式。JS會根據不同的設備添加不同的data-dpr
值,比如說2
或者3
,同時會給html
加上對應的font-size
的值,比如說75px;
- 在js中設置柵格數
-
function refreshRem(){
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {//目前主流手機最大的css像素尺寸,是540(比如devicePixelRatio為2,分辨率是1080x1920的手機),所以用了這個經驗值。這樣可以讓在ipad橫屏這種情況下瀏覽無線頁面,不至於因為拉伸適配后體驗太差。
width = 540 * dpr;
}
var rem = width / 16;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
-
- 頁面中的元素,都可以通過
rem
單位來設置。他們會根據html
元素的font-size
值做相應的計算,從而實現屏幕的適配效果 - 其中
initial-dpr
會把dpr
強制設置為給定的值。如果手動設置了dpr
之后,不管設備是多少的dpr
,都會強制認為其dpr
是你設置的值。Android系列,始終認為其dpr
為1
。 - 事實上他做了這幾樣事情:
- 動態改寫
<meta>
標簽 - 給
<html>
元素添加data-dpr
屬性,並且動態改寫data-dpr
的值 - 給
<html>
元素添加font-size
屬性,並且動態改寫font-size
的值
- 動態改寫
討論:
- 字體需不需設置成px?()
- 原先設計圖是640的,新設計圖是750的。如何兼容之前的版本?
- 能不能在refeshRem中的540適當的放大,從而支持pad樣式?
- rem兼容哪些坑?
- 部分小機型,頁面渲染meta沒有渲染出來。
- dpr是3的時候scale是0.333333333不是1:1
- 圖片服務器。高清屏看高清圖。
H5適配終端數據
參考文檔:http://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html