首页 > 解决方案 > 为 PostCSS 中的所有直系后代生成规则

问题描述

我想创建一个 PostCSS 插件,我可以在其中为所有直系后代生成新规则。

例如,我想生成规则:

div > * {
   color: black;
}

对于所有divs,这是display: block

我没有找到如何做到这一点的好例子。

module.exports = () => {
  let skipped = Symbol("isSkipped"); // skipped flag
  let counter = Symbol("skippedCounter"); // counter for test "isSkipped" optimization

  function generateRule(decl) {
    let rules = decl.parent;
    rules[counter] = Number.isInteger(rules[counter]) ? rules[counter] : 0;

    if (!rules[skipped]) {
      if (decl.value === "block") {
        
        // generate a new rule here

        rules[skipped] = true;
        rules[counter]++;
      }
    }
  }

  return {
    postcssPlugin: "postcss-example-plugin",
    Declaration: {
      display: (decl) => generateRule(decl),
    },
  };
};
module.exports.postcss = true;

标签: javascriptabstract-syntax-treepostcss

解决方案


我不能 100% 确定您要查找的部分,所以如果这不能回答您的问题,请随时澄清,我会更新回复。

这是一些我认为可以满足您的需求的代码-尽管它主要是您在没有优化的情况下已经编写的代码:

module.exports = {
  postcssPlugin: "add-rule-to-descendants",
  Declaration: {
    // https://postcss.org/api/#declarationprocessor
    display(displayDecl, { Rule, Declaration }) {
      if (displayDecl.value === 'block') {
        // Add the new rule after the parent https://postcss.org/api/#rule-after
        displayDecl.parent.after(
          new Rule({
            selector: `${displayDecl.parent.selector} > *`,
            nodes: [
              new Declaration({ prop: 'color', value: 'black' })
            ]
          })
        );
      }
    }
  }
}

我还通过对 Repl.it https://repl.it/@dcwither/postcss-all-decendants-rule#plugin.js的一些快速测试来准备这个示例。


推荐阅读