18 CSS Gradient UI17 / 18
Conic Gradient Avatar Border / Ring
A "team activity" strip of avatar rings: static conic story rings for unseen updates, a slow-rotating live ring for members currently online, a segmented progress ring, and a stacked-avatar group — real photos, all pure CSS.
Published
The code
<div class="cgu-17-group">
<section class="cgu-17" aria-label="Conic gradient avatar ring demos">
<div class="cgu-17__inner">
<header class="cgu-17__head">
<p class="cgu-17__eyebrow">17 · Avatar rings</p>
<h2 class="cgu-17__title">Rings that carry state</h2>
<p class="cgu-17__sub">Unseen, live, progress, and group — four conic-ring patterns on one roster. Only the gradients animate; the photos never move.</p>
</header>
<div class="cgu-17__roster">
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--story"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=32" alt="Maya Chen"></div>
<figcaption class="cgu-17__who">Maya<span class="cgu-17__state">2 updates</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--live"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=12" alt="Jonas Weber"><i class="cgu-17__dot" aria-hidden="true"></i></div>
<figcaption class="cgu-17__who">Jonas<span class="cgu-17__state">live now</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--seg"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=47" alt="Priya Nair"></div>
<figcaption class="cgu-17__who">Priya<span class="cgu-17__state">3 of 4 reviews</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--seen"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=68" alt="Tom Alvarez"></div>
<figcaption class="cgu-17__who">Tom<span class="cgu-17__state">all seen</span></figcaption>
</figure>
<figure class="cgu-17__person cgu-17__person--group">
<div class="cgu-17__stack">
<div class="cgu-17__ring cgu-17__ring--story cgu-17__ring--sm"><img class="cgu-17__img" src="https://i.pravatar.cc/96?img=5" alt="Ana Duarte"></div>
<div class="cgu-17__ring cgu-17__ring--story cgu-17__ring--sm"><img class="cgu-17__img" src="https://i.pravatar.cc/96?img=15" alt="Liam O'Shea"></div>
<div class="cgu-17__ring cgu-17__ring--sm cgu-17__more">+6</div>
</div>
<figcaption class="cgu-17__who">Design guild<span class="cgu-17__state">8 members</span></figcaption>
</figure>
</div>
<p class="cgu-17__foot">Close the conic loop — last stop repeats the first — or a seam appears at 12 o'clock.</p>
</div>
</section>
</div><div class="cgu-17-group">
<section class="cgu-17" aria-label="Conic gradient avatar ring demos">
<div class="cgu-17__inner">
<header class="cgu-17__head">
<p class="cgu-17__eyebrow">17 · Avatar rings</p>
<h2 class="cgu-17__title">Rings that carry state</h2>
<p class="cgu-17__sub">Unseen, live, progress, and group — four conic-ring patterns on one roster. Only the gradients animate; the photos never move.</p>
</header>
<div class="cgu-17__roster">
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--story"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=32" alt="Maya Chen"></div>
<figcaption class="cgu-17__who">Maya<span class="cgu-17__state">2 updates</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--live"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=12" alt="Jonas Weber"><i class="cgu-17__dot" aria-hidden="true"></i></div>
<figcaption class="cgu-17__who">Jonas<span class="cgu-17__state">live now</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--seg"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=47" alt="Priya Nair"></div>
<figcaption class="cgu-17__who">Priya<span class="cgu-17__state">3 of 4 reviews</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--seen"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=68" alt="Tom Alvarez"></div>
<figcaption class="cgu-17__who">Tom<span class="cgu-17__state">all seen</span></figcaption>
</figure>
<figure class="cgu-17__person cgu-17__person--group">
<div class="cgu-17__stack">
<div class="cgu-17__ring cgu-17__ring--story cgu-17__ring--sm"><img class="cgu-17__img" src="https://i.pravatar.cc/96?img=5" alt="Ana Duarte"></div>
<div class="cgu-17__ring cgu-17__ring--story cgu-17__ring--sm"><img class="cgu-17__img" src="https://i.pravatar.cc/96?img=15" alt="Liam O'Shea"></div>
<div class="cgu-17__ring cgu-17__ring--sm cgu-17__more">+6</div>
</div>
<figcaption class="cgu-17__who">Design guild<span class="cgu-17__state">8 members</span></figcaption>
</figure>
</div>
<p class="cgu-17__foot">Close the conic loop — last stop repeats the first — or a seam appears at 12 o'clock.</p>
</div>
</section>
</div>.cgu-17-group {
display: block;
width: 100%;
}
.cgu-17,
.cgu-17 *,
.cgu-17 *::before,
.cgu-17 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
@property --cgu17-a {
syntax: '<angle>';
initial-value: 210deg;
inherits: false;
}
.cgu-17 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
padding: 64px 24px;
font-family: 'Segoe UI',system-ui,sans-serif;
color: #eef0ff;
background: radial-gradient(90% 70% at 50% -10%,#171226 0%,#0c0a14 60%);
}
.cgu-17__inner {
width: min(920px,100%);
display: grid;
gap: 44px;
}
.cgu-17__head {
text-align: center;
display: grid;
gap: 13px;
justify-items: center;
}
.cgu-17__eyebrow {
font-size: 12px;
font-weight: 700;
letter-spacing: .28em;
text-transform: uppercase;
color: #f0abfc;
}
.cgu-17__title {
font-size: clamp(27px,4.2vw,46px);
font-weight: 800;
letter-spacing: -.02em;
line-height: 1.08;
text-wrap: balance;
}
.cgu-17__sub {
max-width: 56ch;
font-size: 15.5px;
line-height: 1.6;
color: #a7abc8;
text-wrap: pretty;
}
.cgu-17__roster {
display: flex;
gap: clamp(20px,4vw,44px);
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
}
.cgu-17__person {
display: grid;
gap: 12px;
justify-items: center;
}
.cgu-17__ring {
position: relative;
width: 96px;
aspect-ratio: 1;
border-radius: 50%;
padding: 7px;
}
.cgu-17__ring::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
padding: 3.5px;
-webkit-mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
}
.cgu-17__ring--story::before {
background: conic-gradient(from 210deg,#f59e0b,#ef4444,#d946ef,#8b5cf6,#f59e0b);
}
.cgu-17__ring--live::before {
background: conic-gradient(from var(--cgu17-a),#34d399,#22d3ee,#818cf8,#34d399);
animation: cgu17-turn 8s linear infinite;
}
.cgu-17__ring--seg::before {
background: conic-gradient(#34d399 0 22%,transparent 22% 25%,#34d399 25% 47%,transparent 47% 50%,#34d399 50% 72%,transparent 72% 75%,#2b2f45 75% 97%,transparent 97% 100%);
}
.cgu-17__ring--seen::before {
background: conic-gradient(#3a3f58 0 100%);
}
.cgu-17__img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
.cgu-17__dot {
position: absolute;
right: 4px;
bottom: 4px;
width: 18px;
height: 18px;
border-radius: 50%;
background: linear-gradient(140deg,#6ee7b7,#10b981);
box-shadow: 0 0 0 3px #0c0a14;
}
.cgu-17__who {
display: grid;
gap: 2px;
justify-items: center;
font-size: 14px;
font-weight: 700;
}
.cgu-17__state {
font-size: 11.5px;
font-weight: 600;
color: #8b90b0;
}
.cgu-17__stack {
display: flex;
padding-left: 14px;
}
.cgu-17__ring--sm {
width: 68px;
margin-left: -14px;
padding: 5px;
}
.cgu-17__ring--sm::before {
padding: 2.5px;
}
.cgu-17__more {
display: grid;
place-items: center;
font-size: 14px;
font-weight: 800;
color: #c7d2fe;
background: #1a1e33;
border-radius: 50%;
box-shadow: inset 0 0 0 2.5px #3a3f58;
}
.cgu-17__foot {
text-align: center;
font-size: 13px;
color: #7c81a3;
}
@keyframes cgu17-turn {
to {
--cgu17-a: 570deg;
}
}
@media (prefers-reduced-motion: reduce) {
.cgu-17__ring--live::before {
animation: none;
}
}.cgu-17-group {
display: block;
width: 100%;
}
.cgu-17,
.cgu-17 *,
.cgu-17 *::before,
.cgu-17 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
@property --cgu17-a {
syntax: '<angle>';
initial-value: 210deg;
inherits: false;
}
.cgu-17 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
padding: 64px 24px;
font-family: 'Segoe UI',system-ui,sans-serif;
color: #eef0ff;
background: radial-gradient(90% 70% at 50% -10%,#171226 0%,#0c0a14 60%);
}
.cgu-17__inner {
width: min(920px,100%);
display: grid;
gap: 44px;
}
.cgu-17__head {
text-align: center;
display: grid;
gap: 13px;
justify-items: center;
}
.cgu-17__eyebrow {
font-size: 12px;
font-weight: 700;
letter-spacing: .28em;
text-transform: uppercase;
color: #f0abfc;
}
.cgu-17__title {
font-size: clamp(27px,4.2vw,46px);
font-weight: 800;
letter-spacing: -.02em;
line-height: 1.08;
text-wrap: balance;
}
.cgu-17__sub {
max-width: 56ch;
font-size: 15.5px;
line-height: 1.6;
color: #a7abc8;
text-wrap: pretty;
}
.cgu-17__roster {
display: flex;
gap: clamp(20px,4vw,44px);
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
}
.cgu-17__person {
display: grid;
gap: 12px;
justify-items: center;
}
.cgu-17__ring {
position: relative;
width: 96px;
aspect-ratio: 1;
border-radius: 50%;
padding: 7px;
}
.cgu-17__ring::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
padding: 3.5px;
-webkit-mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
}
.cgu-17__ring--story::before {
background: conic-gradient(from 210deg,#f59e0b,#ef4444,#d946ef,#8b5cf6,#f59e0b);
}
.cgu-17__ring--live::before {
background: conic-gradient(from var(--cgu17-a),#34d399,#22d3ee,#818cf8,#34d399);
animation: cgu17-turn 8s linear infinite;
}
.cgu-17__ring--seg::before {
background: conic-gradient(#34d399 0 22%,transparent 22% 25%,#34d399 25% 47%,transparent 47% 50%,#34d399 50% 72%,transparent 72% 75%,#2b2f45 75% 97%,transparent 97% 100%);
}
.cgu-17__ring--seen::before {
background: conic-gradient(#3a3f58 0 100%);
}
.cgu-17__img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
.cgu-17__dot {
position: absolute;
right: 4px;
bottom: 4px;
width: 18px;
height: 18px;
border-radius: 50%;
background: linear-gradient(140deg,#6ee7b7,#10b981);
box-shadow: 0 0 0 3px #0c0a14;
}
.cgu-17__who {
display: grid;
gap: 2px;
justify-items: center;
font-size: 14px;
font-weight: 700;
}
.cgu-17__state {
font-size: 11.5px;
font-weight: 600;
color: #8b90b0;
}
.cgu-17__stack {
display: flex;
padding-left: 14px;
}
.cgu-17__ring--sm {
width: 68px;
margin-left: -14px;
padding: 5px;
}
.cgu-17__ring--sm::before {
padding: 2.5px;
}
.cgu-17__more {
display: grid;
place-items: center;
font-size: 14px;
font-weight: 800;
color: #c7d2fe;
background: #1a1e33;
border-radius: 50%;
box-shadow: inset 0 0 0 2.5px #3a3f58;
}
.cgu-17__foot {
text-align: center;
font-size: 13px;
color: #7c81a3;
}
@keyframes cgu17-turn {
to {
--cgu17-a: 570deg;
}
}
@media (prefers-reduced-motion: reduce) {
.cgu-17__ring--live::before {
animation: none;
}
}/* No JavaScript — every ring is a conic-gradient on a mask-composite donut; the live ring rotates its @property-registered angle so the photo never spins. */
/* No JavaScript — every ring is a conic-gradient on a mask-composite donut; the live ring rotates its @property-registered angle so the photo never spins. */Here's a working CSS Gradient UI from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Conic Gradient Avatar Border / Ring
Source: https://codefronts.com/design-styles/css-gradient-ui/conic-gradient-avatar-border-ring/
A "team activity" strip of avatar rings: static conic story rings for unseen updates, a slow-rotating live ring for members currently online, a segmented progress ring, and a stacked-avatar group — real photos, all pure CSS.
## HTML
```html
<div class="cgu-17-group">
<section class="cgu-17" aria-label="Conic gradient avatar ring demos">
<div class="cgu-17__inner">
<header class="cgu-17__head">
<p class="cgu-17__eyebrow">17 · Avatar rings</p>
<h2 class="cgu-17__title">Rings that carry state</h2>
<p class="cgu-17__sub">Unseen, live, progress, and group — four conic-ring patterns on one roster. Only the gradients animate; the photos never move.</p>
</header>
<div class="cgu-17__roster">
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--story"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=32" alt="Maya Chen"></div>
<figcaption class="cgu-17__who">Maya<span class="cgu-17__state">2 updates</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--live"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=12" alt="Jonas Weber"><i class="cgu-17__dot" aria-hidden="true"></i></div>
<figcaption class="cgu-17__who">Jonas<span class="cgu-17__state">live now</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--seg"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=47" alt="Priya Nair"></div>
<figcaption class="cgu-17__who">Priya<span class="cgu-17__state">3 of 4 reviews</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--seen"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=68" alt="Tom Alvarez"></div>
<figcaption class="cgu-17__who">Tom<span class="cgu-17__state">all seen</span></figcaption>
</figure>
<figure class="cgu-17__person cgu-17__person--group">
<div class="cgu-17__stack">
<div class="cgu-17__ring cgu-17__ring--story cgu-17__ring--sm"><img class="cgu-17__img" src="https://i.pravatar.cc/96?img=5" alt="Ana Duarte"></div>
<div class="cgu-17__ring cgu-17__ring--story cgu-17__ring--sm"><img class="cgu-17__img" src="https://i.pravatar.cc/96?img=15" alt="Liam O'Shea"></div>
<div class="cgu-17__ring cgu-17__ring--sm cgu-17__more">+6</div>
</div>
<figcaption class="cgu-17__who">Design guild<span class="cgu-17__state">8 members</span></figcaption>
</figure>
</div>
<p class="cgu-17__foot">Close the conic loop — last stop repeats the first — or a seam appears at 12 o'clock.</p>
</div>
</section>
</div>
```
## CSS
```css
.cgu-17-group {
display: block;
width: 100%;
}
.cgu-17,
.cgu-17 *,
.cgu-17 *::before,
.cgu-17 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
@property --cgu17-a {
syntax: '<angle>';
initial-value: 210deg;
inherits: false;
}
.cgu-17 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
padding: 64px 24px;
font-family: 'Segoe UI',system-ui,sans-serif;
color: #eef0ff;
background: radial-gradient(90% 70% at 50% -10%,#171226 0%,#0c0a14 60%);
}
.cgu-17__inner {
width: min(920px,100%);
display: grid;
gap: 44px;
}
.cgu-17__head {
text-align: center;
display: grid;
gap: 13px;
justify-items: center;
}
.cgu-17__eyebrow {
font-size: 12px;
font-weight: 700;
letter-spacing: .28em;
text-transform: uppercase;
color: #f0abfc;
}
.cgu-17__title {
font-size: clamp(27px,4.2vw,46px);
font-weight: 800;
letter-spacing: -.02em;
line-height: 1.08;
text-wrap: balance;
}
.cgu-17__sub {
max-width: 56ch;
font-size: 15.5px;
line-height: 1.6;
color: #a7abc8;
text-wrap: pretty;
}
.cgu-17__roster {
display: flex;
gap: clamp(20px,4vw,44px);
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
}
.cgu-17__person {
display: grid;
gap: 12px;
justify-items: center;
}
.cgu-17__ring {
position: relative;
width: 96px;
aspect-ratio: 1;
border-radius: 50%;
padding: 7px;
}
.cgu-17__ring::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
padding: 3.5px;
-webkit-mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
}
.cgu-17__ring--story::before {
background: conic-gradient(from 210deg,#f59e0b,#ef4444,#d946ef,#8b5cf6,#f59e0b);
}
.cgu-17__ring--live::before {
background: conic-gradient(from var(--cgu17-a),#34d399,#22d3ee,#818cf8,#34d399);
animation: cgu17-turn 8s linear infinite;
}
.cgu-17__ring--seg::before {
background: conic-gradient(#34d399 0 22%,transparent 22% 25%,#34d399 25% 47%,transparent 47% 50%,#34d399 50% 72%,transparent 72% 75%,#2b2f45 75% 97%,transparent 97% 100%);
}
.cgu-17__ring--seen::before {
background: conic-gradient(#3a3f58 0 100%);
}
.cgu-17__img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
.cgu-17__dot {
position: absolute;
right: 4px;
bottom: 4px;
width: 18px;
height: 18px;
border-radius: 50%;
background: linear-gradient(140deg,#6ee7b7,#10b981);
box-shadow: 0 0 0 3px #0c0a14;
}
.cgu-17__who {
display: grid;
gap: 2px;
justify-items: center;
font-size: 14px;
font-weight: 700;
}
.cgu-17__state {
font-size: 11.5px;
font-weight: 600;
color: #8b90b0;
}
.cgu-17__stack {
display: flex;
padding-left: 14px;
}
.cgu-17__ring--sm {
width: 68px;
margin-left: -14px;
padding: 5px;
}
.cgu-17__ring--sm::before {
padding: 2.5px;
}
.cgu-17__more {
display: grid;
place-items: center;
font-size: 14px;
font-weight: 800;
color: #c7d2fe;
background: #1a1e33;
border-radius: 50%;
box-shadow: inset 0 0 0 2.5px #3a3f58;
}
.cgu-17__foot {
text-align: center;
font-size: 13px;
color: #7c81a3;
}
@keyframes cgu17-turn {
to {
--cgu17-a: 570deg;
}
}
@media (prefers-reduced-motion: reduce) {
.cgu-17__ring--live::before {
animation: none;
}
}
```
## JavaScript
```js
/* No JavaScript — every ring is a conic-gradient on a mask-composite donut; the live ring rotates its @property-registered angle so the photo never spins. */
```Here's a working CSS Gradient UI from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Conic Gradient Avatar Border / Ring
Source: https://codefronts.com/design-styles/css-gradient-ui/conic-gradient-avatar-border-ring/
A "team activity" strip of avatar rings: static conic story rings for unseen updates, a slow-rotating live ring for members currently online, a segmented progress ring, and a stacked-avatar group — real photos, all pure CSS.
## HTML
```html
<div class="cgu-17-group">
<section class="cgu-17" aria-label="Conic gradient avatar ring demos">
<div class="cgu-17__inner">
<header class="cgu-17__head">
<p class="cgu-17__eyebrow">17 · Avatar rings</p>
<h2 class="cgu-17__title">Rings that carry state</h2>
<p class="cgu-17__sub">Unseen, live, progress, and group — four conic-ring patterns on one roster. Only the gradients animate; the photos never move.</p>
</header>
<div class="cgu-17__roster">
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--story"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=32" alt="Maya Chen"></div>
<figcaption class="cgu-17__who">Maya<span class="cgu-17__state">2 updates</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--live"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=12" alt="Jonas Weber"><i class="cgu-17__dot" aria-hidden="true"></i></div>
<figcaption class="cgu-17__who">Jonas<span class="cgu-17__state">live now</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--seg"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=47" alt="Priya Nair"></div>
<figcaption class="cgu-17__who">Priya<span class="cgu-17__state">3 of 4 reviews</span></figcaption>
</figure>
<figure class="cgu-17__person">
<div class="cgu-17__ring cgu-17__ring--seen"><img class="cgu-17__img" src="https://i.pravatar.cc/144?img=68" alt="Tom Alvarez"></div>
<figcaption class="cgu-17__who">Tom<span class="cgu-17__state">all seen</span></figcaption>
</figure>
<figure class="cgu-17__person cgu-17__person--group">
<div class="cgu-17__stack">
<div class="cgu-17__ring cgu-17__ring--story cgu-17__ring--sm"><img class="cgu-17__img" src="https://i.pravatar.cc/96?img=5" alt="Ana Duarte"></div>
<div class="cgu-17__ring cgu-17__ring--story cgu-17__ring--sm"><img class="cgu-17__img" src="https://i.pravatar.cc/96?img=15" alt="Liam O'Shea"></div>
<div class="cgu-17__ring cgu-17__ring--sm cgu-17__more">+6</div>
</div>
<figcaption class="cgu-17__who">Design guild<span class="cgu-17__state">8 members</span></figcaption>
</figure>
</div>
<p class="cgu-17__foot">Close the conic loop — last stop repeats the first — or a seam appears at 12 o'clock.</p>
</div>
</section>
</div>
```
## CSS
```css
.cgu-17-group {
display: block;
width: 100%;
}
.cgu-17,
.cgu-17 *,
.cgu-17 *::before,
.cgu-17 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
@property --cgu17-a {
syntax: '<angle>';
initial-value: 210deg;
inherits: false;
}
.cgu-17 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
padding: 64px 24px;
font-family: 'Segoe UI',system-ui,sans-serif;
color: #eef0ff;
background: radial-gradient(90% 70% at 50% -10%,#171226 0%,#0c0a14 60%);
}
.cgu-17__inner {
width: min(920px,100%);
display: grid;
gap: 44px;
}
.cgu-17__head {
text-align: center;
display: grid;
gap: 13px;
justify-items: center;
}
.cgu-17__eyebrow {
font-size: 12px;
font-weight: 700;
letter-spacing: .28em;
text-transform: uppercase;
color: #f0abfc;
}
.cgu-17__title {
font-size: clamp(27px,4.2vw,46px);
font-weight: 800;
letter-spacing: -.02em;
line-height: 1.08;
text-wrap: balance;
}
.cgu-17__sub {
max-width: 56ch;
font-size: 15.5px;
line-height: 1.6;
color: #a7abc8;
text-wrap: pretty;
}
.cgu-17__roster {
display: flex;
gap: clamp(20px,4vw,44px);
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
}
.cgu-17__person {
display: grid;
gap: 12px;
justify-items: center;
}
.cgu-17__ring {
position: relative;
width: 96px;
aspect-ratio: 1;
border-radius: 50%;
padding: 7px;
}
.cgu-17__ring::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
padding: 3.5px;
-webkit-mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
}
.cgu-17__ring--story::before {
background: conic-gradient(from 210deg,#f59e0b,#ef4444,#d946ef,#8b5cf6,#f59e0b);
}
.cgu-17__ring--live::before {
background: conic-gradient(from var(--cgu17-a),#34d399,#22d3ee,#818cf8,#34d399);
animation: cgu17-turn 8s linear infinite;
}
.cgu-17__ring--seg::before {
background: conic-gradient(#34d399 0 22%,transparent 22% 25%,#34d399 25% 47%,transparent 47% 50%,#34d399 50% 72%,transparent 72% 75%,#2b2f45 75% 97%,transparent 97% 100%);
}
.cgu-17__ring--seen::before {
background: conic-gradient(#3a3f58 0 100%);
}
.cgu-17__img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
.cgu-17__dot {
position: absolute;
right: 4px;
bottom: 4px;
width: 18px;
height: 18px;
border-radius: 50%;
background: linear-gradient(140deg,#6ee7b7,#10b981);
box-shadow: 0 0 0 3px #0c0a14;
}
.cgu-17__who {
display: grid;
gap: 2px;
justify-items: center;
font-size: 14px;
font-weight: 700;
}
.cgu-17__state {
font-size: 11.5px;
font-weight: 600;
color: #8b90b0;
}
.cgu-17__stack {
display: flex;
padding-left: 14px;
}
.cgu-17__ring--sm {
width: 68px;
margin-left: -14px;
padding: 5px;
}
.cgu-17__ring--sm::before {
padding: 2.5px;
}
.cgu-17__more {
display: grid;
place-items: center;
font-size: 14px;
font-weight: 800;
color: #c7d2fe;
background: #1a1e33;
border-radius: 50%;
box-shadow: inset 0 0 0 2.5px #3a3f58;
}
.cgu-17__foot {
text-align: center;
font-size: 13px;
color: #7c81a3;
}
@keyframes cgu17-turn {
to {
--cgu17-a: 570deg;
}
}
@media (prefers-reduced-motion: reduce) {
.cgu-17__ring--live::before {
animation: none;
}
}
```
## JavaScript
```js
/* No JavaScript — every ring is a conic-gradient on a mask-composite donut; the live ring rotates its @property-registered angle so the photo never spins. */
```How this works
An avatar ring is a circle wearing the demo-03 mask ring with a conic fill. The cleanest structure is a wrapper that owns the ring, so the image never needs resizing math:
.ring{ position: relative; border-radius: 50%; padding: 4px; }
.ring::before{ content:""; position:absolute; inset:0; border-radius:50%;
padding: 3px;
background: conic-gradient(from var(--a, 210deg), #f59e0b, #ef4444, #d946ef, #f59e0b);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor; mask-composite: exclude; }Close the loop (last stop = first) so the conic has no visible seam. The live ring registers --a with @property and rotates it — only the gradient turns, never the photo. The segment ring swaps the smooth conic for hard stops with transparent gaps: conic-gradient(#34d399 0 22%, transparent 22% 25%, …) — an instant "3 of 4 steps" indicator.
Make it yours
- Ring thickness = the pseudo-element's
padding; gap = the wrapper's. - Seen-state: swap the conic for a flat grey ring — one class toggle.
- Segment counts: each segment is a start/end stop pair; gaps are transparent spans.
- Rotation speed: the
cgu17-turnduration (8s reads as calm presence).
Gotchas — read before shipping
- Close the conic loop or a hard seam shows at 12 o'clock.
- Rotate the gradient angle via
@property— rotating the element would spin the photo too. - Keep a 2px+ gap between ring and photo; rings touching the image look like compression artifacts.
- Status conveyed by ring color needs a text or badge fallback — color alone fails WCAG 1.4.1.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 114+ | 17.5+ | 128+ | 114+ |
Floor set by @property, text-wrap as this demo is written. The core technique itself goes back further — Chrome 85+.
Static rings need only conic-gradient + mask (Baseline 2023). The rotating ring needs @property and degrades to a static ring without it.