Connection lost. Reconnecting… attempt 1 of 8
Paused. Your work is held on the server.
Could not reconnect.
This session has expired on the server.
An unhandled error has occurred.
Sedna.UI
v0.17.0 · main

Avatars

tier 2 — classes

Who did something, or what did. An avatar carries an image, initials or an icon — and never the name on its own.

Sizes and fallbacks

Three sizes — .avatar-sm, the default and .avatar-lg — holding an <img>, initials or a Remix Icon, in that order of preference; .avatar--muted is for an actor with no person behind it, and .avatar--viz-1 to .avatar--viz-6 give each person in a group their own hue from the series tokens — set the colour with the class, not a style, or the initials keep the brand ink and vanish on the fill. An avatar is never the only carrier of a name: put the name in text beside it, in an alt, or in a .visually-hidden span.

JW JW JW
AF PN TF JW AF PN
JW Jordan Weiss, assignee
<div class="sedna-col">
    <div class="sedna-row sedna-gap-2">
        <span class="avatar avatar-sm">JW</span>
        <span class="avatar">JW</span>
        <span class="avatar avatar-lg">JW</span>
        <span class="avatar avatar--muted"><i class="ri-server-line"></i></span>
        <span class="avatar"><i class="ri-user-line"></i></span>
    </div>
    <div class="sedna-row sedna-gap-2">
        <span class="avatar avatar--viz-1">AF</span>
        <span class="avatar avatar--viz-2">PN</span>
        <span class="avatar avatar--viz-3">TF</span>
        <span class="avatar avatar--viz-4">JW</span>
        <span class="avatar avatar--viz-5">AF</span>
        <span class="avatar avatar--viz-6">PN</span>
    </div>
    <div class="sedna-row">
        <span class="avatar avatar-sm">JW</span>
        <span>Jordan Weiss<span class="visually-hidden">, assignee</span></span>
    </div>
</div>

Group

Overlapping, for “these several people”. The counter at the end is .avatar-more and not an .avatar — it is a number, not one more person.

JW PN MK +3
JW PN MK +8
JW PN
<div class="sedna-col">
    <div class="avatar-group">
        <span class="avatar">JW</span>
        <span class="avatar">PN</span>
        <span class="avatar">MK</span>
        <span class="avatar avatar--muted"><i class="ri-server-line"></i></span>
        <span class="avatar-more">+3</span>
    </div>
    <div class="avatar-group">
        <span class="avatar avatar-sm">JW</span>
        <span class="avatar avatar-sm">PN</span>
        <span class="avatar avatar-sm">MK</span>
        <span class="avatar-more">+8</span>
    </div>
    <div class="avatar-group">
        <span class="avatar avatar-lg">JW</span>
        <span class="avatar avatar-lg">PN</span>
        <span class="avatar avatar-lg avatar--muted"><i class="ri-user-line"></i></span>
    </div>
</div>

Pair

.avatar-pair stacks two people corner to corner inside one avatar's square, so in a list a pair's name starts where a single person's does and the column of names stays straight — an .avatar-group there would be as wide as its count. Chat's conversation list uses it for a group. Put the size class on the pair, not on the avatars inside it; at .avatar-sm one initial fits. Name the pair once, on the wrapper, and hide the avatars inside from a screen reader.

<div class="sedna-col">
    <div class="sedna-row-wrap sedna-gap-3">
        <span class="avatar-pair avatar-sm" role="img" aria-label="Priya Nair and Tomás Ferreira">
            <span class="avatar avatar--viz-2" aria-hidden="true">P</span>
            <span class="avatar avatar--viz-4" aria-hidden="true">T</span>
        </span>
        <span class="avatar-pair" role="img" aria-label="Priya Nair and Tomás Ferreira">
            <span class="avatar avatar--viz-2" aria-hidden="true">PN</span>
            <span class="avatar avatar--viz-4" aria-hidden="true">TF</span>
        </span>
        <span class="avatar-pair avatar-lg" role="img" aria-label="Priya Nair and Tomás Ferreira">
            <span class="avatar avatar--viz-2" aria-hidden="true">PN</span>
            <span class="avatar avatar--viz-4" aria-hidden="true">TF</span>
        </span>
        <span class="avatar-presence avatar-presence--meeting" role="img" aria-label="Alex Fischer and build-runner-04, in a meeting">
            <span class="avatar-pair avatar-lg">
                <span class="avatar" aria-hidden="true">AF</span>
                <span class="avatar avatar--muted" aria-hidden="true"><i class="ri-server-line"></i></span>
            </span>
        </span>
    </div>
    <div class="card" style="max-width:420px">
        <ul class="list">
            <li>
                <a class="list-row" href="#">
                    <span class="avatar">AF</span>
                    <span class="list-main">
                        <span class="list-title">Alex Fischer</span>
                        <span class="list-sub">Owner</span>
                    </span>
                </a>
            </li>
            <li>
                <a class="list-row" href="#">
                    <span class="avatar-pair" role="img" aria-label="Priya Nair and Tomás Ferreira">
                        <span class="avatar avatar--viz-2" aria-hidden="true">PN</span>
                        <span class="avatar avatar--viz-4" aria-hidden="true">TF</span>
                    </span>
                    <span class="list-main">
                        <span class="list-title">Priya Nair, Tomás Ferreira</span>
                        <span class="list-sub">Shared owners</span>
                    </span>
                </a>
            </li>
        </ul>
    </div>
</div>

Presence

.avatar-presence around an avatar puts the state on its corner: --online, --away, --busy, --do-not-disturb, --meeting (in a meeting or a call), --presenting, --out-of-office, --offline or --unknown. Every state is a different shape, not only a different colour, so it survives the colour-blind palette and forced colours — do not restyle one into a plain dot. The mark grows with .avatar-lg. It is the state's only carrier for the eye and none for a screen reader: name it, on the wrapper's aria-label or in the text beside it.

AF PN TF JW AF PN TF JW
AF PN JW AF PN JW AF PN JW
<div class="sedna-col">
    <div class="sedna-row-wrap sedna-gap-3">
        <span class="avatar-presence avatar-presence--online" role="img" aria-label="Alex Fischer, online"><span class="avatar">AF</span></span>
        <span class="avatar-presence avatar-presence--away" role="img" aria-label="Priya Nair, away"><span class="avatar avatar--viz-2">PN</span></span>
        <span class="avatar-presence avatar-presence--busy" role="img" aria-label="Tomás Ferreira, busy"><span class="avatar avatar--viz-4">TF</span></span>
        <span class="avatar-presence avatar-presence--do-not-disturb" role="img" aria-label="Jordan Weiss, do not disturb"><span class="avatar">JW</span></span>
        <span class="avatar-presence avatar-presence--meeting" role="img" aria-label="Alex Fischer, in a meeting"><span class="avatar">AF</span></span>
        <span class="avatar-presence avatar-presence--presenting" role="img" aria-label="Priya Nair, presenting"><span class="avatar avatar--viz-2">PN</span></span>
        <span class="avatar-presence avatar-presence--out-of-office" role="img" aria-label="Tomás Ferreira, out of office"><span class="avatar avatar--viz-4">TF</span></span>
        <span class="avatar-presence avatar-presence--offline" role="img" aria-label="Jordan Weiss, offline"><span class="avatar">JW</span></span>
        <span class="avatar-presence avatar-presence--unknown" role="img" aria-label="build-runner-04, presence unknown"><span class="avatar avatar--muted"><i class="ri-server-line"></i></span></span>
    </div>
    <div class="sedna-row-wrap sedna-gap-3">
        <span class="avatar-presence avatar-presence--online" role="img" aria-label="Alex Fischer, online"><span class="avatar avatar-sm">AF</span></span>
        <span class="avatar-presence avatar-presence--away" role="img" aria-label="Priya Nair, away"><span class="avatar avatar-sm avatar--viz-2">PN</span></span>
        <span class="avatar-presence avatar-presence--do-not-disturb" role="img" aria-label="Jordan Weiss, do not disturb"><span class="avatar avatar-sm">JW</span></span>
        <span class="avatar-presence avatar-presence--online" role="img" aria-label="Alex Fischer, online"><span class="avatar">AF</span></span>
        <span class="avatar-presence avatar-presence--away" role="img" aria-label="Priya Nair, away"><span class="avatar avatar--viz-2">PN</span></span>
        <span class="avatar-presence avatar-presence--do-not-disturb" role="img" aria-label="Jordan Weiss, do not disturb"><span class="avatar">JW</span></span>
        <span class="avatar-presence avatar-presence--online" role="img" aria-label="Alex Fischer, online"><span class="avatar avatar-lg">AF</span></span>
        <span class="avatar-presence avatar-presence--away" role="img" aria-label="Priya Nair, away"><span class="avatar avatar-lg avatar--viz-2">PN</span></span>
        <span class="avatar-presence avatar-presence--do-not-disturb" role="img" aria-label="Jordan Weiss, do not disturb"><span class="avatar avatar-lg">JW</span></span>
    </div>
