Progressive enhancement
Behavior discovery uses only data-mr-*. Presentation classes are not runtime identity and the CSS remains useful when the JavaScript bundle is omitted.
Native and ARIA state first
- Current-page links use
aria-current="page". - Tabs use
aria-selected, rovingtabindex, andhiddenpanels. - The shell toggle uses
aria-expandedandaria-controls. - Search uses native modal
<dialog>. - Layer discovery observes native
<dialog>/Popover state instead of duplicating it. - Tooltip previews use native hint popovers; pinned tooltips become normal non-modal Popover Layers.
- Layer
ask()treats native/ordinary close as dismissal; semantic accepted values remain a JavaScript workflow concern rather than HTML state. - Optional remote Layer navigation enhances real
href/actiontargets; without JavaScript those links/forms still navigate or submit normally. Enhanced same-origin multipart forms stay inside the Layer workflow instead of navigating away solely because they contain a file.
Tabs
<nav class="mr-nav-tabs" role="tablist" aria-label="Example tabs">
<button data-mr-tab="one" data-mr-tabs-group="demo">One</button>
<button data-mr-tab="two" data-mr-tabs-group="demo">Two</button>
</nav>
<section data-mr-panel="one" data-mr-tabs-group="demo" data-mr-tabs-default>First panel</section>
<section data-mr-panel="two" data-mr-tabs-group="demo">Second panel</section>
No-JavaScript baseline
| Enhancement | Without JavaScript |
|---|---|
| Copyable snippet | Code stays readable. |
| Clickable-list filter | The complete list remains visible. |
| Resettable file input | The native file input remains usable. |
| Single-page tabs | All authored panels remain visible. |
| Navigation shell | Navigation content remains reachable. |
| Search | Provide a normal form/link fallback when no-JS search is required. |
| Tooltip explanation | Essential meaning remains in normal page content; tooltip text is supplementary only. |
| Remote Layer subinteraction | The same URL is a complete standalone page, and opted-in forms submit through their real action/method. Multipart forms use native browser submission before enhancement and browser-created FormData after enhancement. |
SSR and repeated initialization
import { initMarkupRefineBehaviors } from "markup-refine-lib/behaviors";
initMarkupRefineBehaviors(container);The initializer is SSR-safe and idempotent. It registers [data-mr-layer] surfaces and [data-mr-tooltip] triggers in the supplied root.
Remote navigation is deliberately excluded. Opt into initLayerNavigation() from markup-refine-lib/layer-navigation only where HTTP enhancement is wanted.
Stable Layer degradation contract
Layer enhancement is capability-gated. Failure at a higher capability level must leave the authored lower-capability task usable rather than hiding it behind partially prepared UI. Markup Refine does not provide a generic “enhanced” marker that authors must style around, and it never auto-promotes an unsupported popover into a modal.
See the Stable Layer API for the permanent degradation matrix covering no JavaScript, no CSS, unsupported native APIs, initialization failure, late initialization, and remote request failure.