Theming v4: Unable to use CSS layers with tailwind css as primevue injects a declaration of its own layer at the top of the HTML head breaking the `@layer` orders
Describe the bug
When using the styled option with cssLayers: true, primevue injects a @layer primeui declaration at the top of the HTML section:
<style type="text/css" data-primevue-style-id="layer-order">@layer primeui</style>
This breaks the usage with tailwind css (as described in the docs) as it declares @layer primeui as first so a later added statement like
@layer tailwind-base, primeui, tailwind-utilities;
does nothing as this does not change the order of the layers as @layer primeui was already declared before.
Reproducer
not possible as native plugins cannot be used there
PrimeVue version
4.0.0-beta.1
Vue version
3.x
Language
TypeScript
Build / Runtime
Vite
Browser(s)
No response
Steps to reproduce the behavior
- Enable the
cssLayeroption in the theme configuration
app.use(PrimeVue, {
// Default theme configuration
theme: {
base: PrimeOne,
preset: Aura,
options: {
cssLayer: true
}
}
});
- Use a tailwind config like the following which is similar to the docs (this is just using tailwind v4 alpha AND is using both layer names
primeuiandprimevuejust in case - see #5536 ):
@layer tailwind-base, primeui, primevue, tailwind-utilities;
@import 'tailwindcss/preflight' layer(tailwind-base);
@import 'tailwindcss/utilities' layer(tailwind-utilities);
- Have a look at the browser inspector for a
Buttonelement - primevue styles are being overwritten bytailwind-base(e.g. Buttons have no background-color).
Expected behavior
The layer declaration
<style type="text/css" data-primevue-style-id="layer-order">@layer primeui</style>
does not get injected at the top of the HTML head so I can declare the layer order by myself using
@layer tailwind-base, primeui, primevue, tailwind-utilities;
so I can use tailwind css and primevue together.
Could you maybe add your own stylesheet which just defines the layer order and load it in the main.js? Afaik it will be inserted before any primevue css, so the layer order should be respected.
Could you maybe add your own stylesheet which just defines the layer order and load it in the main.js? Afaik it will be inserted before any primevue css, so the layer order should be respected.
@m-meier no, that's actually not working. As written in the issue the html code
<style type="text/css" data-primevue-style-id="layer-order">@layer primeui</style>
gets injected by primevue at the top of the HTML head - before any other code even if I import my own css declaring the layers in line 1 of the main.ts.
@sceee I'm sorry, I didn't read it correctly. You are of course right.
However I have an undocumented solution from the source code. Since it's undocumented I don't know if this is a permanent solution, but maybe it will do as a workaround for now. Instead of just "true" you can also specify an object as cssLayer parameter which allows you to customize the name and more importantly the order that is inserted at the top:
@m-meier oh, nice, thank you very much, this seems to work 👏
I actually found some hints that the name might be configurable, but it was not reflected in the docs.
So maybe - if that's the official way - it should be updated in the docs.
@m-meier I think that injecting css top level in the head is not a good practice, since it opens a lot of topics. E.g. usually we don't want anything set before meta charset and title in the head.
This is now reflected in the docs since v4.0.0-rc1: https://primevue.org/theming/styled/#options
options: {
cssLayer: {
name: 'primevue',
order: 'tailwind-base, primevue, tailwind-utilities'
}
}