persist()
declarationsince 0.9.0experimentalrequires runtimeKeeps a state across reloads, in localStorage or, for the tab’s session, in sessionStorage, under a key you choose.
On this page · 10 sections+−
Syntax
--<state>: state(<initial>, persist("<key>" [, local | session]));registry syntax: --state: state(initial, persist("key" [, local | session]))
Parameters
- keyquoted
<string>required - 1 to 64 characters from
A–Z,a–z,0–9,_,.,:and-. Stored asrcss:<key>. - storage
localorsessionoptional - Default
local(localStorage).sessionuses sessionStorage.
Effect
No value. The state starts from its stored value, and later changes are stored.
Example
.prefs { --theme: state(light, persist("docs-theme"));}.prefs .theme:on(click) { --theme: cycle(light, dark);}.prefs .name { content: var(--theme);}.prefs:when(--theme == dark) { background: #1c1c1e; color: #f2f2f2;}state()Function · hover any red tokenMakes each matching element the owner of an independent state with an initial value.Reference →
Resultnative button
waiting for interaction
Correct and incorrect usage
correctA counter kept for the tab’s session, shared by two widgets
count.cssreactive
.pc { --n: state(0, persist("visits", session)); }.pc .inc:on(click) { --n: increment(1); }.pc .v { content: var(--n); }Every .pc on the page owns its own state, but they share the key, so a click in one updates the others.
incorrectA key with a space
theme.cssreactive
.prefs { --theme: state(light, persist("my theme")); }A compile error: keys use letters, digits and _ . : - only.
Behavior
- Experimental: storage policies such as Safari’s private mode and partitioned storage in iframes still need manual testing.
- In this site’s previews storage is unavailable, because they run in sandboxed iframes. The example works but starts over on reload. Copy it into a page of your own to see the value kept.
- Initialization. A valid stored value first; otherwise the DOM source of a
bind()(a valid attribute, or a control the user or the browser already edited); otherwise the declared initial value. The result is then written to the bound attribute or control. - Typed validation. Values are stored as JSON,
{"t":type,"v":value,"u":unit}. A stored value is used only if it fits the declared type, and keywords must be identifiers or#hexcolors, so stored text can never becomeurl()or extra declarations. Anything else is ignored, with one note. - Coalesced writes. At most one
setItemper key every 250 ms, and the last value always wins. Pending writes are flushed when the page is hidden (visibilitychange) or left (pagehide). A drag that updates a persisted position writes about 4 times per second. - Shared keys. States with the same key and storage share one value in the page. With localStorage, other tabs of the same origin follow through the
storageevent; applying such a change never writes back. - Failures. Unavailable storage (sandboxed iframes, some privacy modes), quota errors and unreadable values give one note. The state keeps working, without persistence.
- With
bind(), in either order, each at most once:state("", bind(value), persist("name")).
Supported contexts
- A modifier of
state(), whereverstate()is allowed. A custom bundle needs thepersistfeature.
Limitations
- Kept per browser profile and origin. It never synchronizes across devices or browsers.
- A state bound to a password, one-time-code or payment field is never persisted (one diagnostic).
- The library never clears storage: a key stays after its rule is removed. Remove it with
localStorage.removeItem("rcss:<key>"). - Only declared states are stored. Nothing is read from the DOM on its own.
Examples
- Persistent preference · API examples, runs the real runtime
Related
Experimental · syntax may change between minor versions