by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 06:11

    ai on ose

    Fix package.json order (compare)

  • 05:53

    ai on ose

    Add fast scanning rule (compare)

  • 05:39

    ai on ose

    Clean up code Add fast filters for decl props… (compare)

  • 05:08

    ai on ose

    Update PrettierX (compare)

  • Aug 10 04:15
    ai closed #1383
  • Aug 10 04:15
    ai commented #1383
  • Aug 10 04:03
    ai labeled #1390
  • Aug 10 04:03
    ai edited #1385
  • Aug 10 04:02
    ai milestoned #1390
  • Aug 10 04:02
    ai opened #1390
  • Aug 10 02:22
    ai labeled #1389
  • Aug 10 02:22
    ai labeled #1388
  • Aug 10 02:22
    ai milestoned #1389
  • Aug 10 02:22
    ai opened #1389
  • Aug 10 02:18
    ai commented #1387
  • Aug 10 02:18

    ai on ose

    Use logo from official website Update plugin guidelines (compare)

  • Aug 10 02:18
    ai closed #1387
  • Aug 10 02:18
    ai commented #1387
  • Aug 10 01:53
    ai milestoned #1388
  • Aug 10 01:53
    ai opened #1388
Adi Sahar
@adi518
My tree shaking fails with styleInject, anyone solve this?
1 reply
Alberto Trujillo González
@altrugon
I had to place "postcss-import": {}, at the beginning of my plugin list
Gavin McFarland
@limitlessloop
Also I'm experimenting with something that uses CSS vars that you change the value of at different breakpoints. https://typolize.now.sh/
Andrey Sitnik
@ai
I created a plugin to fix 100vh issue in Safari
https://github.com/postcss/postcss-100vh-fix
2 replies
Gavin McFarland
@limitlessloop
Hi, I read somewhere but can’t find the source now; that it was recommended that any plugin which relies on unique CSS or something that effects the syntax should use reference the plugin in the stylesheet using @use. Are there any plans to make this a default part of PostCSS?
26 replies
Kether Saturnius
@K3TH3R
So possibly weird question... is it possible to retain a reference to a node to return to at a later time? I'm working on a plugin-based framework and rather than having each plugin generate it's own :root {} node for the css vars the plugin is outputting, I'd like to be able to push all of the nodes into the same :root {} instance...
Gavin McFarland
@limitlessloop
@K3TH3R from what I know there isn't an API for PostCSS plugins talk to each other but someone else may correct me. The best way would be for the last plugin or a separate plugin to merge the nodes into the same root. If you didn't want it to interfere with other :root {} blocks you could get each plugin to add a comment and the look for root blocks with those comments.
Kether Saturnius
@K3TH3R
well... I've figured out how to pass a context object between plugins like this: return plugins.reduce((promise, plugin) => { return promise.then(plugin(ctx)(css)) }, Promise.resolve())
so would there be a way to store a node reference within that ctx object?
Kether Saturnius
@K3TH3R
yeah, so I think I figured out a workable solution. I can just create a new postcss root node as a property on my context object and each plugin can just append its styles to that node and then I just write all the css at the end of the plugin pipeline
Gavin McFarland
@limitlessloop
@K3TH3R Nice. Do your plugins work stand alone as well?
1 reply
Gavin McFarland
@limitlessloop
For a while I’ve been working on a polyfill for flex gap. Today I finally finished all the features and it’s ready to move out of alpha. It emulates gaps using margins, but this is more than just a plugin which applies margins. It uses some really interesting maths to calculate all the possible combinations of values and supports pretty much every scenario including even applying margin with gaps and nested gaps.
https://github.com/limitlessloop/flex-gap-polyfill
6 replies
Andrey Sitnik
@ai

What do you think about this new plugin API for PostCSS 8?

https://twitter.com/PostCSS/status/1291507810216230912

/cc @jonathantneal @limitlessloop

// before

const postcss = require('postcss')

module.exports = postcss.plugin('name', (opts) => {
  return root => {
    root.on('decl', (node, index) => {
      if (node.prop === 'will-change') {
        node.cloneBefore({ prop: 'backface-visibility', value: 'hidden' })
      }
    })
  }
})
// after

module.exports = (opts) => ({
  postcssPlugin: 'name',
  decl(decl) {
    if (node.prop === 'will-change') {
      node.cloneBefore({ prop: 'backface-visibility', value: 'hidden' })
    }
  }
})
module.exports.postcss = true
Jonathan Neal
@jonathantneal
I like it. I prefer it. It would be helpful if access to the postcss object (or some utility object) came in through through the second argument.
Similar to how in Babel your plugin is a function that receives the babel instance with access to all the types and checkers, which developers often name t.
Andrey Sitnik
@ai

