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
feature: add support for adding prefix to CSS to scope down the styling #453
Comments
This problem exists when there is an app with enabled CSS extraction and another app that uses runtime insertion on the same page (example: https://stackblitz.com/edit/stackblitz-starters-6gpxe7), i.e. multi bundle scenario. Basically:
Workaround timeThis is tricky, there are two ways:
The second option is more realistic as we just need to modify CSS rules. This can be done with createEnhancedRenderer()import { createDOMRenderer } from '@griffel/core';
import type { CreateDOMRendererOptions, GriffelRenderer } from '@griffel/core';
import { serialize, compile, stringify } from 'stylis';
const ENHANCE_CACHE: Record<string, string> = {};
export function enhanceCSSRule(className: string, cssRule: string) {
if (!ENHANCE_CACHE[className + cssRule]) {
ENHANCE_CACHE[className + cssRule] = serialize(compile(`.${className} {${cssRule} }`), stringify);
}
return ENHANCE_CACHE[className + cssRule];
}
export const createEnhancedRenderer = (
document: Document | undefined,
options: CreateDOMRendererOptions & { specificityClassName: string },
): GriffelRenderer => {
const { specificityClassName } = options;
const originalRenderer = createDOMRenderer(document, options);
return {
...originalRenderer,
insertCSSRules(cssRules) {
const rules = Object.fromEntries(
Object.entries(cssRules).map(([bucketName, cssRulesInBucket]) => {
return [
bucketName,
cssRulesInBucket.map(cssEntry => {
if (typeof cssEntry === 'string') {
return enhanceCSSRule(specificityClassName, cssEntry);
}
return [enhanceCSSRule(specificityClassName, cssEntry[0]), cssEntry[1]];
}),
];
}),
);
originalRenderer.insertCSSRules(rules);
},
};
}; Then it could be used like that: const renderer = createEnhancedRenderer(document, {
specificityClassName: 'foo',
// ❗ This is mandatory, runtime styles should be inserted before CSS stylesheet
insertionPoint: document.head.firstChild,
});
<RendererProvider renderer={renderer}>
<div className="foo">{/* children */}</div>
</RendererProvider> All together: https://stackblitz.com/edit/vitejs-vite-d11ccd Proper solutionWe should stop compiling styles on library styles i.e. Fluent should ship not optimized styles, so we can process them in runtime/build time. This requires wider discussion as then by default, Fluent will become slower and will require AOT processing. After that, we can implement the option mentioned in this feature request & consider API for processors/plugins. |
We have applications overlap in one page.
Since the hashed className .fqdk4by may both existing in griffel.css and data-make-styles-bucket. They may cause global pollution or something else. So we need to add prefix for className to make CSS scoped.
Maybe solution like selectorPrefix https://fela.js.org/docs/latest/advanced/renderer-configuration
The text was updated successfully, but these errors were encountered: