How to Build Responsive Circular Avatar Lists with Modern CSS

I once had a client who saw a fancy “Who’s Online” widget on a high-end SaaS site and decided their WordPress team page needed that exact same look. They didn’t want a grid. They wanted a circular ring of faces that overlapped perfectly. My first instinct, back when I was younger and more impatient, was to just throw absolute positioning at it. I hardcoded nth-child rotations for six items. It looked great—until the client added a seventh team member. Then an eighth. The whole thing fell apart like a broken clock. Total nightmare.

The lesson learned there was simple: if you hardcode geometry, you’re just building technical debt. To build truly responsive circular avatar lists, you have to let the browser do the math. We’re moving past the horizontal layouts we talked about previously and diving into the heavy lifting of trigonometry in modern CSS.

The Smarter Way to Handle Circular Avatar Lists

In the old days, we’d reach for JavaScript to calculate the X and Y coordinates of every image in a circle. Now? We have the offset property. It’s cleaner, but it’s still a bit niche. My preference for production-ready code is actually using a double rotation trick with transform. It sounds counter-intuitive, but it works flawlessly with the new sibling-index() and sibling-count() functions.

Here is how you set up the base logic. This approach ensures that no matter how many avatars you drop into the bbioon-avatar-ring, they distribute themselves evenly. No more manual nth-child calculations. Trust me on this, your future self will thank you when the client decides to hire five more people on a Friday afternoon.

.bbioon-avatar-ring {
  display: grid;
  --bbioon-s: 100px; /* avatar size */
  aspect-ratio: 1;
  container-type: inline-size;
}

.bbioon-avatar-ring img {
  grid-area: 1/1;
  width: var(--bbioon-s);
  --bbioon-r: calc(50cqw - var(--bbioon-s) / 2);
  --bbioon-angle: calc(1turn * sibling-index() / sibling-count());
  
  /* The magic: rotate out, translate to the radius, then rotate back to stay upright */
  transform: rotate(calc(-1 * var(--bbioon-angle))) 
             translate(var(--bbioon-r)) 
             rotate(var(--bbioon-angle));
}

This builds on the concepts found in the original research over at CSS-Tricks. The sibling-index() function is the real hero here. It lets the CSS know exactly where each element sits in the list without us having to intervene.

Solving the Cut-Out and Masking Nightmare

The real “senior” problem isn’t just placing the images; it’s that cool cut-out effect where each circle looks like it’s biting into the next one. This requires a mask with a radial-gradient. But here’s the kicker: the center of that mask has to be the center of the next image in the circle. This is where the math gets hairy.

I tried to do this with simple percentages first. Big mistake. Because we’re in a circular coordinate system, the relative position of the “next” image changes depending on where you are in the ring. You have to use sin() and cos() inside your CSS calc(). It sounds like high school geometry because it is. But once you plug in the formula, it’s rock solid.

.bbioon-avatar-ring img {
  --bbioon-next-angle: calc(1turn * (sibling-index() + 1) / sibling-count());
  
  mask: radial-gradient(50% 50% at
    calc(50% + var(--bbioon-r) * (cos(var(--bbioon-next-angle)) - cos(var(--bbioon-angle))))
    calc(50% + var(--bbioon-r) * (sin(var(--bbioon-angle)) - sin(var(--bbioon-next-angle)))),
    #0000 calc(100% + 10px), #000);
}

One detail people often miss is the browser support. Functions like sibling-index() are currently working in Chrome and Edge but still pending in others. For a client project, I usually include a grid fallback. Always have a plan B. Period.

So, What’s the Takeaway?

Modern CSS is effectively turning the browser into a geometry engine. We don’t need heavy JavaScript libraries for these layouts anymore. By using container queries and trig functions, we can build circular avatar lists that are fully responsive and maintenance-free. It’s about building systems, not just styles.

Look, this stuff gets complicated fast. If you’re tired of debugging someone else’s CSS mess and just want your site to work perfectly on every device, drop my team a line. We’ve probably seen your exact problem before.

author avatar
Ahmad Wael
I'm a WordPress and WooCommerce developer with 15+ years of experience building custom e-commerce solutions and plugins. I specialize in PHP development, following WordPress coding standards to deliver clean, maintainable code. Currently, I'm exploring AI and e-commerce by building multi-agent systems and SaaS products that integrate technologies like Google Gemini API with WordPress platforms, approaching every project with a commitment to performance, security, and exceptional user experience.

Leave a Reply

Your email address will not be published. Required fields are marked *