NS Design System
v3.0.0 · 257 tokens

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 &amp; 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 &amp; 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 &amp; 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