换肤
https://juejin.cn/post/6844903596992135182
https://juejin.cn/post/6844903553090191368
https://juejin.cn/post/6844903745734590477
https://segmentfault.com/a/1190000016061608
https://www.jianshu.com/p/35e0581629d2
https://github.com/postcss/postcss-custom-properties
https://juejin.cn/post/6844904122643120141#heading-9
https://github.com/hzsrc/webpack-theme-color-replacer
https://github.com/m-Ryan/css-color-extract-plugin
https://element.eleme.cn/#/zh-CN/theme/preview
https://github.com/csstree/csstree#readme
https://astexplorer.net/#/gist/244e2fb4da940df52bf0f4b94277db44/e79aff44611020b22cfd9708f3a99ce09b7d67a8
https://blog.csdn.net/a19905522/article/details/87274590
https://github.com/ElementUI/element-theme#readme
element的color色系生成 :
https://blog.csdn.net/weixin_45189747/article/details/102533517?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
https://blog.csdn.net/youlinaixu/article/details/83447527?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-14.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-14.control
antd的color: https://github.com/ant-design/ant-design-colors#readme
https://ant.design/docs/spec/colors
var csstree = require('css-tree'); // parse CSS to AST var ast = csstree.parse(`.example { world: "!" } .el-button:focus, .el-button:hover { color: #409eff; border-color: #c6e2ff; background-color: #ecf5ff; }`); // traverse AST and modify it csstree.walk(ast, function(node) { if (node.type === 'ClassSelector') { node.name = `${node.name}[data-ui=ibu]`; } if(node.type==='Hash'){ node.value='@@primary' } if(node.type=='Function'&&node.name==='rgba'){ // node.children.value='@@primary' node.type='Hash' node.value='@@border1' } }); // generate CSS from AST console.log(csstree.generate(ast)); // .hello{world:"!"}
//postcss.js const postcss = require("postcss"); const path = require("path"); const fs = require("fs-extra"); const elementColorMapFunc = require("./colortest").default; let elmentColorMap = elementColorMapFunc(); function resolve(pathStr) { return path.resolve(__dirname, pathStr); } // 解析 let resultPath = resolve("./src/components/PenBtn2.css"); let fileStr = fs.readFileSync(resolve("./src/components/PenBtn.css")); let css = postcss.parse(fileStr); // 循环处理 css.walkRules(function(rule, index) { let namesArr = []; rule.selectors.forEach((selector) => { namesArr.push(`div[data-ui="IBU"] ${selector}`); }); namesArr.length && (rule.selectors = namesArr.concat()); // 编辑属性键值 rule.walkDecls((decl) => { let { parent: rule, value, prop } = decl; // let nodes = rule.nodes; // let colorTargetArr = Object.values(elmentColorMap).filter(valObj=>{ // return valObj.value=='#409EFF' // }) if (value == "#409eff") { decl.value = "red"; } }); }); if (fs.existsSync(resultPath)) { fs.removeSync(resultPath); } fs.writeFileSync(resultPath, css.toResult());
//color.js /** *@description 生成对应配色映射关系 *@date 2021-06-10 16:35:03 */ const Color = require("color"); //FIXME:还需要全局搜索变量 看是否有一些mix了的颜色 //Brand Color let primaryColor = "#409EFF", //$--color-primary successColor = "#67C23A", //$--color-warning warningColor = "#E6A23C", //$--color-warning dangerColor = "#F56C6C", //$--color-danger infoColor = "#909399", //$--color-info // Font Color textRegularColor = "#606266", //$--color-text-regular textPlaceholderColor = "#C0C4CC", //$--color-text-placeholder textPrimaryColor = "#303133", //$--color-text-primary textSecondaryColor = "#909399", //$--color-text-secondary //FIXME:#909399 这个色有两个变量匹配上了,需要区分 // Border Color borderColorBaseColor = "#DCDFE6", //$--border-color-base borderColorLightColor = "#E4E7ED", //$--border-color-lightColor borderColorLighterColor = "#EBEEF5", //$--border-color-lighter borderColorExtraLightColor = "#F2F6FC", //$--border-color-extra-light // Background Color colorWhite = "#FFFFFF", //$--color-white colorBlack = "#000000", //$--color-black backgroundColorBase = "#F5F7FA"; //$--background-color-base class GenerateColor { constructor() { this.colorMap = {}; this.init(); } init() { this.getPrimaryMap(); this.getSuccessMap(); this.getWarningMap(); this.getDangerMap(); this.getinfoMap(); } createValueObj(majorColor, mixColor, percent, cb) { return { value: Color(majorColor) .mix(Color(mixColor), percent) .hex() .toLowerCase(), callBack: cb || null, }; } getPrimaryMap() { //primary let primaryArr = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]; let primaryMap = primaryArr.reduce( (pre, cur, index) => { pre[`@primary-${index + 1}`] = this.createValueObj( primaryColor, colorWhite, cur ); return pre; }, { "@primary": { value: primaryColor, callBack: null }, } ); Object.assign(this.colorMap, primaryMap); } getSuccessMap() { let successArr = [0.8, 0.9]; let successMap = successArr.reduce( (pre, cur, index) => { pre[`@success-${index + 1}`] = this.createValueObj( successColor, colorWhite, cur ); return pre; }, { "@success": { value: successColor, callBack: null }, } ); Object.assign(this.colorMap, successMap); } getWarningMap() { let warningArr = [0.8, 0.9]; let warningMap = warningArr.reduce( (pre, cur, index) => { pre[`@warning-${index + 1}`] = this.createValueObj( warningColor, colorWhite, cur ); return pre; }, { "@warning": { value: warningColor, callBack: null }, } ); Object.assign(this.colorMap, warningMap); } getDangerMap() { let dangerArr = [0.8, 0.9]; let dangerMap = dangerArr.reduce( (pre, cur, index) => { pre[`@danger-${index + 1}`] = this.createValueObj( dangerColor, colorWhite, cur ); return pre; }, { "@danger": { value: dangerColor, callBack: null }, } ); Object.assign(this.colorMap, dangerMap); } getinfoMap() { let infoArr = [0.8, 0.9]; let infoMap = infoArr.reduce( (pre, cur, index) => { pre[`@info-${index + 1}`] = this.createValueObj( infoColor, colorWhite, cur ); return pre; }, { "@info": { value: infoColor, callBack: null }, } ); Object.assign(this.colorMap, infoMap); } getAllMap() { return this.colorMap; } } const colorMapFactory = () => { return new GenerateColor().getAllMap(); }; exports.default = colorMapFactory; // https://blog.csdn.net/weixin_42665725/article/details/113413798 // https://blog.csdn.net/youlinaixu/article/details/83447527?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-14.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-14.control
const path = require("path"); const csstree = require("css-tree"); const fs = require("fs-extra"); function resolve(dir) { return path.join(__dirname, dir); } let cssFileString = fs.readFileSync( resolve("./src/components/PenBtn.css"), "utf-8" ); // parse CSS to AST let ast = csstree.parse(cssFileString); // traverse AST and modify it // csstree.findAll(ast, fn) csstree.walk(ast, function(node,item,list) { if (node.type === "Selector" && !this.function) { node.children.unshift({ type: "WhiteSpace", loc: null, value: " ", }); node.children.unshift({ type:"AttributeSelector", name:{ type:"Identifier", name:"data-ui" }, matcher:"=", value:{ type:"String", value:"\"IBU\"" }, flags: null }) node.children.unshift({ type:"TypeSelector", name:"div" }) } if (node.type === "Hash") { switch (node.value) { case "409eff": node.value = "FF5340"; break; default: break; } // node.value='@@primary' } // if(node.type=='Function'&&node.name==='rgba'){ // // node.children.value='@@primary' // node.type='Hash' // node.value='@@border1' // } }); // generate CSS from AST let resultData = csstree.generate(ast); console.log(resultData); if (fs.existsSync("./src/components/PenBtn2.css")) { fs.removeSync(resolve("./src/components/PenBtn2.css"), (err) => { console.log(err); }); } fs.writeFileSync(resolve("./src/components/PenBtn2.css"), resultData);
.el-button-group > .el-button.is-active, .el-button-group > .el-button.is-disabled, .el-button-group > .el-button:active, .el-button-group > .el-button:focus, .el-button-group > .el-button:hover { z-index: 1; } .el-button { display: inline-block; line-height: 1; white-space: nowrap; cursor: pointer; background: #fff; border: 1px solid #dcdfe6; color: #606266; -webkit-appearance: none; text-align: center; -webkit-box-sizing: border-box; box-sizing: border-box; outline: 0; margin: 0; -webkit-transition: 0.1s; transition: 0.1s; font-weight: 500; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; padding: 12px 20px; font-size: 14px; border-radius: 4px; } .el-button + .el-button { margin-left: 10px; } .el-button:focus, .el-button:hover { color: #409eff; border-color: #c6e2ff; background-color: #ecf5ff; } .el-button:active { color: #3a8ee6; border-color: #3a8ee6; outline: 0; } .el-button::-moz-focus-inner { border: 0; } .el-button [class*="el-icon-"] + span { margin-left: 5px; } .el-button.is-plain:focus, .el-button.is-plain:hover { background: #fff; border-color: #409eff; color: #409eff; } .el-button.is-active, .el-button.is-plain:active { color: #3a8ee6; border-color: #3a8ee6; } .el-button.is-plain:active { background: #fff; outline: 0; } .el-button.is-disabled, .el-button.is-disabled:focus, .el-button.is-disabled:hover { color: #c0c4cc; cursor: not-allowed; background-image: none; background-color: #fff; border-color: #ebeef5; } .el-button.is-disabled.el-button--text { background-color: transparent; } .el-button.is-disabled.is-plain, .el-button.is-disabled.is-plain:focus, .el-button.is-disabled.is-plain:hover { background-color: #fff; border-color: #ebeef5; color: #c0c4cc; } .el-button.is-loading { position: relative; pointer-events: none; } .el-button.is-loading:before { pointer-events: none; content: ""; position: absolute; left: -1px; top: -1px; right: -1px; bottom: -1px; border-radius: inherit; background-color: rgba(255, 255, 255, 0.35); } .el-button.is-round { border-radius: 20px; padding: 12px 23px; } .el-button.is-circle { border-radius: 50%; padding: 12px; } .el-button--primary { color: #fff; background-color: #409eff; border-color: #409eff; } .el-button--primary:focus, .el-button--primary:hover { background: #66b1ff; border-color: #66b1ff; color: #fff; } .el-button--primary.is-active, .el-button--primary:active { background: #3a8ee6; border-color: #3a8ee6; color: #fff; } .el-button--primary:active { outline: 0; } .el-button--primary.is-disabled, .el-button--primary.is-disabled:active, .el-button--primary.is-disabled:focus, .el-button--primary.is-disabled:hover { color: #fff; background-color: #a0cfff; border-color: #a0cfff; } .el-button--primary.is-plain { color: #409eff; background: #ecf5ff; border-color: #b3d8ff; } .el-button--primary.is-plain:focus, .el-button--primary.is-plain:hover { background: #409eff; border-color: #409eff; color: #fff; } .el-button--primary.is-plain:active { background: #3a8ee6; border-color: #3a8ee6; color: #fff; outline: 0; } .el-button--primary.is-plain.is-disabled, .el-button--primary.is-plain.is-disabled:active, .el-button--primary.is-plain.is-disabled:focus, .el-button--primary.is-plain.is-disabled:hover { color: #8cc5ff; background-color: #ecf5ff; border-color: #d9ecff; } .el-button--success { color: #fff; background-color: #67c23a; border-color: #67c23a; } .el-button--success:focus, .el-button--success:hover { background: #85ce61; border-color: #85ce61; color: #fff; } .el-button--success.is-active, .el-button--success:active { background: #5daf34; border-color: #5daf34; color: #fff; } .el-button--success:active { outline: 0; } .el-button--success.is-disabled, .el-button--success.is-disabled:active, .el-button--success.is-disabled:focus, .el-button--success.is-disabled:hover { color: #fff; background-color: #b3e19d; border-color: #b3e19d; } .el-button--success.is-plain { color: #67c23a; background: #f0f9eb; border-color: #c2e7b0; } .el-button--success.is-plain:focus, .el-button--success.is-plain:hover { background: #67c23a; border-color: #67c23a; color: #fff; } .el-button--success.is-plain:active { background: #5daf34; border-color: #5daf34; color: #fff; outline: 0; } .el-button--success.is-plain.is-disabled, .el-button--success.is-plain.is-disabled:active, .el-button--success.is-plain.is-disabled:focus, .el-button--success.is-plain.is-disabled:hover { color: #a4da89; background-color: #f0f9eb; border-color: #e1f3d8; } .el-button--warning { color: #fff; background-color: #e6a23c; border-color: #e6a23c; } .el-button--warning:focus, .el-button--warning:hover { background: #ebb563; border-color: #ebb563; color: #fff; } .el-button--warning.is-active, .el-button--warning:active { background: #cf9236; border-color: #cf9236; color: #fff; } .el-button--warning:active { outline: 0; } .el-button--warning.is-disabled, .el-button--warning.is-disabled:active, .el-button--warning.is-disabled:focus, .el-button--warning.is-disabled:hover { color: #fff; background-color: #f3d19e; border-color: #f3d19e; } .el-button--warning.is-plain { color: #e6a23c; background: #fdf6ec; border-color: #f5dab1; } .el-button--warning.is-plain:focus, .el-button--warning.is-plain:hover { background: #e6a23c; border-color: #e6a23c; color: #fff; } .el-button--warning.is-plain:active { background: #cf9236; border-color: #cf9236; color: #fff; outline: 0; } .el-button--warning.is-plain.is-disabled, .el-button--warning.is-plain.is-disabled:active, .el-button--warning.is-plain.is-disabled:focus, .el-button--warning.is-plain.is-disabled:hover { color: #f0c78a; background-color: #fdf6ec; border-color: #faecd8; } .el-button--danger { color: #fff; background-color: #f56c6c; border-color: #f56c6c; } .el-button--danger:focus, .el-button--danger:hover { background: #f78989; border-color: #f78989; color: #fff; } .el-button--danger.is-active, .el-button--danger:active { background: #dd6161; border-color: #dd6161; color: #fff; } .el-button--danger:active { outline: 0; } .el-button--danger.is-disabled, .el-button--danger.is-disabled:active, .el-button--danger.is-disabled:focus, .el-button--danger.is-disabled:hover { color: #fff; background-color: #fab6b6; border-color: #fab6b6; } .el-button--danger.is-plain { color: #f56c6c; background: #fef0f0; border-color: #fbc4c4; } .el-button--danger.is-plain:focus, .el-button--danger.is-plain:hover { background: #f56c6c; border-color: #f56c6c; color: #fff; } .el-button--danger.is-plain:active { background: #dd6161; border-color: #dd6161; color: #fff; outline: 0; } .el-button--danger.is-plain.is-disabled, .el-button--danger.is-plain.is-disabled:active, .el-button--danger.is-plain.is-disabled:focus, .el-button--danger.is-plain.is-disabled:hover { color: #f9a7a7; background-color: #fef0f0; border-color: #fde2e2; } .el-button--info { color: #fff; background-color: #909399; border-color: #909399; } .el-button--info:focus, .el-button--info:hover { background: #a6a9ad; border-color: #a6a9ad; color: #fff; } .el-button--info.is-active, .el-button--info:active { background: #82848a; border-color: #82848a; color: #fff; } .el-button--info:active { outline: 0; } .el-button--info.is-disabled, .el-button--info.is-disabled:active, .el-button--info.is-disabled:focus, .el-button--info.is-disabled:hover { color: #fff; background-color: #c8c9cc; border-color: #c8c9cc; } .el-button--info.is-plain { color: #909399; background: #f4f4f5; border-color: #d3d4d6; } .el-button--info.is-plain:focus, .el-button--info.is-plain:hover { background: #909399; border-color: #909399; color: #fff; } .el-button--info.is-plain:active { background: #82848a; border-color: #82848a; color: #fff; outline: 0; } .el-button--info.is-plain.is-disabled, .el-button--info.is-plain.is-disabled:active, .el-button--info.is-plain.is-disabled:focus, .el-button--info.is-plain.is-disabled:hover { color: #bcbec2; background-color: #f4f4f5; border-color: #e9e9eb; } .el-button--text, .el-button--text.is-disabled, .el-button--text.is-disabled:focus, .el-button--text.is-disabled:hover, .el-button--text:active { border-color: transparent; } .el-button--medium { padding: 10px 20px; font-size: 14px; border-radius: 4px; } .el-button--mini, .el-button--small { font-size: 12px; border-radius: 3px; } .el-button--medium.is-round { padding: 10px 20px; } .el-button--medium.is-circle { padding: 10px; } .el-button--small, .el-button--small.is-round { padding: 9px 15px; } .el-button--small.is-circle { padding: 9px; } .el-button--mini, .el-button--mini.is-round { padding: 7px 15px; } .el-button--mini.is-circle { padding: 7px; } .el-button--text { color: #409eff; background: 0 0; padding-left: 0; padding-right: 0; } .el-button--text:focus, .el-button--text:hover { color: #66b1ff; border-color: transparent; background-color: transparent; } .el-button--text:active { color: #3a8ee6; background-color: transparent; } .el-button-group { display: inline-block; vertical-align: middle; } .el-button-group::after, .el-button-group::before { display: table; content: ""; } .el-button-group::after { clear: both; } .el-button-group > .el-button { float: left; position: relative; } .el-button-group > .el-button + .el-button { margin-left: 0; } .el-button-group > .el-button:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; } .el-button-group > .el-button:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; } .el-button-group > .el-button:first-child:last-child { border-radius: 4px; } .el-button-group > .el-button:first-child:last-child.is-round { border-radius: 20px; } .el-button-group > .el-button:first-child:last-child.is-circle { border-radius: 50%; } .el-button-group > .el-button:not(:first-child):not(:last-child) { border-radius: 0; } .el-button-group > .el-button:not(:last-child) { margin-right: -1px; } .el-button-group > .el-dropdown > .el-button { border-top-left-radius: 0; border-bottom-left-radius: 0; border-left-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--primary:first-child { border-right-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--primary:last-child { border-left-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--primary:not(:first-child):not(:last-child) { border-left-color: rgba(255, 255, 255, 0.5); border-right-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--success:first-child { border-right-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--success:last-child { border-left-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--success:not(:first-child):not(:last-child) { border-left-color: rgba(255, 255, 255, 0.5); border-right-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--warning:first-child { border-right-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--warning:last-child { border-left-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--warning:not(:first-child):not(:last-child) { border-left-color: rgba(255, 255, 255, 0.5); border-right-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--danger:first-child { border-right-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--danger:last-child { border-left-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--danger:not(:first-child):not(:last-child) { border-left-color: rgba(255, 255, 255, 0.5); border-right-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--info:first-child { border-right-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--info:last-child { border-left-color: rgba(255, 255, 255, 0.5); } .el-button-group .el-button--info:not(:first-child):not(:last-child) { border-left-color: rgba(255, 255, 255, 0.5); border-right-color: rgba(255, 255, 255, 0.5); }