Other State
Overview
Other state modifiers let you apply utility styles conditionally based on miscellaneous element states. They target elements that are open (like <details> and popovers) or inert (non-interactive), generating variant utility classes for these specific conditions.
Why Use Other State Modifiers?
Other state modifiers help you:
- Style disclosure widgets: Apply styles to open
<details>elements and popovers - Handle inert state: Style elements that are non-interactive due to the
inertattribute - Build accessible patterns: Create visual feedback for native HTML patterns like disclosure and popover
useOpenModifier
The useOpenModifier() function creates a modifier that applies styles to elements that are in an open state. This includes <details> elements with the open attribute and elements using the Popover API.
import { styleframe } from "styleframe";
import { useRotateUtility, useDisplayUtility, useOpacityUtility } from "@styleframe/theme";
import { useOpenModifier } from "@styleframe/theme";
const s = styleframe();
const open = useOpenModifier(s);
useRotateUtility(s, {
90: '90deg',
}, [open]);
useOpacityUtility(s, {
100: '1',
}, [open]);
export default s;
._rotate\:90 { rotate: 90deg; }
._opacity\:100 { opacity: 1; }
._open\:rotate\:90 {
&:is([open], :popover-open) { rotate: 90deg; }
}
._open\:opacity\:100 {
&:is([open], :popover-open) { opacity: 1; }
}
<!-- Rotate icon when details is open -->
<details class="_open:rotate:90">
<summary>Click to expand</summary>
<p>Expanded content here.</p>
</details>
<!-- Style popover when open -->
<div popover class="_opacity:100 _open:opacity:100">
Popover content
</div>
CSS Selector
| Modifier Name | CSS Selector |
|---|---|
open | &:is([open], :popover-open) |
open modifier uses :is([open], :popover-open) to match both the <details> element's open attribute and the Popover API's :popover-open pseudo-class, giving you a single modifier for both patterns.useInertModifier
The useInertModifier() function creates a modifier that applies styles to inert elements and their descendants. The inert HTML attribute makes an element and all its descendants non-interactive and invisible to assistive technology.
import { styleframe } from "styleframe";
import { useOpacityUtility, usePointerEventsUtility } from "@styleframe/theme";
import { useInertModifier } from "@styleframe/theme";
const s = styleframe();
const inert = useInertModifier(s);
useOpacityUtility(s, {
50: '0.5',
}, [inert]);
usePointerEventsUtility(s, {
none: 'none',
}, [inert]);
export default s;
._opacity\:50 { opacity: 0.5; }
._pointer-events\:none { pointer-events: none; }
._inert\:opacity\:50 {
&:is([inert], [inert] *) { opacity: 0.5; }
}
._inert\:pointer-events\:none {
&:is([inert], [inert] *) { pointer-events: none; }
}
<!-- Dim and disable interaction for inert content -->
<div inert class="_inert:opacity:50 _inert:pointer-events:none">
<button>This button is non-interactive</button>
<a href="#">This link is non-interactive</a>
</div>
CSS Selector
| Modifier Name | CSS Selector |
|---|---|
inert | &:is([inert], [inert] *) |
inert modifier targets both the inert element itself and all its descendants using &:is([inert], [inert] *). This ensures that styles are applied consistently throughout the entire inert subtree.useOtherStateModifiers
The useOtherStateModifiers() function registers all other state modifiers at once and returns them as a destructurable object.
Returned Modifiers
| Key | Modifier Name | CSS Selector |
|---|---|---|
open | open | &:is([open], :popover-open) |
inert | inert | &:is([inert], [inert] *) |
Examples
Animated Details Element
import { styleframe } from "styleframe";
import { useRotateUtility, useTransitionDurationUtility } from "@styleframe/theme";
import { useOpenModifier, useMotionSafeModifier } from "@styleframe/theme";
const s = styleframe();
const open = useOpenModifier(s);
const motionSafe = useMotionSafeModifier(s);
useRotateUtility(s, {
0: '0deg',
90: '90deg',
}, [open]);
useTransitionDurationUtility(s, {
200: '200ms',
}, [motionSafe]);
export default s;
<details>
<summary>
<span class="_rotate:0 _open:rotate:90 _motion-safe:transition-duration:200">
▶
</span>
Toggle section
</summary>
<p>Section content revealed when opened.</p>
</details>
Modal with Inert Background
import { styleframe } from "styleframe";
import { useOpacityUtility, useBlurUtility } from "@styleframe/theme";
import { useInertModifier } from "@styleframe/theme";
const s = styleframe();
const inert = useInertModifier(s);
useOpacityUtility(s, {
50: '0.5',
}, [inert]);
useBlurUtility(s, {
sm: '4px',
}, [inert]);
export default s;
<!-- Background content becomes inert when modal is open -->
<main inert class="_inert:opacity:50 _inert:blur:sm">
<p>Page content (disabled while modal is open)</p>
</main>
<dialog open>
<p>Modal content (interactive)</p>
</dialog>
Best Practices
- Use
openfor native disclosure patterns: Style<details>and popover elements with theopenmodifier instead of JavaScript class toggling - Use
inertfor background content: When showing modals or dialogs, applyinertto background content for both accessibility and visual dimming - Combine with motion modifiers: Use
motion-safewithopentransitions for accessible animated disclosure widgets - Test popover support: The
:popover-openpseudo-class is a newer API; verify browser support for your target audience
FAQ
open modifier uses &:is([open], :popover-open) which matches both the <details> element's open attribute and the Popover API's :popover-open pseudo-class. This makes it work seamlessly with both patterns.inert attribute affects the entire subtree, making all descendants non-interactive. The modifier selector &:is([inert], [inert] *) matches both the inert element and its children, ensuring consistent styling throughout the disabled region.[open, hover] generates _open:property:value, _hover:property:value, and _open:hover:property:value. This allows for different hover effects when an element is open vs closed.Directional
Create directional modifiers for targeting elements based on text direction (RTL/LTR) with full type safety.
Styleframe Documentation Site
This directory contains the source content for the Styleframe documentation site. It uses Nuxt Content with Markdown files organized into numbered sections. An AI agent working here should understand the site structure, formatting conventions, and content patterns to write or modify documentation pages that are indistinguishable from existing ones.