</div>

Presence as text, and last seen

.avatar-presence--label puts the same mark in front of text: in a list row, a people picker or a profile card, where the state is written out and can carry a time — “in a meeting until 11:30”. Offline has nothing more to say than when the person was last there, so say that instead, in a <time>.

Online Away Busy Do not disturb In a meeting Presenting Out of office Offline Unknown
<div class="sedna-col">
    <div class="sedna-row-wrap sedna-gap-3">
        <span class="avatar-presence avatar-presence--label avatar-presence--online">Online</span>
        <span class="avatar-presence avatar-presence--label avatar-presence--away">Away</span>
        <span class="avatar-presence avatar-presence--label avatar-presence--busy">Busy</span>
        <span class="avatar-presence avatar-presence--label avatar-presence--do-not-disturb">Do not disturb</span>
        <span class="avatar-presence avatar-presence--label avatar-presence--meeting">In a meeting</span>
        <span class="avatar-presence avatar-presence--label avatar-presence--presenting">Presenting</span>
        <span class="avatar-presence avatar-presence--label avatar-presence--out-of-office">Out of office</span>
        <span class="avatar-presence avatar-presence--label avatar-presence--offline">Offline</span>
        <span class="avatar-presence avatar-presence--label avatar-presence--unknown">Unknown</span>
    </div>
    <div class="card" style="max-width:420px">
        <ul class="list">
            <li>
                <a class="list-row" href="#">
                    <span class="avatar-presence avatar-presence--meeting"><span class="avatar">AF</span></span>
                    <span class="list-main">
                        <span class="list-title">Alex Fischer</span>
                        <span class="list-sub"><span class="avatar-presence avatar-presence--label avatar-presence--meeting">In a meeting until 11:30</span></span>
                    </span>
                </a>
            </li>
            <li>
                <a class="list-row" href="#">
                    <span class="avatar-presence avatar-presence--out-of-office"><span class="avatar avatar--viz-4">TF</span></span>
                    <span class="list-main">
                        <span class="list-title">Tomás Ferreira</span>
                        <span class="list-sub"><span class="avatar-presence avatar-presence--label avatar-presence--out-of-office">Out of office until Monday</span></span>
                    </span>
                </a>
            </li>
            <li>
                <a class="list-row" href="#">
                    <span class="avatar-presence avatar-presence--offline"><span class="avatar">JW</span></span>
                    <span class="list-main">
                        <span class="list-title">Jordan Weiss</span>
                        <span class="list-sub">Last seen <time datetime="2026-09-14T17:40">yesterday at 17:40</time></span>
                    </span>
                </a>
            </li>
        </ul>
    </div>
</div>

Rings

.avatar--ring-warn says an administrator is acting as this person, and .avatar--ring, in the brand colour, marks the selected person or the one speaking. The ring stands a gap off the avatar and the gap is transparent, so it reads on a card, on the page and over a selected row; it works at every size, on an .avatar-pair, and under a presence mark. A ring is never the only carrier: write “Acting as” beside it. Do not ring an avatar inside an .avatar-group, whose cut-out clips it.

