Description
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):
- Maintains Security: Explicit opt-outs make it clear when pure modules are being bypassed
- Better DX: Developers don't need hacky workarounds for legitimate use cases
- Clear Intent: Code reviews can easily identify and validate non-pure usage
- 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