Rise nav
Links in a pill bar: under the pointer a fill rises through a link while its label rolls over, a dot glides under the current page, and narrow screens get a menu button.
- enhancer
- navigation
- menu
- hover
- links
- mobile
- since 0.2
Background Studio: tune it below, then copy the code
Your system asks for reduced motion: the demo shows its final state and nothing moves.
Live demo
Rise nav example
Code
It follows the controls above: change an option and the code changes with it.
<link rel="stylesheet" href="/axi0/motion/motion.css?v=6">
<script src="/axi0/motion/motion.js?v=10" defer></script>
<nav data-motion="rise-nav" aria-label="Main">
<a href="#" data-logo aria-label="Home page"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="7"/><circle cx="12" cy="12" r="1.6" fill="currentColor"/></svg></a>
<a href="#" aria-current="page">Home</a>
<a href="#">Work</a>
<a href="#">Studio</a>
<a href="#">Journal</a>
<a href="#">Contact</a>
</nav>
import { RiseNav } from "./motion/react/RiseNav";
<RiseNav>Your content</RiseNav>
<script setup lang="ts">
import RiseNav from "./motion/vue/RiseNav.vue";
</script>
<template>
<RiseNav>Your content</RiseNav>
</template>
const el = document.querySelector("#title");
el.dataset.motion = "rise-nav";
The wrappers: RiseNav.tsx (React, TypeScript) and RiseNav.vue (Vue). Both render the same attributes as the HTML; the loader does the rest.
Options
| Attribute | Default | What it does |
|---|---|---|
data-motion-fill | auto | the color that rises through a link (empty: the accent) |
data-motion-collapse | 560 | below this page width the links fold into a menu button |
data-motion-menu | Menu | the menu button's name |
Accessibility
- It stays a nav landmark of ordinary links: Tab reaches each one, Enter follows it. aria-current="page" marks the current link; the glide dot only shows it. - Each label is written twice for the roll; the copy is hidden from screen readers, so every link is read once. - The fill and the roll follow keyboard focus too. - Below the collapse width a Menu button (aria-expanded, aria-controls) shows and hides the links; Escape closes them and puts focus back on the button, and so does a click outside. - Without JavaScript it is a plain row of links. Reduced motion shows every state at once, with no movement, and stops anything that would move on its own. Frame loops and CSS animations pause off screen and in hidden tabs. Only transform, opacity and paint animate, so nothing around it moves.
Size
rise-nav.js is 2.2 KB gzip, with components-kit.js 3.9 KB it needs. A page loads the loader (2.7 KB) and core.js (1.4 KB) once, whatever it uses.