AF AF AF AF
PN PN PN PN
<div class="sedna-col">
    <div class="sedna-row-wrap sedna-gap-3">
        <span class="avatar avatar-sm avatar--ring-warn">AF</span>
        <span class="avatar avatar--ring-warn">AF</span>
        <span class="avatar avatar-lg avatar--ring-warn">AF</span>
        <span class="avatar-presence avatar-presence--online" role="img" aria-label="Alex Fischer, online"><span class="avatar avatar-lg avatar--ring-warn">AF</span></span>
        <span class="avatar-pair avatar--ring-warn" role="img" aria-label="Priya Nair and Tomás Ferreira">
            <span class="avatar avatar--viz-2" aria-hidden="true">PN</span>
            <span class="avatar avatar--viz-4" aria-hidden="true">TF</span>
        </span>
    </div>
    <div class="sedna-row-wrap sedna-gap-3">
        <span class="avatar avatar-sm avatar--ring">PN</span>
        <span class="avatar avatar--ring">PN</span>
        <span class="avatar avatar-lg avatar--ring">PN</span>
        <span class="avatar-presence avatar-presence--presenting" role="img" aria-label="Priya Nair, presenting"><span class="avatar avatar-lg avatar--viz-2 avatar--ring">PN</span></span>
    </div>
</div>

Acting as, in a list

The person being acted as, in an administrator's user list: the ring on the avatar and a .badge-warn that says so in words.

  • AF Alex Fischer alex.fischer@example.com Administrator
  • TF Tomás Ferreira tomas.ferreira@example.com Acting as
  • JW Jordan Weiss jordan.weiss@example.com Viewer
<div class="card" style="max-width:520px">
    <ul class="list">
        <li>
            <span class="list-row">
                <span class="avatar-presence avatar-presence--online"><span class="avatar">AF</span></span>
                <span class="list-main">
                    <span class="list-title">Alex Fischer</span>
                    <span class="list-sub">alex.fischer@example.com</span>
                </span>
                <span class="list-meta"><span class="badge">Administrator</span></span>
            </span>
        </li>
        <li>
            <span class="list-row">
                <span class="avatar-presence avatar-presence--away"><span class="avatar avatar--viz-4 avatar--ring-warn">TF</span></span>
                <span class="list-main">
                    <span class="list-title">Tomás Ferreira</span>
                    <span class="list-sub">tomas.ferreira@example.com</span>
                </span>
                <span class="list-meta"><span class="badge badge-warn"><i class="ri-spy-line"></i> Acting as</span></span>
            </span>
        </li>
        <li>
            <span class="list-row">
                <span class="avatar-presence avatar-presence--offline"><span class="avatar">JW</span></span>
                <span class="list-main">
                    <span class="list-title">Jordan Weiss</span>
                    <span class="list-sub">jordan.weiss@example.com</span>
                </span>
                <span class="list-meta"><span class="badge">Viewer</span></span>
            </span>
        </li>
    </ul>
</div>

Acting as, in the topbar

While an administrator acts as somebody, the user widget shows that person, with .avatar--ring-warn on .user-avatar and the badge in place of the e-mail line — frame classes as they are, nothing added to the frame. The menu says who is really signed in and offers the way back. On a phone the topbar drops the name and the badge, so name the state on the trigger's aria-label as well.

<div style="padding-bottom:180px">
    <header class="topbar topbar--responsive">
        <div class="topbar-spacer"></div>
        <div class="user-widget">
            <button class="user-trigger" type="button" aria-expanded="true" aria-label="Acting as Tomás Ferreira">
                <span class="user-avatar avatar--ring-warn">TF</span>
                <span class="user-info">
                    <span class="user-name">Tomás Ferreira</span>
                    <span class="user-email"><span class="badge badge-warn"><i class="ri-spy-line"></i> Acting as</span></span>
                </span>
            </button>
            <div class="menu">
                <span class="menu-label">Signed in as Alex Fischer</span>
                <a class="menu-item" href="#"><i class="ri-user-settings-line"></i> Tomás Ferreira&rsquo;s profile</a>
                <hr class="menu-sep" />
                <button class="menu-item" type="button">
                    <i class="ri-logout-circle-r-line"></i> Stop acting as Tomás Ferreira
                </button>
            </div>
        </div>
    </header>
