question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Custom variant wrongly purged

See original GitHub issue

I defined the following custom variant:

      // aos variant
      addVariant('aos', ({ modifySelectors, separator }) => {
        modifySelectors(({ selector }) => {
          return selectorParser(selectors => {
            const clonedSelectors = selectors.clone();
            [selectors, clonedSelectors].forEach((sel, i) => {
              sel.walkClasses(classNode => {
                classNode.value = `aos${separator}${classNode.value}`;
                classNode.parent.insertBefore(classNode, selectorParser().astSync(`.aos-animate${i === 0 ? '' : ' '}`));
              });
            });
            selectors.append(clonedSelectors);
          }).processSync(selector);
        });
      });

The variant works propery, as in aos:translate-x-0 for instance. The problem is that when I build it for production using the default purge settings, this variant css is not included.

It seems the dash in the .aos-animate css is the culprit as I have another variant called stuck which doesn’t get purged.

If I rename eveything to aos-animate, including variant name, it still doesn’t work.

If I rename everythign to aos, including css selector in the modified css, it does work but obviously it doesn’t work as the library I am using sets it to aos-animate.

I am going to probably switch the library (a scroll to reveal) that will allow me to set the class to something single workd, but I do believe this is a bug.

Thanks! Just started to use tailwind (and UI) and happy with it so far. Still riding the learning curve.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
smarterdigitalltdcommented, Nov 25, 2020

Here’s what I’ve found so far:

Here’s an example of a variant that works fine in non-prod (ie non-purged) environments (confirming that the CSS targeting is correct, as well as the plugin inclusion + variant config are all OK):

module.exports = plugin(function ({ addVariant, e }) {
  addVariant("scrolled", ({ modifySelectors, separator }) => {
    modifySelectors(({ className }) => {
      return `.headroom--not-top.headroom--pinned .${e(`scrolled${separator}${className}`)}`;
    });
  });
})

However, that stops working with PurgeCSS until I change to:

module.exports = plugin(function ({ addVariant, e }) {
  addVariant("scrolled", ({ modifySelectors, separator }) => {
    modifySelectors(({ className }) => {
      return `.${e(`headroom--not-top`)} .${e(`scrolled${separator}${className}`)}`;
    });
  });
})

Note that I had to drop the “.headroom–pinned” selector - it seemed that this wouldn’t work even if I tried this:

module.exports = plugin(function ({ addVariant, e }) {
  addVariant("scrolled", ({ modifySelectors, separator }) => {
    modifySelectors(({ className }) => {
      return `.${e(`headroom--not-top`)}.${e(`headroom--pinned`)} .${e(`scrolled${separator}${className}`)}`;
    });
  });
})

This should be equivalent to the original working-only-in-dev version at the top in terms of what should be rendered, but nothing at all for this variant appears in the CSS file.

So now I’m using the second example. However - another variant which uses the exact same structure as the above isn’t working unless it’s a non-prod/purged environment (this might be related to @hanoii 's hyphen weirdness - although hyphens worked for me above):

module.exports = plugin(function ({ addVariant, e }) {
  addVariant("current-menu-item", ({ modifySelectors, separator }) => {
    modifySelectors(({ className }) => {
      return `.${e(`current-menu-item`)} .${e(`current-menu-item${separator}${className}`)}`;
    });
  });
})

Apart from the variant and class names, it’s identical to the earlier example which did work in both purged & non-purged environments.

Finally, I tried alternative syntax as per @hanoii 's example (and other libraries) - although this seems to be a PurgeCSS - not a PostCSS - thing.

Doesn’t work:

module.exports = plugin(function ({ addVariant, e }) {
  addVariant("scrolled", ({ modifySelectors, separator }) => {
    modifySelectors(({ selector }) => {
      return selectorParser(selectors => {
        selectors.walkClasses(classNode => {
          classNode.value = `scrolled${separator}${classNode.value}`;
          classNode.parent.insertBefore(classNode, selectorParser().astSync(`.${e('headroom--pinned')}.${e('headroom--not-top')} `));
        });
      }).processSync(selector);
    });
  });
})

Works:

module.exports = plugin(function ({ addVariant, e }) {
  addVariant("scrolled", ({ modifySelectors, separator }) => {
    modifySelectors(({ selector }) => {
      return selectorParser(selectors => {
        selectors.walkClasses(classNode => {
          classNode.value = `scrolled${separator}${classNode.value}`;
          classNode.parent.insertBefore(classNode, selectorParser().astSync(`.${e('headroom--pinned')} `));
        });
      }).processSync(selector);
    });
  });
})

Plus, for all of these variations, I’ve tried combos of the PurgeCSS whitelist (I tried “safelist” too) config (Regex isn’t my thing, so I’m not fully confident here):

    whitelist: {
      greedy: [/headroom/, /current-menu-item/],
    },
    whitelist: {
      deep: [/headroom/, /current-menu-item/],
    },

I’m also tied to using Tailwind 1.9.x on this project for the time being so I’m quite stuck (but I’m making what might be a false assumption that TW2 would magically resolve this! 😃

I can’t go live with un-purged CSS, so I might need to start extracting variants out to CSS files for the time being.

0reactions
adamwathancommented, Dec 17, 2020

Yeah this is expected behavior with PurgeCSS, it will remove all CSS selectors that don’t appear to be used. So for example:

.foo .bar {
  background: white;
}

Here the only way for this selector to ever actually do anything is if both foo and bar appear in your HTML. If PurgeCSS can’t find both of them, it will consider the selector to be unused and remove the CSS.

The solution is to either safelist aos, or make sure PurgeCSS is looking at the JavaScript file that adds the class (that’s the approach I would take).

We explain this very explicitly in the documentation:

image

This list should include any files in your project that reference any of your styles by name. For example, if you have a JS file in your project that dynamically toggles some classes in your HTML, you should make sure to include that file in this list.

Going to close as not a bug but hopefully that is helpful!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Microsoft Dynamics AX Forum
Error when creating product variant, Function EcoResProductNumberBuilderVarinat.validateForNumber has been incorrectly called. Unanswered. Hi. I'm facing the ...
Read more >
Tailwind will not purge - Stack Overflow
Did you try running the script with NODE_ENV=production ? like. NODE_ENV=production npx tailwindcss -i ./src/tailwind.css -o .
Read more >
Thoughts on custom alternative to std::variants : r/cpp - Reddit
22 votes, 35 comments. 235K subscribers in the cpp community. Discussions, articles and news about the C++ programming language or ...
Read more >
The racial burden of voter list maintenance errors - Science
Administrative records are increasingly used to identify registered voters who may have moved, with potential movers then sent postcards asking them to ...
Read more >
Common homozygosity for predicted loss-of-function variants ...
Here, we found 166 genes with 179 predicted LoF variants for which the frequency of homozygous individuals exceeds 1% in at least one...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found