Skip to content

opt-out mechanism for unavoidable global CSS scenarios #78

Closed
@jantimon

Description

@jantimon

postcss-modules-local-by-default enforces pure CSS Modules by requiring all styles to be locally scoped, with :global only being allowed within :local wrappers. Generally this is exactly the desired behavior, but there are several cases where it is hardly possible to use pure CSS Modules:

1. third-party integration scenarios

when integrating third-party services that inject their own DOM nodes with React Portals there are sometimes cases where we need to style elements outside of our component tree:

/* These elements are injected directly into body by third-party scripts */
#stripe-modal-backdrop {
  background: rgba(0, 0, 0, 0.5);
}

2. new platform apis

The View Transitions API is a good example of where pure CSS Modules are very hard to use:

::view-transition-group(my-custom-name) {
  animation-timing-function: ease-in-out;
}

3. global animations

Right now it is not possible to target global animations e.g.:

animation-name: fade-out

Solution in similar tools

One tool which limits the usage of javascript is typescript - but it allows disabling this for edge cases e.g.:

// @ts-ignore
// @ts-expect-error

Proposal:

We could add something similar to css modules to allow explicitly opting-out

/* @cssmodules-pure: false */
::view-transition-group(modal) {
  animation-timing-function: ease-in-out;
}

/* Re-enable pure mode */
/* @cssmodules-pure: true */
.component {
  color: blue;
}

Alternative syntax options could include:

/* @cssmodules-disable-pure */
/* @cssmodules-enable-pure */

/* or */

/* @cssmodules-impure-start */
/* @cssmodules-impure-end */

I believe this would keep the current behaviour of postcss-modules-local-by-default as it is today and also offer an escape hatch in very special edge case scenarios. The advantages might be obvious (because of the learnings from typescript or one of these other tools):

  1. Maintains Security: Explicit opt-outs make it clear when pure modules are being bypassed
  2. Better DX: Developers don't need hacky workarounds for legitimate use cases
  3. Clear Intent: Code reviews can easily identify and validate non-pure usage
  4. Future Proof: Ready for new web platform features that may require global scope

How would you design such an opt-out?
I can help test different approaches and create a PR once we figure out how to move on

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions