84Lesson navigation
Prev / next by NAME, and by as little else as possible. An arrow pair with no titles makes the learner click to find out where they are going — so the name is the control and the arrow is the decoration. The default draws nothing around them: no box, no fill, no still, and the only motion is the arrow travelling two pixels in the direction it points.
Use it for
- The end of every lesson, video or article
- --split at the end of a video, where there is exactly one thing to do next
- --minimal in a rail or a dense column
- --cards at the end of a COURSE, where the next thing is a decision
- --sticky on a long article lesson, so the way out is always one reach away
Not for
- Inside the player's stage — the player has its own bar
- Paging a table or a search result — that is Pagination
Minimal — the default
An arrow, the direction in mono, the name. No box, no fill, no still. This replaced two bordered cards carrying a label, a title and a 16:9 thumbnail each, with a progress row between them: five objects competing at the exact moment the reader wants one thing.
markup
<nav class="ns-lesson-nav" aria-label="Lesson navigation" style="inline-size:100%">
<a class="ns-lesson-nav__btn" href="#0">
<i class="ph ph-arrow-left ns-lesson-nav__arrow" aria-hidden="true"></i>
<span class="ns-lesson-nav__dir">Previous</span>
<span class="ns-lesson-nav__name">Objects & fields</span>
</a>
<div class="ns-progress-row">
<progress class="ns-progress" value="8" max="24" aria-label="8 of 24 lessons complete"></progress>
<span class="ns-progress-row__value">8/24</span>
</div>
<a class="ns-lesson-nav__btn ns-lesson-nav__btn--next" href="#0">
<span class="ns-lesson-nav__dir">Next</span>
<span class="ns-lesson-nav__name">Flow builder basics</span>
<i class="ph ph-arrow-right ns-lesson-nav__arrow" aria-hidden="true"></i>
</a>
</nav>Split — one obvious next action
At the end of a video there is exactly one thing to do, so it looks like one thing to do: prev stays a quiet link, next becomes the solid control. This is the shape the player uses.
markup
<nav class="ns-lesson-nav ns-lesson-nav--split" aria-label="Lesson navigation" style="inline-size:100%">
<a class="ns-lesson-nav__btn" href="#0">
<i class="ph ph-arrow-left ns-lesson-nav__arrow" aria-hidden="true"></i>
<span class="ns-lesson-nav__dir">Previous</span>
<span class="ns-lesson-nav__name">Objects & fields</span>
</a>
<a class="ns-lesson-nav__up" href="#0"><i class="ph ph-list" aria-hidden="true"></i> All 24 lessons</a>
<a class="ns-lesson-nav__btn ns-lesson-nav__btn--next" href="#0">
<span class="ns-lesson-nav__dir">Next</span>
<span class="ns-lesson-nav__name">Flow builder basics</span>
<i class="ph ph-arrow-right ns-lesson-nav__arrow" aria-hidden="true"></i>
</a>
</nav>Minimal one-line
Names only, no direction labels — for a rail, a dense player column, or an article whose footer is already busy.
markup
<nav class="ns-lesson-nav ns-lesson-nav--minimal" aria-label="Lesson navigation" style="inline-size:100%">
<a class="ns-lesson-nav__btn" href="#0">
<i class="ph ph-arrow-left ns-lesson-nav__arrow" aria-hidden="true"></i>
<span class="ns-lesson-nav__dir">Previous lesson:</span>
<span class="ns-lesson-nav__name">Objects & fields</span>
</a>
<a class="ns-lesson-nav__btn ns-lesson-nav__btn--next" href="#0">
<span class="ns-lesson-nav__dir">Next lesson:</span>
<span class="ns-lesson-nav__name">Flow builder basics</span>
<i class="ph ph-arrow-right ns-lesson-nav__arrow" aria-hidden="true"></i>
</a>
</nav>Locked next, and the way back
The locked control still navigates — to the join page. __up is the way back to the curriculum, which on a phone is the only way back to it.
markup
<nav class="ns-lesson-nav" aria-label="Lesson navigation" style="inline-size:100%">
<a class="ns-lesson-nav__btn" href="#0">
<i class="ph ph-arrow-left ns-lesson-nav__arrow" aria-hidden="true"></i>
<span class="ns-lesson-nav__dir">Previous</span>
<span class="ns-lesson-nav__name">Bulkification, properly</span>
</a>
<a class="ns-lesson-nav__up" href="#0"><i class="ph ph-list" aria-hidden="true"></i> All 24 lessons</a>
<a class="ns-lesson-nav__btn ns-lesson-nav__btn--next" href="#0" data-state="locked">
<span class="ns-lesson-nav__dir">Members only</span>
<span class="ns-lesson-nav__name">Governor limits in practice</span>
<i class="ph ph-lock-simple ns-lesson-nav__arrow" aria-hidden="true"></i>
</a>
</nav>Cards — the end of a course
The boxed pair WITH the still, now opt-in. Correct where the next thing is a decision rather than a continuation: the last lesson, or a course-complete screen.
markup
<nav class="ns-lesson-nav ns-lesson-nav--cards" aria-label="Lesson navigation" style="inline-size:100%">
<a class="ns-lesson-nav__btn" href="#0">
<i class="ph ph-arrow-left ns-lesson-nav__arrow" aria-hidden="true"></i>
<span class="ns-lesson-nav__thumb" aria-hidden="true"><i class="ph ph-video"></i></span>
<span class="ns-lesson-nav__dir">Previous</span>
<span class="ns-lesson-nav__name">Testing and deployment</span>
</a>
<a class="ns-lesson-nav__btn ns-lesson-nav__btn--next" href="#0">
<span class="ns-lesson-nav__dir">Next course</span>
<span class="ns-lesson-nav__name">Bulk-safe Apex patterns</span>
<span class="ns-lesson-nav__thumb ns-ph ns-ph--sm" aria-hidden="true"></span>
<i class="ph ph-arrow-right ns-lesson-nav__arrow" aria-hidden="true"></i>
</a>
</nav>Accessibility contract
- Each control is a link with the lesson's real name in its accessible name — "Next" alone tells a screen-reader user nothing
- A locked next lesson stays a link, to the upgrade page: a dead button at the end of a lesson explains nothing
- The progress element carries the human numbers in its aria-label
- Below 48rem the stills and the progress row are dropped, not shrunk — the two named links ARE the navigation on a phone
- The arrow's 2px travel is the only motion, and it is dropped under prefers-reduced-motion