Rotating images on a circular path using CSS/SASS

I came across Hugo Giraudel’s excellent tutorial on arranging images on a circle using SASS/CSS, and I am trying to take it another step further by animating the rotation of the circle of images. I have modified a codepen showing one of a variety of unsatisfactory results I am getting. The HTML is just an unordered list of five images:

<ul class='circle-container'>
  <li class="city">
    <a href='#'><img src='http://lorempixel.com/150/150/city'></a>
  </li>
  <li class="nature">
    <a href='#'><img src='http://lorempixel.com/150/150/nature'></a>
  </li>
  <li class="abstract">
    <a href='#'><img src='http://lorempixel.com/150/150/abstract'></a>
  </li>
  <li class="sports">
    <a href='#'><img src='http://lorempixel.com/150/150/sports/'></a>
  </li>
  <li class="food">
    <a href='#'><img src='http://lorempixel.com/150/150/food'></a>
  </li>
</ul>

His SASS/CSS with some minor edits of mine:

/**
 * Mixin to put items on a circle
 * [1] - Allows children to be absolutely positioned
 * [2] - Allows the mixin to be used on a list
 * [3] - In case box-sizing: border-box has been enabled
 * [4] - Allows any type of direct children to be targeted
 */

@mixin putOnCircle( 
          $nb-items, //Number of items
          $circle-size, //Parent size
          $item-size, //Item size
          $class-for-IE: false //Base class name, false means use of pseudo-selectors
       ) {
  $item-size: 150px;
  $nb-items: 5; 
  $circle-size: 550px;
  $half-item:     $item-size / 2;
  $half-parent: $circle-size / 2;

  position: relative;               /* [1] */
  width:  $circle-size;
  height: $circle-size;
  padding: 0;
  border-radius: 50%; 
  list-style: none;                 /* [2] */ 
  @include box-sizing(content-box); /* [3] */ 

  > * {                             /* [4] */
    display: block;
    position: absolute;
    top:  50%; 
    left: 50%;
    width:  $item-size;
    height: $item-size;
    margin: -$half-item;

    $angle: 360 / $nb-items;
    $rot: 0;
    @for $i from 1 to $nb-items+1 {

      // If no support for IE8-

      @if $class-for-IE == false {
        &:nth-of-type(#{$i}) {
          @include transform(rotate(#{$rot}deg) translate($half-parent) rotate(-#{$rot}deg));
        }
      }

      // If support for IE8-  

      @else {
        &.#{$class-for-IE}#{$i} {
          // If CSS transforms are not supported
          $mt: sin($rot * pi() / 180) * $half-parent - $half-item;
          $ml: cos($rot * pi() / 180) * $half-parent - $half-item;
          margin: $mt 0 0 $ml;
        }
      }
      $rot: $rot + $angle;
    }
  }
}

.circle-container {
  @include putOnCircle(8, 20em, 6em, false); 
  margin: 5em auto 0;
  border: solid 5px tomato;
  animation: rot 8s infinite linear;
  -webkit-animation: rot 8s infinite linear;
  -moz-animation: rot 8s infinite linear;

  a {
    display: block;
    border-radius: 50%;
    box-shadow: 0 0 0 5px tomato;
  }

  img { 
    display: block; 
    width: 100%; 
    border-radius: 50%;
    @include  filter(grayscale(100%));

    &:hover {
      @include filter(grayscale(0));
    }
  }
}
@keyframes rot {
  from {
    transform:        rotate(0deg)
                      translate(-275px)
                      rotate(0deg);
   -webkit-transform: rotate(0deg)
                      translate(-275px)
                      rotate(0deg);
  }
  to {
    transform:        rotate(360deg)
                      translate(-275px)
                      rotate(-360deg);
   -webkit-transform: rotate(360deg)
                      translate(-275px) 
                      rotate(-360deg);
  }
}

@-webkit-keyframes rot {
  from {
    transform:        rotate(0deg)
                      translate(-275px)
                      rotate(0deg);
   -webkit-transform: rotate(0deg)
                      translate(-275px)
                      rotate(0deg);
  }
  to {
    transform:        rotate(360deg)
                      translate(-275px) 
                      rotate(-360deg);
   -webkit-transform: rotate(360deg)
                      translate(-275px) 
                      rotate(-360deg);
  }
}

.city,
.nature,
.abstract,
.sports,
.food {
  /*animation: rot 8s infinite linear;
  -webkit-animation: rot 8s infinite linear;
  -moz-animation: rot 8s infinite linear;
*/
}

In the code above (same as in the codepen), the images stay in their fixed positions, but the entire circle container rotates (revolves, really).

If I remove the animation on the circle-container ul:

.circle-container {
      @include putOnCircle(8, 20em, 6em, false); 
      margin: 5em auto 0;
      border: solid 5px tomato;
      /* animation: rot 8s infinite linear;
      -webkit-animation: rot 8s infinite linear;
      -moz-animation: rot 8s infinite linear; */

…and instead animate the list items (or the anchor elements, or the imgs):

.city,
    .nature,
    .abstract,
    .sports,
    .food {
      animation: rot 8s infinite linear;
      -webkit-animation: rot 8s infinite linear;
      -moz-animation: rot 8s infinite linear;
    }

I am then able to rotate (revolve) an image correctly around the circle, but only one image. The four other images seem to fall in line behind it. I am sure the solution is fairly simple, but I’ve tried every permutation I can think of, and it’s been eluding me long enough that I thought I’d turn here for advice. Any help would be greatly appreciated!


Source: css3

Leave a Reply