57Account menu
The signed-in end of the navbar: an avatar trigger opening a panel that states WHO you are before it offers anything to do. Signed out, the same slot is two buttons — quiet sign-in beside the one solid blue thing on the page.
Use it for
- Every signed-in surface — the panel is where account, progress and sign-out live
- Ghost Members: wrap it in {{#if @member}} and the signed-out pair in the {{else}}
Not for
- A bare avatar with no name anywhere — an avatar is not an accessible name
- Burying sign-out three levels deep; it is the one item people go looking for
- Duplicating the whole site map inside it — that is the navbar's job
Signed out
Sign in is quiet, sign up is THE primary. Two primaries here is the most common navbar mistake in the wild — it makes the user choose between two equally loud things at the exact moment they know least.
markup
<div class="ns-topnav__auth">
<a class="ns-btn ns-btn--quiet ns-btn--sm" href="#">Sign in</a>
<a class="ns-btn ns-btn--primary ns-btn--sm" href="#">Start learning</a>
</div>Signed in
Live: click the avatar. Identity, then progress, then actions, then sign out behind a hairline — the order is the order people look for them.
markup
<nav class="ns-topnav" aria-label="Account menu example">
<a class="ns-topnav__brand" href="#"><img src="../assets/logo/favicon.svg" alt=""><span class="ns-topnav__brand-name">Namaste Salesforce</span></a>
<div class="ns-topnav__actions">
<div class="ns-usermenu">
<button type="button" class="ns-usermenu__trigger" data-ns-menu aria-expanded="false" aria-controls="doc-account" aria-label="Account menu for Aarti Kulkarni">
<span class="ns-avatar ns-avatar--sm" aria-hidden="true">AK</span>
<span class="ns-usermenu__name">Aarti K.</span>
</button>
<div class="ns-usermenu__panel" id="doc-account">
<div class="ns-usermenu__head">
<span class="ns-avatar" aria-hidden="true">AK</span>
<span class="ns-usermenu__identity">
<span class="ns-usermenu__fullname">Aarti Kulkarni</span>
<span class="ns-usermenu__email">aarti@example.com</span>
</span>
<span class="ns-usermenu__plan">Pro</span>
</div>
<div class="ns-usermenu__progress">
<span class="ns-usermenu__progress-label"><span>Admin trail</span><span>64%</span></span>
<progress class="ns-progress" value="64" max="100" aria-label="Admin trail progress">64%</progress>
</div>
<hr class="ns-menu__sep">
<a class="ns-menu__item" href="#"><i class="ph ph-user" aria-hidden="true"></i> My learning</a>
<a class="ns-menu__item" href="#"><i class="ph ph-bookmark-simple" aria-hidden="true"></i> Bookmarks</a>
<a class="ns-menu__item" href="#"><i class="ph ph-seal-check" aria-hidden="true"></i> Certificates</a>
<hr class="ns-menu__sep">
<a class="ns-menu__item" href="#"><i class="ph ph-gear" aria-hidden="true"></i> Settings</a>
<a class="ns-menu__item" href="#"><i class="ph ph-question" aria-hidden="true"></i> Help</a>
<hr class="ns-menu__sep">
<button type="button" class="ns-menu__item ns-menu__item--danger"><i class="ph ph-arrow-up-right" aria-hidden="true"></i> Sign out</button>
</div>
</div>
</div>
</nav>Triggers
Avatar only for a dense app bar; avatar plus short name where there is room — the name is what tells a shared-computer household which account they are about to post from. Photo, initials and a progress ring all fit the same disc (see Avatar).
markup
<div class="ns-usermenu">
<button type="button" class="ns-usermenu__trigger" aria-expanded="false" aria-label="Account menu for Aarti Kulkarni">
<span class="ns-avatar ns-avatar--sm" aria-hidden="true">AK</span>
</button>
</div>
<div class="ns-usermenu">
<button type="button" class="ns-usermenu__trigger" aria-expanded="false" aria-label="Account menu for Aarti Kulkarni">
<span class="ns-avatar ns-avatar--sm" aria-hidden="true">AK</span>
<span class="ns-usermenu__name">Aarti K.</span>
</button>
</div>
<div class="ns-usermenu">
<button type="button" class="ns-usermenu__trigger" aria-expanded="true" aria-label="Account menu for Ravi Sharma — expanded">
<span class="ns-avatar-ring" style="--p:64"><span class="ns-avatar ns-avatar--sm" aria-hidden="true">RS</span></span>
<span class="ns-usermenu__name">Ravi S.</span>
</button>
</div>Accessibility contract
- The trigger names the account: aria-label="Account menu for Aarti Kulkarni", because the initials disc is aria-hidden
- The identity block is real text, so a screen reader reads the account before the actions
- Sign out is a <button> — it changes state, it does not navigate
- Below lg the name is hidden visually; the accessible name on the trigger keeps it announced