cssnext下一代的css

陳小壞發表於2019-05-24

前端技術更新迭代的速度令人咂舌,網際網路+的風頭剛起那幾年,前端技術大多還停留在jquery階段,按需載入還停留在seajs和requirejs的階段,css3和H5也不過才嶄露頭角,但經過幾年的飛速發展,Angular、Vue和React儼然已形成前端框架的三足鼎立之勢,且風頭正勁,各領風騷!

看慣了css、sass、less的容顏,驚豔於css3的神奇,嚮往著下一代css的傳奇。今天就簡單玩玩下一代的css傳奇cssnext(據說阿里早幾年前就開始玩cssnext了)。

先上幾個cssnext的語法:

:root{
  --mainColor: blue;
  --fontSize12:12px;
  --toolbar:{
    margin:10px 0 20px 10px;
    padding:0
  };
  --heading-color: #ff0000;
}

a{
  color: var(--mainColor);
  font-size: calc(var(--fontSize12) * 3);

  &:hover {
    color: rebeccapurple;
  }
}
.bianJu{@apply --toolbar;}

@custom-media --viewport-medium (width <= 1200px);
@custom-selector :--heading h1, h2, h3, h4, h5, h6;

:--heading {
  margin-block: 0;
  color: var(--heading-color);
}

@media (--viewport-medium) {
  body {
    color: var(--mainColor);
    font-size: var(--fontSize12);
    line-height: calc(var(--fontSize12) * 1.5);
    overflow-wrap: break-word;
    padding-inline: calc(var(--fontSize12) / 2 + 1px);
  }
  a{color: var(--heading-color);}
  a, :--heading, .bianJu{font-size: calc(var(--fontSize12) * 2);}
}

.hero:matches(main, .main) {
  background-image: image-set("../assets/images/pic.jpg" 1x, "../assets/images/pic.jpg" 2x);
}

驚不驚喜?意不意外?是不是有點像less?是不是有點像js?確實很好玩的!
這些只是cssnext的冰山一角,目前國內使用這個的還不多,我也只是好奇,就自己玩了一把,茲當是做個筆記。
目前各瀏覽器對cssnext的支援度還不夠,版本較新的谷歌瀏覽器也只是支援了一丟丟的cssnext語法,像

:root{
  --mainColor: blue;
  --fontSize12:12px;
  --bianJu:{
    margin:10px 0 20px 10px;
    padding:0
  };
  --heading-color: #ff0000;
}

a{
  color: var(--mainColor);
  font-size: calc(var(--fontSize12) * 3);

  &:hover {
    color: rebeccapurple;
  }
}

等等這種的語法,較新的谷歌瀏覽器還是支援的,但比如@apply自定義屬性集、@custom-media自定義媒體查詢、@custom-selector自定義選擇器還是不支援的,所以就要藉助一些webpack的postcss外掛來實現了。

接下來就配置幾個webpack的外掛來實現諸如@apply、@custom-media、@custom-selector的css解析轉換:

const postcssPresetEnv = require('postcss-preset-env');
const postcssCustomProperties = require('postcss-custom-properties');    //轉換自定義屬性 如:@custom-media @custom-selector
const postcssApply = require('postcss-apply');  //轉換自定義屬性集  @apply

module.exports = {
    module: {
            {
                test    : /\.(sa|sc|c)ss$/,
                use     : [
                    'style-loader',
                    'css-loader',
                    { loader: 'postcss-loader',
                        options: {
                            ident: 'postcss',
                            plugins: () => [
                                postcssApply(),
                                postcssCustomProperties({
                                    preserve: false,
                                }),
                                postcssPresetEnv({
                                    stage: 0,
                                    browsers: 'last 5 versions',
                                }),                      
                            ]
                        }
                    },
                    'sass-loader',
                ],             
            },
        ],
    },
}

需要說明的是:
1、cssnext也可以使用postcss-cssnext這個包來解析,postcss-cssnext這個包可以解析諸如--mainColor這種的語法,也可以解析諸如@apply這種自定義的屬性集,但不能解析諸如@custom-media這種自定義的媒體查詢,而且目前postcss-cssnext已經不再維護,安裝時會提示使用postcss-preset-env來代替。
cssnext下一代的css
2、如果使用postcss-preset-env這個包來解析cssnext,但遇到諸如@custom-media和@apply這種語法,就要使用到額外的安裝包postcss-custom-properties和postcss-apply。
3、如果使用了@apply這種自定義屬性,那麼它不支援讀取從外部引入的事先定義好的屬性集,這個有點不太好理解,還是上程式碼吧。
比如你使用瞭如下自定義的屬性集程式碼:

:root{
  --toolbar:{
    margin:10px 0 20px 10px;
    padding:0
  };
}
.toolbar{@apply --toolbar;}

那麼這麼寫是沒有問題的,但是有時我們為了能複用公共的css就會把公共的css放在一個單獨的css檔案中,每個css樣式表用到這個公共的css檔案時,會通過@import將其引入進來,這本來也是沒有問題的,是通用的做法,只是用在這裡,如果將--toolbar:{margin:10px 0 20px 10px; padding:0};放在一個公共的css檔案中再@import進來,@apply就不識別--toolbar這個變數了。

本篇部落格也只是觸及到了cssnext的冰山一角,就需要用到三個包來編譯解析,且配置webpack時也出現了各種問題,查閱英文的文件和官方給出的答疑解惑(本人英語很差勁,配合著某詞典才勉強看下來,目前國內這方面的中文文件極少),相當費時費力,且瀏覽器的支援度並不友好。其中的postcss-apply的官方給出的提示就很明顯:

The @apply rule and custom property sets most likely won't get any more support from browser vendors as the spec is yet considered deprecated and alternative solutions are being discussed.
大意就是@apply規則和自定義屬性集很可能不會再獲得瀏覽器供應商的支援,因為該規範已棄用且正在討論替代解決方案。

目前還在繼續學習cssnext中!

本文參考:
postcss-preset-env
postcss-custom-properties
postcss-apply

相關文章