postcss 插件開發:批量自動化移動端1px解決方案

前言

移動端web項目愈來愈多,設計師對於UI的要求也愈來愈高,好比1px 的邊框。在高清屏下,移動端的1px 會很粗。現現在已經有許多優秀的1px解決方案css

這裏總結幾種較好用的解決方案html

  1. 僞元素

優勢: 由於僞元素::after或::before是獨立於當前元素,能夠單獨對其縮放而不影響元素自己的縮放前端

僞元素大多數瀏覽器默認單引號也可使用,
和僞類同樣形式,並且單引號兼容性(ie)更好些
複製代碼

缺點:須要額外編寫僞元素樣式。對於我這種懶癌往期用戶來講,真的頭疼;vue

  1. less封裝

優勢:使用 less 對公共代碼(方案一)封裝,同時增長媒體查詢分別對不一樣 DPR 的設備,進行不一樣的縮放node

缺點:須要調用封裝好的less函數。對於不懂less的同窗們來講,可能須要額外去學習下less,若是項目沒使用預處理(less,sass,stylus),還須要額外引入。react

那麼,有沒有辦法我既不額外引入第三方預處理器,也無需額外寫一堆僞元素樣式? ok,既然你看到這裏了,那麼就繼續加油,立刻帶你瞭解一下基於postcss的解決方案。git

目錄

  1. 什麼是postcss?
  2. 如何在項目中使用postcss和postcss相關插件?
  3. postcss插件開發流程和規範
  4. postcss-border-1px開發、npm包和github

若是你只是想直接使用該插件或者想看代碼,你能夠直接跳到4。github

什麼是postcss?

多時候第一次在網上查詢 PostCSS 概念的時候,你們都解釋成一個後處理器的概念,其實我的以爲這些概念不重要,更爲重要的有如下幾點:web

它本質上是一個什麼東西vue-cli

PostCSS 能夠直觀的理解爲:它就是一個平臺、平臺、平臺,重要的事情來三遍比較爽,哈哈!

什麼說它是一個平臺呢?由於咱們直接用它,感受不能幹什麼事情,可是若是讓一些插件在它上面跑,那麼將會很強大。

PostCSS 提供了一個解析器,它可以將 CSS 解析成抽象語法樹(AST)。

也就是說,postcss只是幫咱們把css解析成一個ast,除此以外,它什麼都沒作。因此說,PostCSS 它須要一個插件系統纔可以發揮做用。咱們能夠經過「插件」來傳遞AST,而後再把AST轉換成一個串,最後再輸出到目標文件中去。固然,這裏是有API能夠用,這裏先不講,省得暈了。

關於poscss詳細的介紹,能夠看這裏。

如何在項目中使用postcss?和postcss相關插件

有如下幾個步驟

  1. 在loader中配置postcss

前面說過了,postcss會將css文件轉換成AST,因此咱們須要爲css文件配置postcss-loader,vue-cli3及以上版本都默認配置了postcss,因此你無需再配置。若是你是react版本,請自行google如何配置。

這裏有個注意的地方

若是你的項目配置的less sass之類的,須要將less-loader或者sass-loader配置在postcss下面。由於postcss只接受css,沒法編譯less和sass以及其餘語法。 這裏以less爲例子

{
  test: /\.css$|\.less$/,
  use:
  [
    'style-loader',
    'css-loader',
    'postcss-loader',
    'less-loader'
  ]
}
複製代碼
  1. 新增postcss.config.js文件
const border1px = require('postcss-botder-1px')
module.exports = {
plugin:[
  border1px({option}) // option是插件的參數
]
}
複製代碼

自此,就完成了插件的使用。在項目中,你能夠正常寫border

border:1px solid red;
複製代碼

postcss插件開發流程和規範

postcss開發規範
  1. 用postcss-前綴清除名稱。
  2. 一個插件只作一件事情,也就是單一職責。
  3. 經過 postcss.plugin 來建立你的插件
 module.exports = postcss.plugin('plugin-name', opts => {
  return (root, result) => {
    // Plugin code
  }
})
複製代碼
  1. 只使用postcss提供的公共的api來編寫 PostCSS插件不得依賴未記錄的屬性或方法,postcss提供可不少很是好用的 api

想要了解更多的插件開發規範,點這裏。

postcss開發流程
1. 瞭解postcss解析的ast。

例子:

要解析的css代碼:

.demo{
  border:1px solid red;
}
複製代碼

解析後的ast:

