tailwind-cssviteweb-componentlitunocss

Undefined CSS custom properties when using UnoCSS Wind4 with Lit components


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?


Solution

  • 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. 🫤