It would be helpful if access to the postcss object (or some utility object) came in through through the second argument.

yeap, I am thinking about:

  decl(decl, postcss, result) {
    …
  }
or should be use decl(decl, result, postcss) order?

or we can add all postcss helpers to the result

/cc @jonathantneal

Jonathan Neal
@jonathantneal
This is only intended to demonstrate that I meant the second argument in the default export, but I got carried away:
export default (opts, { parse: { commaSeparatedList, spaceSeparatedList } }) => ({
  name: "my-plugin",
  visitor: {
    Declaration(node) {
      if (node.name.toLowerCase() === 'will-change') {
        node.cloneBefore({ name: 'backface-visibility', value: 'hidden' })
      }
    }
  }
})
Andrey Sitnik
@ai
export default ({ parse: { commaSeparatedList, spaceSeparatedList } }) => ({
it will break postcss([plugin(opts)]) API. I do not want to force PostCSS users to update their configs :(
Jonathan Neal
@jonathantneal
You are totally right. That was a bad typo! I fixed it as you pointed out the incompatibility.
Andrey Sitnik
@ai
when users call plugin(opts), the second argument will be empty :(
Jonathan Neal
@jonathantneal
Ah..
In that case, I like the idea of 2 arguments, where the second contains all the features.
export default (opts) => ({
  name: "my-plugin",
  visitor: {
    Declaration(node, { parse: { commaSeparatedList, spaceSeparatedList }, result }) {
      if (node.name.toLowerCase() === 'will-change') {
        node.cloneBefore({ name: 'backface-visibility', value: 'hidden' })
      }
    }
  }
})
Andrey Sitnik
@ai
We need a Result just for result.warn(). Yeap, it looks like a good idea.
Or should we merge everything to second argument?
  decl (node, { result, list }) {
  }
Jonathan Neal
@jonathantneal
Oh yea. I think that’s how I did it in the second example (or I intended to). I’m a fan of always maxing out at 2 arguments.
Jonathan Neal
@jonathantneal

So, in the new plugin API, the main function would still get passed an options object, but its return value could be an object. And that object could support visitors. I love that.

I would recommend bundling visitors within a visitor field, as I did in the example, and then naming them by their class. I think it would be logical and familiar. Not only does it cross-inform authors of the relationship between the visitor and the type, but it comfortably matches the expectations in Babel.

Andrey Sitnik
@ai
Declaration is soo long :(
Also I like shortcut like declExit and not Delcarataion: { exit }
Jonathan Neal
@jonathantneal
This isn’t an argument (if it was, it would be a bad argument), but have you written any babel plugins? :P
Andrey Sitnik
@ai
nope :D
I afraid of be too familiar with Babel plugin because there are few important changes in API
for instance, in PostCSS you can change any node inside visitor callback
developer could miss it if we will be to similar with Babel API
What do we think about adding postcss to a plugin’s and runner’s peerDependencies?
Jonathan Neal
@jonathantneal
Would the non-suffixed visitor run on Enter or Exit?
With this new API you’re discussing, it would make sense to move postcss to peerDependencies/devDependencies.
Effectively, “postcss” ships as the second argument to a visitor. Although, it seems more like the processor object, with result tagged on for good measure. :D
Whatever that second argument is, that would be a good place to include utilities, like list (as normally imported from PostCSS in v7).
Jonathan Neal
@jonathantneal
Unrelated; I have a feeling it’s going to be tough to sell you on Declaration. In my defense, that is what we call it in CSS, and that is what we call it in the PostCSS documentation, and what it is named as a class in the source. Just sayin’. Just sayin’. (Do forgive my silly mood.)
Andrey Sitnik
@ai

Would the non-suffixed visitor run on Enter

On enter

John Winston
@winston0410
Hi. Is there any PostCSS plugin that would add declarations to a selector, using another declaration as condition?
For example, always add "font-weight: 700" to the selector when "display: none" is found, just for an example
Gavin McFarland
@limitlessloop
@winston0410 I've not come across one but depending on what you want to do it wouldnt be hard to create a plugin yourself. If you tell me what you're looking to do I might be able to help.
Jonathan Neal
@jonathantneal
That sounds like a great feature for our often-dreamed-never-build PostCSS CodeMod.
Jonathan Neal
@jonathantneal
when
  .Rule
    .hasDeclaration({ name: 'display', value: 'none' })
    .then
      .assignDeclaration({ name: 'font-weight', value: '700' })
10 replies
Andrey Sitnik
@ai
@jonathantneal OK, I was convinced https://twitter.com/PostCSS/status/1291813215827976192