I've setup a prototype demo project using Lit to build web components. I'm using unocss with the wind4 TailwindCSS-preset. I am having trouble understanding why so many CSS custom properties are undefined, and is the expectation that I need to define them all?
package.json
{
"name": "unocss-lit-test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "vite",
"build": "vite build",
"watch": "vite build --watch",
"preview": "vite preview",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@unocss/preset-wind4": "^66.1.2",
"lit": "^3.3.0",
"typescript": "^5.8.3",
"unocss": "^66.1.2"
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test</title>
<script type="module" src="./index.js"></script>
<style>
/* I'm expected to define all of these these manually? */
:root {
--un-bg-opacity: 100%;
--un-text-opacity: 100%;
--un-border-opacity: 100%;
}
</style>
</head>
<body>
<my-test-component>my component</my-test-component>
</body>
</html>
index.ts
import { LitElement, css, html } from "lit";
import { customElement } from "lit/decorators.js";
@customElement("my-test-component")
export class SelectDropdown extends LitElement {
static styles = [
css`
@unocss-placeholder;
`,
];
gradientTest = "bg-linear-to-r from-blue-500 to-red-200 m-4 p-10 border-6";
colorTest =
"bg-blue-500 m-4 border text-blue-200 p-10 border-red-200 border-6";
render() {
return html`<div>
<div class="${this.colorTest}">${this.colorTest}</div>
<div class="${this.gradientTest}">${this.gradientTest}</div>
</div>`;
}
}
unocss.config.ts
import { defineConfig } from "unocss";
import { presetAttributify } from "unocss";
import presetWind4 from "@unocss/preset-wind4";
export default defineConfig({
presets: [presetWind4({}), presetAttributify()],
});
vite.config.ts
import { defineConfig } from "vite";
import UnoCSS from "unocss/vite";
export default defineConfig({
plugins: [
UnoCSS({
mode: "shadow-dom",
inspector: true,
}),
],
});
The classes are applying the right styles - padding, margin, and other TailwindCSS utility classes all work fine, but all the colors seem to be missing some variables. Nearly all vars here for example are undefined:
.to-red-200 {
--un-gradient-to: color-mix(in oklab, var(--colors-red-200) var(--un-to-opacity), transparent);
--un-gradient-stops: var(--un-gradient-via-stops, var(--un-gradient-position), var(--un-gradient-from) var(--un-gradient-from-position), var(--un-gradient-to) var(--un-gradient-to-position));
--un-gradient-to-position is not defined
--un-gradient-to is not defined
--un-gradient-position is not defined
Am I expected to define these myself? I assumed the plugin should handle that out of the box.
:root {
--un-bg-opacity: 100%;
--un-text-opacity: 100%;
--un-border-opacity: 100%;
/* ... */
}
What am I missing here?
After painstakingly finding the related issues, I finally found them:
There's a discussion for UnoCSS here: https://github.com/unocss/unocss/discussions/4604
Which linked to an issue in Tailwind here: https://github.com/tailwindlabs/tailwindcss/issues/15005
Tailwind v4 uses @property to define defaults for custom properties. At the moment, shadow roots do not support @property. It used to be explicitly denied in the spec, but it looks like there's talk on adding it: w3c/css-houdini-drafts#1085
There are a few workarounds shown in the issues.
For me, I guess I'll just manually add the preflight-only style globally. 🫤