Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: :is and :where selector lists are purged regardless of matching elements #978

Open
1 task done
chriskirknielsen opened this issue Aug 19, 2022 · 15 comments
Open
1 task done

Comments

@chriskirknielsen
Copy link

Describe the bug

When purging CSS, if a non-blocklisted selector is present in an :is() or :where() selector (e.g. :is(h1, h2, h3), it is still purged from the resulting CSS.

To Reproduce

  1. Create a basic HTML page with an <h2>Lorem ipsum</h2> element.
  2. Create a CSS file with a declaration block of :is(h1, h2, h3) { color: red; } (placing * in front of the selector has no effect)
  3. Run PurgeCSS on the created CSS file based on the content of the created HTML file.

Expected Behavior

The resulting styles should have :is(h1, h2, h3) { color: red; } and the <h2> should show up in red. Instead the whole declaration block is missing.

Environment

purgecss: 4.1.3
Environment: macOS v12.4, Node.js v18.6.0, npm v8.13.2

Add any other context about the problem here

CSS is minified (Sass -> CSS with compressed output) before being fed to PurgeCSS. Tested with expanded styles, same result.

Running this as an HTML transform on an Eleventy build (v.2.0.0-canary14) which grabs a hardcoded comment line and replaces it with the purged CSS, see this gist. (this makes it a little more difficult to debug)

My workaround is to safelist :is and :where but this causes unused CSS to be kept since the selectors are used across the stylesheet.

Code of Conduct

  • I agree to follow this project's Code of Conduct
@chriskirknielsen chriskirknielsen changed the title [Bug]: [Bug]: :is and :where selector lists are purged regardless of matching elements Aug 19, 2022
@GrimLink
Copy link

Same issue with the :any-link or any other selector starting with the colon

@diegohaz
Copy link

@Ffloriel I see that this has been fixed on the main branch. Is there anything we can do to get it released to npm?

@Ffloriel
Copy link
Member

I'll release a beta version with the fix this weekend

@Ffloriel
Copy link
Member

It's released under the next tag for the packages purgecss and @fullhuman/postcss-purgecss
npm i -D @fullhuman/postcss-purgecss@next should give you the version with the fix.

@laurentpayot
Copy link

laurentpayot commented Jun 16, 2023

Hi @Ffloriel. Unfortunately this issue seems to persist with version 6.0.0-alpha.0 (@fullhuman/postcss-purgecss@next).
I made a test and rules like :is(h1, h2) { color: red } are still removed from the bundle.

This is quite annoying for me because I’m using a CSS framework with functional pseudo-classes everywhere.
Any news about a fix?

@laurentpayot
Copy link

I just noticed that there is no difference between v6.0.0-alpha.0 (next version) and v5.0.0: v6.0.0-alpha.0...v5.0.0

Is it normal?

@laurentpayot
Copy link

laurentpayot commented Jun 16, 2023

I found a workaround by safelisting selectors starting with a colon this way:

safelist: {
  standard: [ /^\:[-a-z]+$/ ]
}

standard seems to be enough for my use case.

@leifmarcus
Copy link

@laurentpayot, I think, you need to check the difference between the versions the other way round like v5.0.0...v6.0.0-alpha.0.

@laurentpayot
Copy link

D’oh! 🤦 Thanks @leifmarcus.

@bryanjhv
Copy link

Seems to have been fixed on e9a6530.
Are there any plans on publishing any of the new changes from v6.0.0-alpha.0?

@meduzen
Copy link

meduzen commented Apr 5, 2024

Seems to have been fixed on e9a6530. Are there any plans on publishing any of the new changes from v6.0.0-alpha.0?

It’s not the same issue.

I checked on a project using v6 and it’s not fixed despite what’s mentioned in its changelog. Even :where(body) gets fully removed, and it’s probably the most basic use case out there.

@urob
Copy link

urob commented Jun 12, 2024

I can confirm that this is still an issue as of version 6.0.0. Here's a minimal example that might be useful for debugging:

index.html:

<!DOCTYPE html>
<html lang="en">
  <head> <link rel="stylesheet" href="/main.css"> </head>
  <body> <h1>Some heading</h1> </body>
</html>

main.css:

/* Single pseudo-class selectors will be purged */
:is(body) {
  background: white;
}

:is(h1, h2, h3) {
  font-weight: 700;
}

/* Combining pseudo-classes with other selectors won't be purged  */
:is(body) h1 {
  color: black;
}

body :is(h1, h2, h3) {
  display: flex;
}

Running purgecss from the CLI with default options will strip the two standalone pseudo-classes but keeps the ones that are combined with other selectors.


Here's a complete log of what I have done:

$ npx purgecss --version
6.0.0

$ npx purgecss --css main.css --content index.html --output ./out  

$ cat ./out/main.css

The output from the last command is:

/* Single pseudo-class selectors will be purged */

/* Combining pseudo-classes with other selectors won't be purged  */
:is(body) h1 {
  color: black;
}

body :is(h1) {
  display: flex;
}

@ogbotemi-2000
Copy link

I skimmed through the source code in the index.ts file in the repo and I noticed, before the level of bloat discouraged me, the hardcoding of where, is, has among other terms specific to CSS styles.

This may be a culprit as whatever logic led to their hardcoding is not ubiquitous and may fail as unique scenarios using these terms arise upon usage.

Pending the fix of this bug, here is an alternative developed by me that promises to be thorough and do better: https://www.npmjs.com/package/rmrf-css
Cheers.

@leomendoza123
Copy link

I can confirm that I still see this issue. For instance, the following selector gets removed:

:where(.wp-block-columns.is-layout-flex) { gap: 2em; }

As a temporary fix, I am manually unwrapping the :where selector like this:

.wp-block-columns.is-layout-flex { gap: 2em; }

@ogbotemi-2000
Copy link

Hello, you may try this alternative package that I developed which has a browser-based version to do away with the quirks and bugs of PurgeCSS: https: https://www.npmjs.com/package/rmrf-css

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests