這兩天要把公司以前的觸屏設備的客戶端應用做成h5的web應用,而且有針對不同設備和同一設備下的不同狀態(有windows豎屏和橫屏和android的平板),而且都有設計師為其針對的不同設計標准包括字體大小和不同ui組件的大小,雖然當時經過討論,公司老員工建議就按照這個標准去做,不用考慮自適應,因為設備就這幾種,但是我是一直不甘心,總想把它做成能適配不同設備分辨率的東西,所以來研究這個問題(在了解rem之前,我會做自適應,但只是在做了布局上的自適應,不包括字體)。
因為在之前的公司做過的項目中的某些模塊參照過別的產品,發現過有用rem和em的,然后就來網上研究學習了解了下這幾種相對單位。其中就找到了這篇文章:http://isux.tencent.com/web-app-rem.html,發現這篇文章對除了rem來設計界面的其他方法做了介紹和總結。文章總結了rem相對於其他幾種設計方法的好處,其他幾種方法的壞處,具體那些壞處朋友可以去看下這篇文章。
之所以之前沒有去研究學習rem,包括之前沒有去研究接受其他的新技術,比如es6,前端mvvm框架、模塊化開發、項目構建,編譯,打包發布工具等等。是因為在之前的所在公司,公司任務比較充實,每天都有任務要做,那時用的基本都是老技術,單純的用html,css,js,jq,easyui,bootstrap開發,雖然有點厭倦,寫的代碼比較low,但還好業務邏輯這方面比較有趣,有些界面實現也比較有趣(一直很喜歡做界面),加上我本身工作責任心強,所以那時每天還算過得充實。充實的結果導致我每天都在做任務,幾乎每天晚上7,8點下班回家,然后吃飯,再洗涑,再搞會其他的,基本上就9點過,10點了,這樣下來一天也比較疲倦,就經常導致我無心再學習其他新技術,只想休息放松下,那時我周6加班還是比較頻繁,然后就基本只有周日了,但是由於想睡懶覺和要洗衣服,打游戲,所以學習時間也變得比較少了,總得意思就是學習時間變少了(但是我不是完全不學習,但那時主要學習js和css去了,那本es5我看了好多遍,每次都有新收獲。),當然這其中很大原因還是我懶,其實我還是寫了好些博客草稿,只不過都因為這個懶的原因沒有去整理發布(10篇沒有發布)。。。。。
但是那段時間還是過得很有價值的,鍛煉了我編程的思維邏輯(我是后台出身,還是有點面向對象的概念,學習js也不是那么吃力。在學校學習了一年C#.NET,然后當初應聘的第一份工作是.net,但是公司框架已成熟,對前端需求大,我就去做了前端,然后愛上了前端,但是公司的幾個簡單常用的小接口還是我寫的,雖然借鑒了些百度。到了現在的公司,由於公司需要,我也會偶爾負責后端開發,比如公司現在的一個小型cms,我獨立開發,完全獨立開發,從數據庫到c#.net的數據層,業務層(業務層很少,業務主要在前端,除了通用的數據接口,后端的業務層主要是一些安全驗證,比如對前端編碼過的where條件解碼,過濾sql,避免sql注入;所有的一般處理程序只是作為一個入口,具體的代碼編譯進dll,雖然作用可能小,但是總比沒有好)等等(后台用三層架構,沒用mvc),通用的數據接口和比較常用的接口是自己參照之前公司接口思想寫的(包括樹,grid分頁等),沒有用第三方框架。當然我的C#.NET還是只是皮毛,數據庫設計也是會相對比較簡單的的東西,表創建和視圖自己寫,存儲過程用的別個現成的稍微改了一點點(主要是分頁存儲過程等通用的,只是加了個where條件參數。等我把前端想學的學完了,我可能會去學sql,學存儲過程),當然我主要喜歡前端,以后也會一直向前端發展,后台我只需要懂點皮毛就可以了,有后台那個概念就OK,主要就是了解B&S的前后端的交互,即瀏覽器http和服務器的交互,以及前后端的生命周期。)。因為業務邏輯復雜好玩,任務多,當業務邏輯多到我覺得我的代碼是垃圾,不堪入目,當時一直沒有好的方法去解決這些痛點,現在才體會到原來這些新技術就是解決這些痛點的,並且這些技術會規范你的項目開發邏輯,深深的體會到mvvm設計模式很適合web前端(這里我很推崇vue,漸進式的前端框架,組件化的思想,相對其他框架來說,它做模塊化開發,開發大型應用會比較簡單,環境搭建也很簡單,有官方的腳手架工具vue-cli(安裝cli之前,先安裝webpack,最好是用淘寶鏡像cnpm安裝),地址:http://cn.vuejs.org/v2/guide/installation.html)。
到了現在的一家公司,由於公司的任務不是那么多,時間也比較足,所以我在空閑時間會去研究怎么讓我的代碼更簡潔、更具可讀性,更抽象、更高效的去實現功能業務需求,讓項目模塊具有可擴展,可復用,易於變更,高內聚低耦合等等。然后就去探索,發現很多驚喜,發現還有很多需要學習的新技術,實際上當你認真的去了解這些技術后,發現也沒有想象種那么難,反而是讓你的開發變得更簡單。
回歸正題,我以前做界面就是上面那篇文章里提到的流式布局(主要用bootstrap柵格布局),寬度百分比,高度固定(最開始我高度也百分比,顯然不行),這種方式的壞處就是兼容性不是很好,只適應特定的幾種分辨率,也不好維護。下面我就來介紹下最終我覺得很好的rem(如果設計師沒用給出明確的組件大小,可以結合bootstrap柵格布局實現快速布局,並且后期可以改造成響應式布局,可以到bootstrap官網定制下載只包含柵格的css代碼)。
/***************START*************************************/
假設設計師的視覺稿是按照iPhone6的寬度來設計的,即375px (如果是高清的視覺稿750/2=375)
那么,我們可以完全按照視覺稿上的尺寸來賦值給元素的樣式,比如視覺稿上的尺寸是80px,那么在css中就可以直接定義width:80px; 頁面中所有的尺寸都這樣來設置。
當所有的網站所有的頁面樣式都設置好之后。
我們需要做兩件事情:
1. 設置頁面的rem大小
```css
html { font-size: calc(100vw/3.75); }
100vw是設備的寬度,除以3.75可以讓1rem的大小在iPhone6下等於100px
2. 替換頁面中的單位,把所有的px單位替換成rem,除以100,比如前面的80px,就是0.8rem
這樣在iPhone6下,所有元素的尺寸還是和視覺稿的尺寸一樣,而iphone5中,因為設備的寬度變小了,100vw/3.75得到的值,會相應的變小,即rem的單位值會變小,頁面中所有的尺寸會等比例縮放。
這樣就可以做到針對任何分辨率的設備保持視覺一致了。
最后,前面用到vw單位,但是低版本的設備可能不支持,那么就需要js來處理一下:
```javascript
document.documentElement.style.fontSize = window.innerWidth/3.75 + 'px'
之所以前面讓1rem等於100px,而不是1rem等於1px,是因為在chrome下針對中文的最小字體是12px。
當然,這種步驟是針對現在的狀況改rem來做的,如果一開始就是使用rem,那么寫css的時候,可以直接寫rem單位,按視覺稿除以100,其實也沒有什么計算過程。或者用預處理器的話,也可以寫一個`px2rem`的函數,直接改這個函數就可以了。
document.documentElement.style.fontSize = window.innerWidth/10.80 + 'px',這樣在1080設備上的html的font-size=100px,0.14rem就等於14px;
這樣就能兼容不同設備分辨率了,比如,如果在2160px設備分辨率下,html的font-size經計算就等於200px,那么0.14rem=0.14rem*200=28px了。