-
-
Notifications
You must be signed in to change notification settings - Fork 285
Description
Description
Allow a single condition to generate multiple independent CSS blocks, each wrapped in its own at-rule. This would enable defining hover-for-desktop + active-for-touch in one condition.
Problem Statement/Justification
When building responsive interactions, you often want hover feedback on devices with a pointer and active/press feedback on touch devices. This requires two separate @media blocks:
@media (hover: hover) { .el:hover { background: red; } }
@media (hover: none) { .el:active { background: red; } }Currently, conditions only support [atRule, selector] pairs which nest into a single block. There's no way to define a condition that produces two independent blocks. We're forced to either:
- Define two separate conditions (
_hoverHover+_touchActive) and duplicate styles - Create per-property utilities with
transform()that hardcode the media queries
Both workarounds scale poorly and lose the ergonomics of the condition system.
Proposed Solution or API
A new array-of-arrays syntax for conditions that generates multiple independent CSS blocks:
conditions: {
extend: {
hoverActive: [
['@media (hover: hover)', '&:is(:hover, [data-hover])'],
['@media (hover: none)', '&:is(:active, [data-active])'],
],
},
}Usage stays the same:
css({ _hoverActive: { bg: 'red' } })Generated CSS:
@media (hover: hover) { .selector:is(:hover, [data-hover]) { background: red; } }
@media (hover: none) { .selector:is(:active, [data-active]) { background: red; } }This is backward compatible — parseCondition already handles nested arrays as type: "mixed". The change would be to detect Array<[atRule, selector]> and emit separate rule blocks instead of nesting them.
Alternatives
- Per-property custom utilities with
transform()— works but requires a separate utility for each CSS property (bg, color, opacity, etc.) - Helper function that spreads styles into both conditions — works but TypeScript struggles with complex Panda style types
- Using a single combined selector
&:is(:hover, :active)— loses the media query isolation, causing ghost hover on touch devices
Additional Information
No response