移动端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 排版