前言
CSSNEXT: 可以理解為 CSS 4,雖然不一定所有特性都成為正式標準;
藉助相關的外掛我們可以把新的特性降級到 css3乃至一些特性降級到css2.1…無縫過渡
但裡面的一些特性,折騰了下發現基本可以滿足開發了(代替CSS前處理器SASS,LESS);
因為大多數人用前處理器最多的幾個特性無非如下: 繼承,巢狀寫法, 全域性變數,計算顏色
當然,這不是說sass/less 不夠好,相反它們可以做更多複雜的工作,邏輯運算和條件判斷這些;
若你只是用到一些常規特性,那就可以放心大膽的用了;
藉助webpack 開發的小夥伴基本可以搞起;其他構建工具也可以的,比如gulp
,
webpack 相關的依賴
- postcss-loader : postcss 處理器
- postcss-next : 用來解析 next=>css3寫法的外掛,可以理解類似 ES6(ESNEXT)轉 ES5
若是用 Vue
且用vue-cli
初始化的腳手架,只要在 style
的 lang
屬性指明為postcss
即可
若是自己搭建腳手架的..大體的配置也這麼些
常規解析 : style-loader < css-loader < postcss-loader < sass/less loader;
常規配置
vue-cli
初始化的webpack
那個模板的已經內建了.(vue init webpack xxx_project
)
// css next
// 指定為 postcss 就可以走 postcss 了..自己裝個 `postcss-next`
// 在根目錄的 .postcssrc.js 配置一下就行了
<style lang="postcss" scoped>
</style>
複製程式碼
// .postcssrc.js
// postcss-cssnext 外掛內建了 autoprefixer , 可以在內部配置你需要相容的範圍
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
plugins: {
`postcss-cssnext`: {},
}
};
複製程式碼
webpack
配置的
老版的 webpack 2 之前都是自右向左執行載入器的…可以分離配置項也可以直接追加配置引數
這裡說下比較新的 webpack
配置,就是載入器寫法改了下..基本還是差不多
postcss
的options
可以寫到註釋那一塊,但我更推薦註釋那一塊,會預設找根目錄的postcss.config.js
這個檔案作為配置路徑
{
test: /.(css|scss)$/,
use: [
require.resolve(`style-loader`),
{
loader: require.resolve(`css-loader`),
options: {
importLoaders: 1
},
},
{
loader: require.resolve(`postcss-loader`)
// options: {
// // Necessary for external CSS imports to work
// // https://github.com/facebookincubator/create-react-app/issues/2677
// ident: `postcss`,
// plugins: () => [
// require(`postcss-flexbugs-fixes`),
// autoprefixer({
// browsers: [
// `>1%`,
// `last 4 versions`,
// `Firefox ESR`,
// `not ie < 9`, // React doesn`t support IE8 anyway
// ],
// flexbox: `no-2009`,
// }),
// },
},
{
loader: require.resolve(`sass-loader`)
}
],
},
複製程式碼
我裝了挺多的外掛,有興趣的可以自行吧對應的外掛谷歌一下就知道大體用處了
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
plugins: {
`postcss-import`: {}, // 樣式檔案的匯入處理
`postcss-url`: {},
`postcss-cssnext`: { // 下一代的 CSS 轉換外掛
browsers: [ // 相容,不指定預設則是該外掛預設範圍,最近兩個版本
`>1%`,
`last 4 versions`,
`Firefox ESR`,
`not ie < 9`,
],
flexbox: `no-2009`,
},
cssnano: { // 壓縮
preset: `advanced`,
autoprefixer: false,
`postcss-zindex`: false
},
`postcss-pxtorem`:{ // pxtorem
`rootValue`: 75,
`unitPrecision`: 7,
"propList": ["*"],
`selectorBlackList`: [`ignore`,`html-topbar`],
`replace`: true,
`mediaQuery`: false,
`minPixelValue`: 0
},
}
};
// vh vw 真心不是最完美的方案.我之前用了大漠那套,
// 發現我們突然要把手機端相容 PC 的時候.我發現很無解,
// vh vw 是相對視窗而不是父類的...
// 所以退而求次..rem 的可控性比較強,可以同時考慮 PC 和移動端的轉換
複製程式碼
扯完這個,我們來扯點實際的
語法比較(實現同樣效果)
- 巢狀寫法?
// & 都代表父類自身
// scss
a {
color:#333;
.test{
color:#f00;
}
&:hover{
color:#ccc;
}
&+div{
float:left;
}
}
// css-next
// cssnext 的巢狀是空格子集,不像 scss 那樣直接就行哦
a{
color:#333;
& .test{
color:#f00;
}
&:hover{
color:#ccc;
}
&+div{
float:left;
}
}
// css
a {
color: #333;
}
a .test {
color: #f00;
}
a:hover {
color: #ccc;
}
a + div {
float: left;
}
複製程式碼
- 全域性變數?
// scss
$red:#f00;
$grey:#ccc;
a{
color:$red;
background-color:$grey;
}
// cssnext
// 在:root定義變數,可以理解為全域性變數
// 變數用 var 函式讀取
:root{
--red:#f00;
--grey:#ccc;
}
a{
color:var(--red);
background-color:var(--grey);
}
// css
a{
color:#f00;
background-color:#ccc;
}
複製程式碼
- 實現類似 sass/less 的 mixin?
// scss 可以使用預設變數,還可以定義 function, extends
// css next 沒有這些, 所以下面比較的是常規寫法
//scss
@mixin flex-basic(){
display:flex;
flex-wrap:no-wrap;
}
@mixin flex-horizontal-btw{
@include flex-basic;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.page{
position: absolute;
@include flex-horizontal-btw;
}
//cssnext
// 定義和全域性變數差不多.就是一個 js 物件的寫法
// 應用需要用到類似裝飾器的 @apply
:root {
--flex-basic: {
display: flex;
flex-wrap: no-wrap;
}
--flex-horizontal-btw: {
@apply --flex-basic;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
}
.page {
position: absolute;
@apply --flex-horizontal-btw;
}
// css
.page {
position: absolute;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: no-wrap;
flex-wrap: no-wrap;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
複製程式碼
- 常規的數值計算
// scss 的計算賊強大,cssnext 比不得,但是最基礎的用法還是可以的
// scss
$big-font-size:24px;
html{
font-size: $big-font-size / 3;
}
// cssnext
// 不能像 scss 直接編譯出8px,而是依賴 calc 函式計算的,結果一致
:root{
--big-font-size:24px;
}
html{
font-size: calc(var(--big-font-size) / 3); // font-size: calc(24px / 3);
}
// css
html {
font-size: 8px;
}
複製程式碼
- 顏色計算,一般定製主題或者 UI 規範的會考慮..
同理,scss 可以完全模擬出 cssnext 的幾個顏色函式的實現,
反過來 cssnext是內建直接可以用的(有好幾個計算不同型別的顏色的函式),但是又不能處理太複雜的計算
比如根據條件判斷這些,傳入不同的變數再去運算
說說其他的
cssnext有一些內建的特性也很好用,雖然不如 sass 這些發展多年的強大
這裡的列出的一些特性,熟練用前處理器基本可以模擬出來…就不寫比較例子了
- 聚合選擇器到一個變數
//cssnext
// @custom-selector 裝飾器名稱固定的, 後面是 空格 + 關聯設定
// @custom-selector + 樣式匹配器(:--name) + 應用的元素或者選擇器
@custom-selector :--color a , span , img , .test;
:--color {
color:#333;
&::before{
content:`$`;
}
}
//css
a,
span,
img,
.test {
color:#333
}
a::before,
span::before,
img::before,
.test::before{
content:`$`;
}
複製程式碼
:matches
偽類,這個也可以簡化我們 css 的寫法
// cssnext
div::before{
content:`!!`;
}
div:matches(::before, .items) {
color: red;
& a{
font-size:10px;
}
}
// css
div::before{
content:`!!`;
}
div::before, div.items {
color: red
}
div::before a, div.items a{
font-size:10px;
}
複製程式碼
- 對圖片設定多倍圖的簡化寫法,直接拿官方的例子,有這需求的小夥伴又可以少寫一些程式碼了
//cssnext
.foo {
background-image: image-set(url(img/test.png) 1x,
url(img/test-2x.png) 2x,
url(my-img-print.png) 600dpi);
}
//css
.foo {
background-image: url(img/test.png);
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {.foo {
background-image: url(img/test-2x.png);
}
}
@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) {.foo {
background-image: url(my-img-print.png);
}
}
複製程式碼
還有一些特性我感覺並不常用,
比如雙冒號(pseudo),資料的截斷overflow-wrap
, 字型的initial
;
只能說你要規範化寫,也可以用這些特性,畢竟不管什麼什麼規範,
越發展越完善,越完善越細化和嚴謹
總結
最近在折騰 react 16.3,發現更多人的是偏向於寫 css乃至用 styled-component
,
但是自己又想用scss 的部分特性,於是就有了這篇文章
把手頭專案 vue-cli 初始化的專案.升級到了 webpack4.8.3 , 引入了一堆移動端相關東東..
本想抽離出來做一個腳手架,想想還是算了
webpack 4.8.3的不如期待那般美好..只能說有所提升..