說明:兩個方案均基於Webpack構建。javascript
自適應這裏採用了舊版的flexible,並經過px2rem來進行單位轉換,關於樣式中的px值是否轉換爲rem或者輸出多種對應不一樣dpr的px值,請查看插件說明進行對應的註釋,例如/*no*/
和/*px*/
。這裏有一點須要說明的是,與mobileweb不一樣的是,舊版的flexible具備最大寬度1080(540*dpr)的問題?也就是說當屏幕寬度大於1080的時候,兩邊會留出空白,而沒法佔滿屏幕?若有錯誤,望指正截取一段flexible代碼:css
function refreshRem() { var width = docEl.getBoundingClientRect().width; if (width / dpr > 540) { width = 540 * dpr; } var rem = width / 10; docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem; }
這裏有個小小的建議就是給body加上一段居中樣式:java
body { max-width: 750px; /* 設計稿最大寬度 */ margin: 0 auto; }
這樣當設備寬度大於設計稿的寬度時,則總體頁面居中,更加美觀。(再次強調mobileweb中用的最新的flexible會自動擴展到滿屏,不存在該問題。)jquery
module: { rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [{ loader: "css-loader" }, { loader: "px2rem-loader", options: { remUnit: 75, threeVersion: true } }, { loader: 'postcss-loader' }, { loader: "sass-loader" }, ] }) }, { test: /\.(png|svg|jpg|gif)$/, use: [{ loader: 'url-loader', options: { limit: 4096 } }] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ 'file-loader' ] }, { test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' }, { loader: 'expose-loader', options: '$' }] } ] },
主要是px2rem-loader這裏的對px2rem的相關配置,我這裏設計稿750,所以設定75,其餘參數可自行參考文檔。webpack
注1:git
這個demo依然有引入PostCSS,由於webpack下沒有一個很好autoprefixer的loader(其實有一個autoprefixer-loader,該loader也提示了autoprefixer官方推薦使用postcss-loader替代),所以依然加入了PostCSS混合SASS開發。github
注2:web
不太肯定若是單位寫成PX是否會存在兼容性問題,不過在高級瀏覽器和我測試的幾部手機觀察來看未發生異常。npm
假設經過將單位故意大寫爲
PX
而避免轉換的話,是否是相對尾部寫/*no*/
來進行過濾更爲方便?segmentfault發現這個特徵的是在學習postcss的時候用到postcss-pxtorem插件,碰巧測試出來的。
固然我的倒的確傾向於寫
PX
,若是不存在兼容性問題。示例:
轉換前:.pic-txts { text-align: left; border:1px solid #ddd; /*px*/ border-radius: 5PX; width:690px; display: block; }轉換後:
.pic-txts { text-align: left; border-radius: 5PX; width: 9.2rem; display: block; } [data-dpr="1"] .pic-txts { border: 0.5px solid #ddd; } [data-dpr="2"] .pic-txts { border: 1px solid #ddd; } [data-dpr="3"] .pic-txts { border: 1.5px solid #ddd; }
minPixelValue: 6
比較方便,以及對於不想轉換的px處理的規則使用很是便捷!)快速開發自適應的移動端專題站點或簡單頁面
解決字體和邊框不進行rem轉換(根據考究並未找到合理有效的證據證實font-size建議使用px,我的認爲若是rem計算合理不該該存在明顯的重大問題。天然就不須要用到px2rem的dpr擴輾轉換功能了)
該分支採用postcss-pxtorem避免了postcss-nested註釋問題,具體配置大體以下
require('postcss-pxtorem')({ rootValue: 75, unitPrecision: 5, propList: ['*'], selectorBlackList: [], replace: true, mediaQuery: false, minPixelValue: 12 })
假設設計稿750寬,這裏設置簡單說明一下(沒說的是我還沒弄明白或者是不重要的?):
['*']
所有,假設須要僅對邊框進行設置,能夠寫['*', '!border*']
意思是排除帶有border的屬性,固然這裏會有一個問題,也許有時候不想對border其餘樣式處理例如border-radius
因此也不是很好。['fs']
,那例如fs-xl
類名,裏面有關px的樣式將不被轉換,這裏也支持正則寫法。須要注意的是,如下狀況並不會保留爲px!
.test-radius { width:20px; height:20px; border-radius: calc(@width / 2); background-color:#ccc; }根據反覆測試,calc運算是來自cssnano插件,然而cssnano有必要放在最後執行,因此沒法知足計算後的10px在進行pxtorem轉換,不過這種狀況也是比較合理的。假設width和height轉換爲rem,而圓角是px,我的感受不可避免的會形成圓形錯誤的狀況(是否有可能改圓角px值實際上永遠大於轉換後的rem的50%?有待考究!),因此這種狀況暫時就不考慮了,讓其單位均保持一致便可。
寫到這裏我又陷入了沉思,由於有個問題不明白了。根據postcss.config.js配置cssnano是在最後面,pxtorem是在其前面,那麼如何作到對此段樣式轉換的順序。
這段代碼應該先是postcss-property-lookup對@width進行處理,而後進行calc(@width / 2)計算,最後對px檢測轉換,再進行cssnano壓縮。而實際上有點詭異。難道postcss.config.js中插件的執行順序並不是單純的從上而下!但願不久的未來這個疑問將被解決,或者我也懷疑postcss官方文檔實際有指出,只是我的英文能力較差被我忽略掉了?。
另外一方面,關於此段CSS在畫圓上有一些須要注意的,其實這裏若是寫圓用50%便可,我發現某些狀況下(多是圓形很小)若是按照除以2的寫法轉換成rem彷佛不圓,因此在現代開發來看移動端畫圓就50%了!因此上例僅作測試好了~
額外閱讀,關於border-radius的一些事項。
對了忘了說了,css樣式代碼中將px寫成Px
或者PX
他也不會轉換成rem的~
在PostCSS的配置文件中,我加入了這個插件並放在了postcss-pxtorem的後面引入,這樣在第一次轉換後,postcss-adaptive的默認參數就不會影響到上一個插件的配置而形成的混亂狀況。實際上前面也提到過,這個插件的大部分功能和postcss-pxtorem類似,區別在於對於轉換規則的條件過濾,而postcss-pxtorem這點有極大的優點,使用這個插件主要是解決retina屏(iPhone4以上?)須要對1px邊框處理爲0.5px。具體測試能夠看一下DEMO中的pic-txts結構,如下是該結構部分說明:
這是一個pic-txts結構的wrap,展現小圓角邊框在兩個rem > px 轉換插件的做用下的影響由於在postcss-pxtorem配置中的minPixelValue設置爲6,當圓角爲5px時,他不進行轉換,而postcss-adaptive卻要對px屬性進行操做,這是咱們不但願的,合理的操做有兩種:
- 將圓角值按照設計稿(假設設計稿時10px)設定,並從新調整postcss-pxtorem配置中的minPixelValue爲兩倍安全值,例如12
- 將圓角5px值改爲postcss-pxtorem不處理的規則例如5PX,經過實驗,發現postcss-adaptive並不會處理該屬性
固然若是項目容易改造的話,仍是建議使用方案二,在適配上面已經作得很是完善了,方案二中1px的問題經過類名提升CSS優先級很是方便,也不須要更復雜的操做。PostCSS在這兩年來依舊是發展趨勢,在新的項目中能夠大膽嘗試。
方案三:
其實關於1px適配的問題,我想到了一個特別的方法,那就是在媒體查詢中,聲明一個變量例如:
$borderWidth: 1px; @media (max-resolution: 2dppx) { $borderWidth: 0.5px; }我但願css變量能在符合該媒體查詢規則的狀況下覆蓋以前聲明的變量,然而這種操做是沒法實現的!!!
固然,我後來只有這樣寫:
.test { border:1px solid #ccc; @media (max-resolution: 2dppx) { border-width:0.5px; } }但是你知道這樣寫有多麼麻煩嗎,大型項目中大量的代碼須要批量處理的時候,這是不可能實現的,雖然我當時的確在項目裏手動替換了超過50個地方。。。而後過了幾天思考,又所有還原了採用了方案一(由於項目不方便轉換爲方案二)。
所以,方案三隻是留給你們思考一下,也就沒有什麼實際的使用價值了。