</div>

Name with a subtext

An avatar, a name and a second line, with something trailing. There is no .person class for this: it is .list-row with .list-main, .list-title, .list-sub and .list-meta.

  • JW Jordan Weiss jordan.weiss@example.com Active
  • PN Priya Nair priya.nair@example.com Invited
  • build-runner-04 Service account · no sign-in System
<ul class="list" style="max-width:520px">
    <li>
        <span class="list-row">
            <span class="avatar">JW</span>
            <span class="list-main">
                <span class="list-title">Jordan Weiss</span>
                <span class="list-sub">jordan.weiss@example.com</span>
            </span>
            <span class="list-meta"><span class="badge badge-go">Active</span></span>
        </span>
    </li>
    <li>
        <span class="list-row">
            <span class="avatar">PN</span>
            <span class="list-main">
                <span class="list-title">Priya Nair</span>
                <span class="list-sub">priya.nair@example.com</span>
            </span>
            <span class="list-meta"><span class="badge">Invited</span></span>
        </span>
    </li>
    <li>
        <span class="list-row">
            <span class="avatar avatar--muted"><i class="ri-server-line"></i></span>
            <span class="list-main">
                <span class="list-title">build-runner-04</span>
                <span class="list-sub">Service account &middot; no sign-in</span>
            </span>
            <span class="list-meta"><span class="badge badge-info">System</span></span>
        </span>
    </li>
</ul>

In a table cell

.list-row--flush drops the row's own padding for the places that already provide it — a table cell, a card header, a form row. The access column is a .value-trigger: use it where a <select> would be wrong because the options need icons or a description.

MemberAccessLast seen
JW Jordan Weiss jordan.weiss@example.com 4 min ago
PN Priya Nair priya.nair@example.com 2 days ago
<div class="sedna-scroll-x" tabindex="0" role="group" aria-label="Team members">
<table class="table">
    <thead>
        <tr><th>Member</th><th class="col-control">Access</th><th class="col-num">Last seen</th></tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <span class="list-row list-row--flush">
                    <span class="avatar avatar-sm">JW</span>
                    <span class="list-main">
                        <span class="list-title">Jordan Weiss</span>
                        <span class="list-sub">jordan.weiss@example.com</span>
                    </span>
                </span>
            </td>
            <td class="col-control">
                <div class="menu-anchor">
                    <button class="value-trigger" type="button" data-menu-toggle aria-expanded="false">
                        <span>Maintainer</span>
                    </button>
                    <div class="menu" hidden>
                        <span class="menu-label">Access level</span>
                        <button class="menu-item" type="button"><i class="ri-eye-line"></i> Viewer</button>
                        <button class="menu-item" type="button"><i class="ri-git-pull-request-line"></i> Contributor</button>
                        <button class="menu-item" type="button"><i class="ri-shield-star-line"></i> Maintainer</button>
                    </div>
                </div>
            </td>
            <td class="col-num col-muted">4 min ago</td>
        </tr>
        <tr>
            <td>
                <span class="list-row list-row--flush">
                    <span class="avatar avatar-sm">PN</span>
                    <span class="list-main">
                        <span class="list-title">Priya Nair</span>
                        <span class="list-sub">priya.nair@example.com</span>
                    </span>
                </span>
            </td>
            <td class="col-control">
                <div class="menu-anchor">
                    <button class="value-trigger" type="button" data-menu-toggle aria-expanded="false">
                        <span>Viewer</span>
                    </button>
                    <div class="menu" hidden>
                        <span class="menu-label">Access level</span>
                        <button class="menu-item" type="button"><i class="ri-eye-line"></i> Viewer</button>
                        <button class="menu-item" type="button"><i class="ri-git-pull-request-line"></i> Contributor</button>
                        <button class="menu-item" type="button"><i class="ri-shield-star-line"></i> Maintainer</button>
                    </div>
                </div>
            </td>
            <td class="col-num col-muted">2 days ago</td>
        </tr>
    </tbody>
</table>
</div>