摘要:本期主要介紹以下幾個(gè)插件和幾個(gè)坑和坑這個(gè)就不用多說(shuō)了,必裝插件之一??此茖懛](méi)有任何問(wèn)題。編譯后的結(jié)果那么這樣就沒(méi)有問(wèn)題了。
PostCSS常用插件介紹
繼上一次PostCSS學(xué)習(xí)指南(一)后,漸漸開始在項(xiàng)目中應(yīng)用。
這次決定主要講解一些個(gè)人認(rèn)為非常有幫助的PostCSS插件。
autoprefixer本期主要介紹以下幾個(gè)插件和幾個(gè)坑
autoprefixer
postcss-partial-import
postcss-advanced-variables
cssnano
postcss-px2rem
precss
postcss-nesting和postcss-nested
坑( ??? )?
這個(gè)就不用多說(shuō)了,必裝插件之一。方便的寫規(guī)范的css,它會(huì)為你提供非常完整的hack兼容方案的。當(dāng)然這里需要了解一下的是,它的大部分兼容數(shù)據(jù)來(lái)源Can I Use,另外一個(gè)稍微需要了解的插件配置參數(shù)就是browsers,比如這樣寫:
module.exports = { plugins: [ require("autoprefixer")({ browsers: "last 2 versions" }) ] }
關(guān)于這個(gè)參數(shù)的詳細(xì)介紹可以看看Browserslist Queries,文中說(shuō)了,強(qiáng)烈建議將查詢寫入package.json(后面會(huì)告訴你為何要寫在這里),而非配置postcss.config.js中autoprefixer的browsers參數(shù)。所以此處建議寫法如下:
postcss.config.js
module.exports = { plugins: [ require("autoprefixer"); ] }
package.json內(nèi)增加如下示例
"browserslist": [ "> 1%", "last 2 versions" ]
這里我對(duì)著官方文檔簡(jiǎn)單說(shuō)一下數(shù)組內(nèi)的值對(duì)應(yīng)的含義:
last 2 versions: 每個(gè)瀏覽器中最新的兩個(gè)版本。
> 5% or >= 5%: 全球?yàn)g覽器使用率大于5%或大于等于5%(上例中則是1%)。
其他的一些參數(shù)簡(jiǎn)單介紹:
ie 6-8: 選擇包含ie6-8的版本。
Firefox > 20: 火狐版本號(hào)大于20。
還有很多不一一列舉,這里的配置還是很詳細(xì)的,一般來(lái)說(shuō)最省事的就是不加參數(shù),按照默認(rèn)即可。
需要配置的話,就在package.json里面添加browserslist參數(shù),這樣其他插件也能夠從中獲取到項(xiàng)目將要兼容的版本,目前包含以下幾個(gè)插件會(huì)讀取改配置:
Autoprefixer
babel-preset-env (no config support, only tool option)
eslint-plugin-compat
stylelint-no-unsupported-browser-features
postcss-normalize
關(guān)于autoprefixer的介紹差不多就這些了~
postcss-partial-import這個(gè)沒(méi)啥好說(shuō)的,也是很容易理解的插件,就是讓你的css文件支持@import,支持W3C的寫法也支持SASS那種寫法,這里就不多說(shuō)啦。
postcss-advanced-variables同樣的,像SASS那樣可以自定義變量并進(jìn)行引用,用法也十分簡(jiǎn)單,相信大家一定不用點(diǎn)開官方文檔也會(huì)用的~(你肯定還是點(diǎn)開了哈哈哈~你這叫胡開鏈接綜合癥,生怕錯(cuò)過(guò)了啥內(nèi)容。)
cssnano很顯然這個(gè)插件作者比較高調(diào),github的cssnano上面是沒(méi)有什么說(shuō)明和介紹的,當(dāng)然官方也寫得很詳細(xì)了。這個(gè)插件給我的感覺(jué)就是css代碼壓縮工具(實(shí)際上它集成了很多強(qiáng)化的功能,表面上看起來(lái)是壓縮實(shí)際上進(jìn)行了相當(dāng)多處理,可以看看這個(gè)表格Optimisations),他的配置建議采用默認(rèn)配置,除非你知道你在做什么。
當(dāng)然我在測(cè)試使用中遇到了一點(diǎn)點(diǎn)問(wèn)題,關(guān)于cssnano和autoprefixer結(jié)合使用,或者說(shuō)是postcss.config.js插件引入順序有關(guān)的造成輸出不同的問(wèn)題?我暫時(shí)還在研究,先看代碼:
testcssnano.css
.test { -moz-border-radius: 10px; border-radius: 10px; display: flex; }
postcss.config.js(第一種)
module.exports = { plugins: [ require("cssnano")({ preset: "default", }), require("autoprefixer") ] }
輸出結(jié)果:
.test{border-radius:10px;display:flex}
postcss.config.js(第二種)
module.exports = { plugins: [ require("autoprefixer"), require("cssnano")({ preset: "default", }) ] }
輸出結(jié)果:
.test{border-radius:10px;display:-webkit-box;display:-ms-flexbox;display:flex}
問(wèn)題一,如果手寫-moz-,cssnano會(huì)清除,可見(jiàn)示例,當(dāng)然或許這個(gè)屬性在火狐已經(jīng)支持不需前綴所以,就被去掉了。
問(wèn)題二,如果在配置文件中,cssnano在autoprefixer之前引用,假設(shè)根據(jù)webpack的loader執(zhí)行順序規(guī)則相同的話,大概postcss.config.js中的插件也是這樣由下而上依次執(zhí)行,因此,在第一種例子中,css代碼先被autoprefixer處理,然后再執(zhí)行cssnano清除了那些多余的前綴代碼?大致可分解為:
第一步autoprefixer處理結(jié)果:
.test { -moz-border-radius: 10px; border-radius: 10px; display: flex; display: -webkit-box; display: -ms-flexbox; }
第二步cssnano處理結(jié)果:
.test{border-radius:10px;display:flex}
可是我要遺憾的告訴大家。。。這個(gè)可能是錯(cuò)誤的結(jié)論?。?!
因?yàn)槲覍⒌谝徊降慕Y(jié)果作為初始css,將postcss.config.js中僅引用一個(gè)cssnano插件來(lái)執(zhí)行的結(jié)果如下:
.test{border-radius:10px;display:flex;display:-webkit-box;display:-ms-flexbox}
因此,這個(gè)問(wèn)題就來(lái)了。。。cssnano確實(shí)將-moz-去掉,但是他并沒(méi)有處理其他的關(guān)于display的兼容代碼。
于是我再做了一個(gè)測(cè)試:
我將css代碼改為:
.test { -webkit-transform: scale(.5) translate(10, 20); -moz-transform: scale(.5) translate(10, 20); -ms-transform: scale(.5) translate(10, 20); -o-transform: scale(.5) translate(10, 20); transform: scale(.5) translate(10, 20); }
而postcss.config.js還是同時(shí)引入cssnano和autoprefixer,經(jīng)過(guò)測(cè)試,無(wú)論誰(shuí)先誰(shuí)后輸出結(jié)果均為:
.test{-webkit-transform:scale(.5) translate(10,20);transform:scale(.5) translate(10,20)}
如果css代碼改為:
.test { transform: scale(.5) translate(10, 20); }
postcss.config.js同時(shí)引入cssnano和autoprefixer,
第一種cssnano在前結(jié)果:
.test{transform:scale(.5) translate(10,20)}
第二種autoprefixer在前結(jié)果:
.test{-webkit-transform:scale(.5) translate(10,20);transform:scale(.5) translate(10,20)}
結(jié)果又不一樣,不知道看到這里大家暈了沒(méi)有。
根據(jù)觀察,postcss.config.js的插件執(zhí)行順序是有要求的,至少在同時(shí)使用cssnano和autoprefixer的時(shí)候,cssnano一定要在autoprefixer之后,否則autoprefixer可能會(huì)失效!
另外cssnano和autoprefixer都會(huì)對(duì)很舊的兼容寫法進(jìn)行精簡(jiǎn),例如上文有一段有很多個(gè)transform屬性的css代碼,autoprefixer會(huì)(根據(jù)browserslist)剔除其他的。
至于順序問(wèn)題,我后面繼續(xù)進(jìn)行研究!
postcss-px2rem做移動(dòng)端,適配是個(gè)頭疼的問(wèn)題,不過(guò)我目前還是使用想對(duì)穩(wěn)定的方案flexible,那么就需要用rem來(lái)做主要的單位,這里不說(shuō)適配問(wèn)題只說(shuō)這個(gè)插件,一般移動(dòng)端,設(shè)計(jì)師給的設(shè)計(jì)稿都是750px寬,你只需要下面這樣設(shè)置,就可以直接在代碼里面寫你在PSD量的像素值了,這真是太令人激動(dòng)了!
require("postcss-px2rem")({ remUnit: 75, threeVersion: true })
因?yàn)檫@個(gè)postcss-px2rem又是來(lái)源于px2rem的,所以詳細(xì)的說(shuō)明見(jiàn)px2rem,我這里寫了兩個(gè)參數(shù),一個(gè)remUnit,這個(gè)對(duì)應(yīng)的是每rem對(duì)應(yīng)的px值,既然750px,就寫75啦,不知道這樣理解對(duì)不對(duì)。另一個(gè)threeVersion則對(duì)應(yīng)三個(gè)不同dpr下的大小,這個(gè)比較少用,需要注意的是處理這些參數(shù),是否轉(zhuǎn)換rem都和注釋有關(guān),這里就不細(xì)說(shuō)了,看看文檔就好~當(dāng)然這里也埋下一個(gè)坑,等下會(huì)提到。
precss這就是個(gè)大雜燴,主要是為了滿足SASS開發(fā)者的習(xí)慣,繼承了很多插件,本篇前后文都有提及precss內(nèi)的部分插件,如果并不是全部用到,我建議還是一個(gè)個(gè)手動(dòng)安裝所需插件來(lái)進(jìn)行配置,這東西,配好了以后也就不會(huì)經(jīng)常改動(dòng)了,而且個(gè)人認(rèn)為用大雜燴很容易出現(xiàn)一些坑,又很難排查,例如下面兩個(gè)插件,大家仔細(xì)看看。
另外還有幾個(gè)插件,建議安裝(當(dāng)然如果你完全不知道干啥的可以忽略):
postcss-mixins 一個(gè)和SASS的mixins用法相同的插件
postcss-atroot 讓你的嵌套css處于根部,官方有個(gè)bar.css的@import的例子很棒,可以看看舉一反三
postcss-extend 有相同結(jié)構(gòu)卻有那么一點(diǎn)點(diǎn)不同的區(qū)別,用這個(gè)可以方便的統(tǒng)一管理相同部分樣式代碼
其他的一些我個(gè)人覺(jué)得不常用或者說(shuō)實(shí)用意義不大所以就沒(méi)有寫出來(lái)了。
postcss-nesting和postcss-nested這兩個(gè)也是從precss里面拿出來(lái)的,就是仿SASS的嵌套css寫法用。為啥把這兩個(gè)放一起寫,因?yàn)樗麄冮L(zhǎng)的太像了。只看名字鬼知道他們的區(qū)別,然而他們都被加入到precss里面去了。據(jù)precss介紹,他們兩個(gè)的區(qū)別是:
postcss-nesting: W3C nested selectors
postcss-nested: Sass-like nested selectors
光看這兩行我是看不懂到底是個(gè)啥玩意,難道第一個(gè)是符合W3C規(guī)范的嵌套選擇?粗略看了下兩個(gè)插件的說(shuō)明文檔,沒(méi)看出沒(méi)啥區(qū)別。行,那手動(dòng)寫代碼來(lái)一個(gè)個(gè)試試。先安裝postcss-nesting,編譯試試,嘩嚓一片紅。。。咋回事,我們先看看代碼片段。
.catis-list { padding: 0 50px; overflow: hidden; li { list-style: none; float: left; margin-top: 38px; width: 113px; &:not(:nth-child(4n)) { margin-right: 66px; } .iconfont { font-size: 100px; line-height: 100px; color: #506071; display: block; text-align: center; } .cati-name { font-size: 28px; line-height: 40px; display: block; color: #999; text-align: center; } } }
看似SASS寫法沒(méi)有任何問(wèn)題??墒撬崾镜膱?bào)錯(cuò)信息讓人看不大懂
ERROR in ./src/style/index.css Module build failed: ModuleBuildError: Module build failed: Error: undefined:783:6: property missing ":" at error (D:webProjectsmobileweb ode_modulescsslibparseindex.js:62:15) at declaration (D:webProjectsmobileweb ode_modulescsslibparseindex.js:223:33) at declarations (D:webProjectsmobileweb ode_modulescsslibparseindex.js:252:19)
啥玩意missing了個(gè)冒號(hào)嘛。。。改來(lái)改去都不對(duì)。索性拿來(lái)官方的實(shí)例。才看清楚。原來(lái)每個(gè)嵌套的樣式前面都需要一個(gè)&(注意符號(hào)后面有個(gè)空格),實(shí)際上應(yīng)該如下才對(duì):
.catis-list { padding: 0 50px; overflow: hidden; & li { list-style: none; float: left; margin-top: 38px; width: 113px; &:not(:nth-child(4n)) { margin-right: 66px; } & .iconfont { font-size: 100px; line-height: 100px; color: #506071; display: block; text-align: center; } & .cati-name { font-size: 28px; line-height: 40px; display: block; color: #999; text-align: center; } } }
這里面有一段用到偽類其中&符號(hào)后面是沒(méi)有空格的,是正確的。編譯后的結(jié)果:
.catis-list { padding: 0 0.666667rem; overflow: hidden; } .catis-list li { list-style: none; float: left; margin-top: 0.506667rem; width: 1.506667rem; } .catis-list li:not(:nth-child(4n)) { margin-right: 0.88rem; } .catis-list li .iconfont { font-size: 1.333333rem; line-height: 1.333333rem; color: #506071; display: block; text-align: center; } .catis-list li .cati-name { font-size: 0.373333rem; line-height: 0.533333rem; display: block; color: #999; text-align: center; }
那么這樣就沒(méi)有問(wèn)題了。和官方的說(shuō)明的是一樣的,但是另一方面,如果每次都要寫&加空格,那豈不是很麻煩,習(xí)慣寫SASS的兄弟們肯定不愿意這樣做啦。
那么我要說(shuō)的就是另一個(gè)插件postcss-nested,如precss所述,這個(gè)的確是SASS-LIKE了。當(dāng)然我暫時(shí)還不太明白為何precss要收入兩個(gè)nest插件(為了滿足不同開發(fā)人員的習(xí)慣?)。我們修改postcss.config.js使用postcss-nested,并重新修改樣式代碼之前第一段,再次編譯執(zhí)行,一切OK,那么結(jié)論就是,如果僅習(xí)慣于SASS的嵌套寫法,安裝postcss-nested插件即可~
坑( ??? )?最后來(lái)說(shuō)說(shuō)我遇到的坑,除了剛才說(shuō)的cssnano和autoprefixer同時(shí)使用需要注意順序問(wèn)題。還有另一個(gè)順序研究,就是確定好將要使用的插件后,在postcss.config.js中配置插件require順序還是有講究的,這里我個(gè)人觀察的確還是從上往下的(至于是不是每個(gè)插件輪流處理完文件后挨個(gè)執(zhí)行我尚不確定),比如說(shuō),postcss-partial-import這個(gè)理應(yīng)是第一個(gè)引入的,你若是把它放在最后面,而css代碼中第一行就用了@import那肯定會(huì)報(bào)錯(cuò)!所以,建議根據(jù)css代碼的寫法來(lái)決定你的執(zhí)行順序。
postcss-nested插件是大部分SASS開發(fā)者所喜愛(ài)的,但是你在css文件中用sass寫法會(huì)遇到以下幾個(gè)問(wèn)題:
csslint,css文件不支持嵌套,變量等寫法,如果你將文件模式改為sass,注釋的方式會(huì)變成//,而非/* comments */,當(dāng)然你可以手寫/* ... */這樣的注釋,但是用快捷鍵進(jìn)行注釋會(huì)很痛苦。
這里有個(gè)小技巧,讓項(xiàng)目所有css文件均為sass模式下編輯,在項(xiàng)目settings.json添加:
"files.associations": { "*.css": "scss" }
當(dāng)然你若是想要支持//注釋也是可以的,請(qǐng)?jiān)侔惭bpostcss-scss插件,我這里不多說(shuō)這個(gè)了,因?yàn)槲乙呀?jīng)決定手寫注釋了?
你手寫注釋沒(méi)有問(wèn)題,然而編譯出來(lái)的東西會(huì)出問(wèn)題,你樣式中最后一行如果將注釋寫在花括號(hào)內(nèi)部,它轉(zhuǎn)換出來(lái)的代碼,注釋會(huì)在外部,這是個(gè)大坑,因?yàn)樵谑褂胮ostcss-px2rem的時(shí)候,那注釋來(lái)控制是否轉(zhuǎn)換的功能就失效了。我文字描述可能讓人迷糊,所以看看代碼:
例如CSS部分代碼:
.test { color:#999; border:1px solid #ffffd; /* no */ .inner { color:#333; } }
轉(zhuǎn)換后:
.test { color:#999; border:0.13333rem solid #ffffd; } /* no */ .test .inner { color:#333; }
而不是我想要的:
.test { color:#999; border:1px solid #ffffd; } .test .inner { color:#333; }
理論上是應(yīng)該輸出我想要的結(jié)果,卻沒(méi)有輸出正確,錯(cuò)誤的將1px的border轉(zhuǎn)成rem,原因就是先執(zhí)行的postcss-nested將注釋弄在外部后,postcss-px2rem無(wú)法識(shí)別到它的規(guī)則了。
我一開始也是裝了precss后發(fā)現(xiàn)該問(wèn)題,后來(lái)查了很久才發(fā)現(xiàn)是這個(gè)插件的問(wèn)題。同時(shí)也發(fā)現(xiàn)了這個(gè)人其實(shí)已經(jīng)提過(guò)issue了Wrong location of comment of the last declaration in a nested rule definition只是沒(méi)人解決。
而我臨時(shí)處理的方法就是只好將要注釋的那段代碼不要寫在最后一行了。如下:
.test { border:1px solid #ffffd; /* no */ color:#999; .inner { color:#333; } }
可能有時(shí)候并不會(huì)有兩個(gè)樣式給border墊底,如果只有一行border的樣式,就只能這樣:
.test { .inner { color:#333; } border:1px solid #ffffd; /* no */ }
這樣倒是可以了,不過(guò)看起來(lái)很奇怪,所以如果你使用和我相同的處理方式時(shí),務(wù)必注意此點(diǎn)(寫完本文時(shí)我似乎發(fā)現(xiàn)了更好的解決方案,等確認(rèn)了沒(méi)有問(wèn)題后,放在下一期來(lái)寫~)。
(我記得好像還有坑的,硬是想了半天想不起來(lái)了。。。那就先這樣吧)
本期結(jié)語(yǔ)最后如果你還想探索更多好玩的好用的插件,你可以看看這里PostCSS Plugins List還有這個(gè)可以搜索的分類插件列表,如果你發(fā)現(xiàn)了更棒的插件,也歡迎留言喔~
另外上面的例子如果我沒(méi)有寫的很明白,或者你只是想直接拿來(lái)快速測(cè)試使用的話,可以看看這個(gè)mobileweb
(關(guān)于第三期PostCSS的內(nèi)容還在考慮。。??赡苁菍?duì)第二期的補(bǔ)充和填坑~敬請(qǐng)期待?)
其他關(guān)于我個(gè)人的PostCSS一系列學(xué)習(xí), 介紹及總結(jié), 有興趣可以參閱:
PostCSS自學(xué)筆記(一)【安裝使用篇】
PostCSS自學(xué)筆記(二)【插件篇】
PostCSS自學(xué)筆記(二)【番外篇一】
PostCSS自學(xué)筆記(二)【番外篇二】
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/112501.html
摘要:之前有研究過(guò)做過(guò)假設(shè),在插件列表中,的插件執(zhí)行順序自上而下,一切看起來(lái)似乎是沒(méi)有任何問(wèn)題的。再有摘自深入設(shè)計(jì)摘自寫的姿勢(shì)這兩張圖則應(yīng)該是說(shuō)明了我之前的假設(shè),插件中的執(zhí)行順序自上而下。先來(lái)看看一片來(lái)自的這段會(huì)不會(huì)跟這個(gè)有關(guān)呢,我先埋個(gè)伏筆。 圖解PostCSS的插件執(zhí)行順序 文章其實(shí)是一系列的早就寫完了. 才發(fā)現(xiàn)忘了發(fā)在SegmentFault上面, 最早發(fā)布于https://gitee...
摘要:通過(guò)配置規(guī)則和單位使用或來(lái)解決。其他關(guān)于我個(gè)人的一系列學(xué)習(xí)介紹及總結(jié)有興趣可以參閱自學(xué)筆記一安裝使用篇自學(xué)筆記二插件篇自學(xué)筆記二番外篇一自學(xué)筆記二番外篇二 利用PostCSS解決移動(dòng)端REM適配問(wèn)題 上一期有提到結(jié)合postcss-px2rem插件來(lái)處理移動(dòng)端適配的方案,以及相關(guān)的避坑方法,之后總覺(jué)得這個(gè)解決方案問(wèn)題太多,也就誕生了另一套方案運(yùn)用postcss-pxtorem插件來(lái)進(jìn)行...
摘要:而則可制定個(gè)人需求的一套解決方案僅安裝需要的插件。迫不及待的你已經(jīng)等不及安裝使用了吧。安裝及使用一般是結(jié)合自動(dòng)化工具使用,如果要單獨(dú)使用可以安裝,這里我先對(duì)的安裝使用講解下。接下來(lái)說(shuō)點(diǎn)實(shí)際的,如何利用結(jié)合自動(dòng)化工作在項(xiàng)目中使用。 PostCSS介紹 PostCSS是一個(gè)利用JS插件來(lái)對(duì)CSS進(jìn)行轉(zhuǎn)換的工具,這些插件非常強(qiáng)大,強(qiáng)大到無(wú)所不能。其中,Autoprefixer就是眾多Post...
摘要:從再到目前當(dāng)紅明星,前端模塊打包技術(shù)日新月異,在今年月份和月份左右接連更新了和版本為了減少冗余模塊,縮減文件大小,中也加入了關(guān)于的特征,可以查看知乎如何評(píng)價(jià)新引入的代碼優(yōu)化技術(shù)的討論。 從Grunt->gulp->webpack,再到目前當(dāng)紅明星rollup,前端模塊打包技術(shù)日新月異,webpack在今年1月份和6月份左右接連更新了v2和v3版本,為了減少冗余模塊,縮減bundle文件...
摘要:?jiǎn)卧獪y(cè)試秉承測(cè)試驅(qū)動(dòng)開發(fā)的開發(fā)理念,單元測(cè)試的任務(wù)是必不可少的。維護(hù)一份按照建議,也將更新歷史等數(shù)據(jù)放在了一個(gè)名為文件上,并采用語(yǔ)義化的版本號(hào)。 本文原始來(lái)源:http://devework.com/postcss-p...。轉(zhuǎn)載請(qǐng)?zhí)峁┰紒?lái)源,謝謝! showImg(https://segmentfault.com/img/bVHtqu?w=2028&h=612); 前陣子為了滿足工...
閱讀 489·2019-08-30 15:44
閱讀 903·2019-08-30 10:55
閱讀 2737·2019-08-29 15:16
閱讀 942·2019-08-29 13:17
閱讀 2810·2019-08-26 13:27
閱讀 578·2019-08-26 11:53
閱讀 2125·2019-08-23 18:31
閱讀 1893·2019-08-23 18:23