這是阿里團隊的高清方案佈局代碼,所謂高清方案就是根據設備屏幕的DPR(設備像素比,又稱DPPX,好比dpr=2時,表示1個CSS像素由4個物理像素點組成) 動態設置 html 的font-size, 同時根據設備DPR調整頁面的縮放值,進而達到高清效果。javascript
重要的事情說三遍!
毫不是每一個地方都要用rem,rem只適用於固定尺寸!
毫不是每一個地方都要用rem,rem只適用於固定尺寸!
毫不是每一個地方都要用rem,rem只適用於固定尺寸!
在至關數量的佈局情境中(好比底部導航元素平分屏幕寬,大尺寸元素),你必須使用百分比或者flex才能完美佈局!
看過 《手機端頁面自適應解決方案—rem佈局》的朋友,應該對rem有所瞭解,這裏再也不贅述,
此方案也是默認 1rem = 100px,因此你佈局的時候,徹底能夠按照設計師給你的效果圖寫各類尺寸啦。
好比你在效果圖上量取的某個按鈕元素長 55px, 寬37px ,那你直接能夠這樣寫樣式:css
.myBtn { width: 0.55rem; height: 0.37rem; }
許多同窗對該方案存在很多誤解致使使用出現各類問題,這裏統一回復下。html
答:老實說固然能夠,不過爲了規範,640或者750是相對合適的。
拿Iphone 5s 舉例,它的css像素寬度是320px,因爲它的dpr=2,因此它的物理像素寬度爲320 × 2 = 640px,這也就是爲何,你在5s上截了一張圖,在電腦上打開,它的原始寬度是640px的緣由。
那 iphone 6 的截圖寬度呢? 375 × 2 = 750
那 iphone 6 sp 的截圖寬度呢? 414 × 3 = 1242
以此類推,你如今能明白效果圖爲何通常是 640 ,750 甚至是 1242 的緣由了麼?(真沒有歧視安卓機的意思。。。)java
答:假設你的效果圖寬度是750,在這個效果圖上可能有一個寬度爲7rem(高清方案默認 1rem = 100px)的元素。咱們知道,高清方案的特色就是幾乎完美還原效果圖,也就是說,你寫了一個寬度爲 7rem 的元素,那麼在目前主流移動設備上都是7rem。然而,iphone 5 的寬度爲640,也就是6.4rem。因而橫向滾動條不可避免的出現了。
怎麼辦呢? 這是我目前推薦的比較安全的方式:若是元素的寬度超過效果圖寬度的一半(效果圖寬爲640或750),果斷使用百分比寬度,或者flex佈局。就像把等屏寬的圖片寬度設爲100%同樣。react
答:先說高清方案代碼,再次強調我們的高清方案代碼是根據設備的dpr動態設置html 的 font-size,
若是dpr=1(如電腦端),則html的font-size爲50px,此時 1rem = 50px
若是dpr=2(如iphone 5 和 6),則html的font-size爲100px,此時 1rem = 100px
若是dpr=3(如iphone 6 sp),則html的font-size爲150px,此時 1rem = 150px
若是dpr爲其餘值,即使不是整數,如3.4 , 也是同樣直接將dpr 乘以 50 。git
再來講說效果圖,通常來說,咱們的效果圖寬度要麼是640,要麼是750,不管哪個,它們對應設備的dpr=2,此時,1 rem = 50 × 2 = 100px。這也就是爲何高清方案默認1rem = 100px。而將1rem默認100px也是好處多多,能夠幫你快速換算單位,好比在750寬度下的效果圖,某元素寬度爲53px,那麼css寬度直接設爲53/100=0.53rem了。github
然而極少狀況下,有設計師將效果圖寬定爲1242px,由於他手裏只有一個iphone 6 sp (dpr = 3),設計完效果圖恰好能夠在他的iphone 6 sp裏查看調整。一切完畢以後,他將這個效果圖交給你來切圖。因爲這個效果圖對應設備的dpr=3,也就是1rem = 50 × 3 = 150px。因此若是你量取了一個寬度爲90px的元素,它的css寬度應該爲 90/150=0.6rem。因爲我們的高清方案默認1rem=100px,爲了還原效果圖,你須要這樣換算。固然,一個技巧就是你能夠直接修改我們的高清方案的默認設置。在代碼的最後 你會看到 flex(100, 1) ,將其修改爲flex(66.66667, 1)(感謝簡友:V旅行指出此處錯誤! 2017/3/24)就不用那麼麻煩的換算了,此時那個90px的直接寫成0.9rem就能夠了。瀏覽器
答:點我,這是我對該問題的總結安全
答:我們的rem適合寫固定尺寸。其他的根據須要換成flex或者百分比。源碼示例中就有這三種的綜合運用。微信
點擊瀏覽:一個標準的640手機頁面設計稿參考(沒錯,在此方案中,你能夠徹底按照這張設計稿的尺寸寫佈局了。就是這麼簡單!)
'use strict'; /** * @param {Number} [baseFontSize = 100] - 基礎fontSize, 默認100px; * @param {Number} [fontscale = 1] - 有的業務但願能放大必定比例的字體; */ const win = window; export default win.flex = (baseFontSize, fontscale) => { const _baseFontSize = baseFontSize || 100; const _fontscale = fontscale || 1; const doc = win.document; const ua = navigator.userAgent; const matches = ua.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i); const UCversion = ua.match(/U3\/((\d+|\.){5,})/i); const isUCHd = UCversion && parseInt(UCversion[1].split('.').join(''), 10) >= 80; const isIos = navigator.appVersion.match(/(iphone|ipad|ipod)/gi); let dpr = win.devicePixelRatio || 1; if (!isIos && !(matches && matches[1] > 534) && !isUCHd) { // 若是非iOS, 非Android4.3以上, 非UC內核, 就不執行高清, dpr設爲1; dpr = 1; } const scale = 1 / dpr; let metaEl = doc.querySelector('meta[name="viewport"]'); if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); doc.head.appendChild(metaEl); } metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`); doc.documentElement.style.fontSize = `${_baseFontSize / 2 * dpr * _fontscale}px`; };