移動端web項目愈來愈多,設計師對於UI的要求也愈來愈高,好比1px 的邊框。在高清屏下,移動端的1px 會很粗。現現在已經有許多優秀的1px解決方案css
這裏總結幾種較好用的解決方案html
優勢: 由於僞元素::after或::before是獨立於當前元素,能夠單獨對其縮放而不影響元素自己的縮放前端
僞元素大多數瀏覽器默認單引號也可使用,
和僞類同樣形式,並且單引號兼容性(ie)更好些
複製代碼
缺點:須要額外編寫僞元素樣式。對於我這種懶癌往期用戶來講,真的頭疼;vue
優勢:使用 less 對公共代碼(方案一)封裝,同時增長媒體查詢分別對不一樣 DPR 的設備,進行不一樣的縮放node
缺點:須要調用封裝好的less函數。對於不懂less的同窗們來講,可能須要額外去學習下less,若是項目沒使用預處理(less,sass,stylus),還須要額外引入。react
那麼,有沒有辦法我既不額外引入第三方預處理器,也無需額外寫一堆僞元素樣式? ok,既然你看到這裏了,那麼就繼續加油,立刻帶你瞭解一下基於postcss的解決方案。git
若是你只是想直接使用該插件或者想看代碼,你能夠直接跳到4。github
多時候第一次在網上查詢 PostCSS 概念的時候,你們都解釋成一個後處理器的概念,其實我的以爲這些概念不重要,更爲重要的有如下幾點:web
它本質上是一個什麼東西vue-cli
PostCSS 能夠直觀的理解爲:它就是一個平臺、平臺、平臺,重要的事情來三遍比較爽,哈哈!
什麼說它是一個平臺呢?由於咱們直接用它,感受不能幹什麼事情,可是若是讓一些插件在它上面跑,那麼將會很強大。
PostCSS 提供了一個解析器,它可以將 CSS 解析成抽象語法樹(AST)。
也就是說,postcss只是幫咱們把css解析成一個ast,除此以外,它什麼都沒作。因此說,PostCSS 它須要一個插件系統纔可以發揮做用。咱們能夠經過「插件」來傳遞AST,而後再把AST轉換成一個串,最後再輸出到目標文件中去。固然,這裏是有API能夠用,這裏先不講,省得暈了。
有如下幾個步驟
前面說過了,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'
]
}
複製代碼
const border1px = require('postcss-botder-1px')
module.exports = {
plugin:[
border1px({option}) // option是插件的參數
]
}
複製代碼
自此,就完成了插件的使用。在項目中,你能夠正常寫border
border:1px solid red;
複製代碼
module.exports = postcss.plugin('plugin-name', opts => {
return (root, result) => {
// Plugin code
}
})
複製代碼
例子:
要解析的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構造函數。
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插件了。
上文中,咱們對Css處理後生成的Root以及其節點下的Commont,AtRule,Rule, Declaration有了基本的認識,那麼咱們是如何得到Root,又將拿這些構造函數作些什麼呢。
carbon (1).png
總結以下:
咱們要重點關注對象 Root,Commont,AtRule,Rule, Declaration,Result
;
遍歷這些對象的方法,在上文提到的api文檔中也有詳細介紹。
walkCommonts,walkAtRules,walkRules,walkDels;
append、clone、remove、after、before、insert
npm i postcss-border-1px --s -d
複製代碼
1.目錄。
建立postcss-border-1px 項目
插件思路: 主要是經過遍歷css選擇器,檢測border屬性,若是有,就爲該選擇器新增一個僞元素,並添加僞元素樣式。
carbon.png
補充:
歡迎關注公衆號:前端開發指南
本文使用 mdnice 排版