Placing Items on a Circle

It can be quite challenging to place items on a circle with CSS. Usually, we end up relying on JavaScript because some plugins do it all right away. However more often than not there is no good reason to do it in JavaScript rather than CSS. This is presentational purpose, let's go the CSS way.

The Mixin

Ana Tudor explained how she managed to do it in a Stack Overflow answer, using chained CSS transforms. Thereafter I turned her solution into a Sass mixin to make everything a breeze.

/// Mixin to place items on a circle
/// @author Hugo Giraudel
/// @author Ana Tudor
/// @param {Integer} $item-count - Number of items on the circle
/// @param {Length} $circle-size - Large circle size
/// @param {Length} $item-size - Single item size
@mixin on-circle($item-count, $circle-size, $item-size) {
  position: relative;
  width:  $circle-size;
  height: $circle-size;
  padding: 0;
  border-radius: 50%; 
  list-style: none;       
  
  > * {
    display: block;
    position: absolute;
    top:  50%; 
    left: 50%;
    width:  $item-size;
    height: $item-size;
    margin: -($item-size / 2);
  
    $angle: (360 / $item-count);
    $rot: 0;

    @for $i from 1 through $item-count {
      &:nth-of-type(#{$i}) {
        transform: 
          rotate($rot * 1deg) 
          translate($circle-size / 2) 
          rotate($rot * -1deg);
      }

      $rot: $rot + $angle;
    }
  }
}

Caution! Vendor prefixes have been omitted from this code snippet. Be sure to prefix transform if you do not use Autoprefix.

Demo

For demo purposes, we'll consider a list of 8 images but basically anything could work.

<ul class='circle-container'>
  <li><img src='http://lorempixel.com/100/100/city' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/nature' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/abstract' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/cats' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/food' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/animals' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/business' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/people' alt="..." /></li>
</ul>
.circle-container {
  @include on-circle($item-count: 8, $circle-size: 20em, $item-size: 6em); 
  margin: 5em auto 0;
  border: solid 5px tomato;
  
  img { 
    display: block; 
    max-width: 100%; 
    border-radius: 50%;
    filter: grayscale(100%);
    border: solid 5px tomato;
    transition: .15s;
    
    &:hover,
    &:active {
      filter: grayscale(0);
    }
  }
}

See the Pen Items on circle by Hugo Giraudel (@HugoGiraudel) on CodePen.

Comments

  1. User Avatar
    Rashid Ali
    Permalink to comment#

    this is good but no working in IE

  2. User Avatar
    Petarp
    Permalink to comment#

    Is it possible to position this item’s using Bootstrap grid system?

  3. User Avatar
    oliver
    Permalink to comment#

    Thanks for this article Hugo, it’s really cool. Is there a way to position an image in the middle of the circle?

  4. User Avatar
    Oliver
    Permalink to comment#

    Never mind – I just found you Centering With Sass article. You’re my new favourite writer :)

  5. User Avatar
    AJ
    Permalink to comment#

    Hugo,

    I love this example, it helped greatly in an experiment I am doing where I have a angular data set that may require any where from one element in the circle to eight. Therefore I put some additional logic in the SASS to generate c1 through c8 where the number is the amount of circles.

    http://codepen.io/stegel/details/RWqpwO/

    I noticed that if I add an n+1 element, it gets automatically centered. Was that intentional?

    What I am trying to figure it how to animate one of the outside elements moving to the center. Do you have any suggestions on this?

  6. User Avatar
    Saneesh S Sanal
    Permalink to comment#

    Nice article Hugo, thanks! I was wondering how can we make the element rotate along the circle with out giving rotate transform to the parent wrapper.

  7. User Avatar
    Orel Naten
    Permalink to comment#

    thats a cool circle!, but i need to know…is it possible to pass parameters from html to the ‘@include on-circle($item-count: 8, $circle-size: 20em, $item-size: 6em);’ fanction?, lets say i want to control tha value of ‘item-count’, how can i do this?

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-anchoricon-closeicon-emailicon-linkicon-logo-staricon-menuicon-nav-guideicon-searchicon-staricon-tag