{
  "raws": {
    "semicolon": false,
    "after": ""
  },
  "type": "root",
  "nodes": [
    {
      "raws": {
        "before": "",
        "left": "",
        "right": "\n "
      },
      "type": "comment",
      "source": {
        "start": {
          "line": 1,
          "column": 1
        },
        "input": {
          "css": "/**\n * Paste or drop some CSS here and explore\n * the syntax tree created by chosen parser.\n * Enjoy!\n */\n\n.demo{\n  border:1px solid red;\n}",
          "hasBOM": false,
          "id": "<input css 31>"
        },
        "end": {
          "line": 5,
          "column": 3
        }
      },
      "text": "*\n * Paste or drop some CSS here and explore\n * the syntax tree created by chosen parser.\n * Enjoy!"
    },
    {
      "raws": {
        "before": "\n\n",
        "between": "",
        "semicolon": true,
        "after": "\n"
      },
      "type": "rule",
      "nodes": [
        {
          "raws": {
            "before": "\n  ",
            "between": ":"
          },
          "type": "decl",
          "source": {
            "start": {
              "line": 8,
              "column": 3
            },
            "input": {
              "css": "/**\n * Paste or drop some CSS here and explore\n * the syntax tree created by chosen parser.\n * Enjoy!\n */\n\n.demo{\n  border:1px solid red;\n}",
              "hasBOM": false,
              "id": "<input css 31>"
            },
            "end": {
              "line": 8,
              "column": 23
            }
          },
          "prop": "border",
          "value": "1px solid red"
        }
      ],
      "source": {
        "start": {
          "line": 7,
          "column": 1
        },
        "input": {
          "css": "/**\n * Paste or drop some CSS here and explore\n * the syntax tree created by chosen parser.\n * Enjoy!\n */\n\n.demo{\n  border:1px solid red;\n}",
          "hasBOM": false,
          "id": "<input css 31>"
        },
        "end": {
          "line": 9,
          "column": 1
        }
      },
      "selector": ".demo"
    }
  ],
  "source": {
    "input": {
      "css": "/**\n * Paste or drop some CSS here and explore\n * the syntax tree created by chosen parser.\n * Enjoy!\n */\n\n.demo{\n  border:1px solid red;\n}",
      "hasBOM": false,
      "id": "<input css 31>"
    },
    "start": {
      "line": 1,
      "column": 1
    }
  }
}
複製代碼

是否是感受看的暈頭轉向?別怕!經過打印,你將會看到樹型結構的Js對象是一個名爲Root的構造函數,而起樹型結構的nodes節點下還有Commont,AtRule,Rule構造函數。

  • Root: PostCss處理過的Css,整個處理過程基本上都在圍繞着Root,Commont,AtRule,Rule都是它的子節點。
  • Commont: Css中的註釋信息,註釋的內容在Commont.text下。
  • AtRule: 爲帶@標識的部分,name爲標識名稱,params爲標識參數。nodes爲內部包含的其餘子節點,能夠是Commont,AtRule,Rule,這讓咱們能夠自定義更多的規則
  • Rule: 選擇器樣式部分,一個選擇器表明一個Rule,選擇器對應的樣式列表nodes爲Declaration構造函數
  • Declaration: 爲Css樣式屬性,prop爲樣式屬性,value爲樣式值。可給Rule手動添加樣式屬性,也能夠修改prop,value。
2. 如何調試插件?

postcss插件也能夠在node環境中單獨運行。

其中,index.js文件就是你編寫的插件入口

// 本地測試文件,若是要執行,須要手動建立  /demo/ccs.css
const postcss = require('postcss')
const process = require('process')
const fs = require('fs')
// index.js文件就是你編寫的插件入口
const borderFill = require('./index.js')
fs.readFile('./demo/ccs.css', (err, css) => {
  postcss((borderFill)({ ratio: 100, replace: false }))
    .process(css, { from: './demo/css.css', to: './dist/css.css' })
    .then(result => {
      fs.writeFile('./dist/css.css', result.css, () => true)
      if (result.map) {
        fs.writeFile('./dist/css.map', result.map, () => true)
      }
    })
})
複製代碼

這樣,你就能夠在一個本身搭建的簡易的環境中測試你編寫的postcss插件了。

3. 如何編寫插件?

上文中,咱們對Css處理後生成的Root以及其節點下的Commont,AtRule,Rule, Declaration有了基本的認識,那麼咱們是如何得到Root,又將拿這些構造函數作些什麼呢。

carbon (1).png

總結以下:

  • 咱們要重點關注對象 Root,Commont,AtRule,Rule, Declaration,Result;

  • 遍歷這些對象的方法,在上文提到的api文檔中也有詳細介紹。

walkCommonts,walkAtRules,walkRules,walkDels;

  • 遍歷完後,咱們匹配到對應的節點後,就須要對節點進行操做,有如下api: append、clone、remove、after、before、insert

postcss-border-1px開發

npm包

npm i postcss-border-1px --s -d
複製代碼

github:點這裏。

1.目錄。

建立postcss-border-1px 項目

插件思路: 主要是經過遍歷css選擇器,檢測border屬性,若是有,就爲該選擇器新增一個僞元素,並添加僞元素樣式。

carbon.png

補充:

歡迎關注公衆號:前端開發指南

本文使用 mdnice 排版

相關文章
相關標籤/搜索