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