Barefoot CSS v7.0

States & Events

The state machine: one data-state value, painted by family, with a defined precedence when several conditions hold. Plus the bf:* event contract — every opt-in module reports what it did, so a page can extend it instead of forking it.

Back to the conformance demo · playground · states docs · events docs.

The families

Every documented data-state value, painted by its family. The region's own text is the real status; the paint only reinforces it.

loading

Nothing has arrived yet.

refreshing

Content held while it reloads.

optimistic

Saved locally — server confirmation pending.

empty

Nothing here yet.

stale

Shown, but known to be outdated.

partial

An incomplete set, not an empty one.

fresh

Updated a moment ago.

confirmed

The optimistic change stuck.

full

Deliberately unpainted — nothing to flag.

Don't show empty while loading

A region still pending never paints the empty surface. Toggle the busy signal on this empty region — aria-busy="true" wins, because "nothing here" about data that has not arrived is a lie.

No projects yet

Projects load on open — this panel stays pending until they land.

.bf-empty-state — the panel is the space

A decorative glyph, a heading, an explanation, and the way out — grid-centered, filling the parent's remaining space. The dashed frame below is the parent's definite block size; the panel inside takes all of it.

No projects yet

Create your first project, or import one from a template.

Markup

<div style="display: grid; block-size: 22rem"> <div class="bf-empty-state"> <span aria-hidden="true">◌</span> <h3>No projects yet</h3> <p>Create your first project, or import one from a template.</p> <button type="button" data-variant="primary">New project</button> </div> </div>

The bf:* event contract

Act with any surface below — switch the theme, change the tab, sort the table, remove a chip, dismiss the alert, open the toast. Every module reports what it did as a bubbling CustomEvent; the log is one document listener.

Production deploys are locked behind a manual approval.

Staging rebuilds on every push to main.

Preview environments expire after 48 hours.

Click a header to sort — bf:sort reports the column and direction.
api12
web3
worker5

Stack

css js a11y

Deploy succeeded.

Event log

    Listener

    document.addEventListener( "bf:themechange" /* … */, (e) => log(e.type, e.detail) );