Composable utilities declare custom property defaults in Preset.property_defaults, collected and emitted as a universal selector block (*, ::after, ::before, …) by CompiledConfig::compile(). This block is always emitted in full, even when none of the associated utilities match scanned HTML — no tree-shaking.
Tailwind CSS v4 returns @property declarations inline from each utility handler (via atRoot()), hoists and deduplicates them. Defaults are only emitted for properties actually referenced by matched utilities.
Current state
Preset.property_defaults: Vec<CssEntry> is collected at compile time, emitted unconditionally. CssEntries returned by rules has no concept of hoisted/root declarations.
Direction
Extend CssEntries (or introduce a wrapper) so rules can return optional root-level declarations alongside regular property–value pairs. On match, root declarations are collected, deduplicated, and hoisted as @property rules (inherits: false) — replacing the universal selector approach. property_defaults is then removed from Preset.
Not in scope: full @layer ordering or @property syntax validation.
Composable utilities declare custom property defaults in
Preset.property_defaults, collected and emitted as a universal selector block (*, ::after, ::before, …) byCompiledConfig::compile(). This block is always emitted in full, even when none of the associated utilities match scanned HTML — no tree-shaking.Tailwind CSS v4 returns
@propertydeclarations inline from each utility handler (viaatRoot()), hoists and deduplicates them. Defaults are only emitted for properties actually referenced by matched utilities.Current state
Preset.property_defaults: Vec<CssEntry>is collected at compile time, emitted unconditionally.CssEntriesreturned by rules has no concept of hoisted/root declarations.Direction
Extend
CssEntries(or introduce a wrapper) so rules can return optional root-level declarations alongside regular property–value pairs. On match, root declarations are collected, deduplicated, and hoisted as@propertyrules (inherits: false) — replacing the universal selector approach.property_defaultsis then removed fromPreset.Not in scope: full
@layerordering or@propertysyntax validation.