iOS & OS X Style Pure CSS Loading Spinner

Category: CSS & CSS3 , Loading | October 31, 2014
Authorjmak
Last UpdateOctober 31, 2014
LicenseMIT
Views20,071 views
iOS & OS X Style Pure CSS Loading Spinner

iOS & OS X Style Pure CSS Loading Spinner is a Sass-based CSS loading indicator that recreates the 12-blade activity spinner used in older Apple UI design concepts.

It places the spinner inside a dark overlay for page-level loading states and compiles to regular CSS for the browser.

The animation uses CSS keyframes and staggered delays across 12 .spinner-blade elements. No JavaScript required.

How to use it:

1. Add the spinner markup

The overlay contains one centered spinner and 12 blade elements. Keep all 12 blades because the Sass loop assigns each one a different rotation and animation delay.

<div class="overlay">
  <div class="spinner center">
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
    <div class="spinner-blade"></div>
  </div>
</div>

2. Add the Sass styles

The current styles use a 75px spinner, #69717d blades, and a black overlay at 90% opacity. Projects that use plain CSS can compile this Sass once before deployment. No Sass code runs in the browser.

$spinner-size: 75px !default;
$spinner-color: #69717d !default;
$overlay-color: black !default;
@mixin absolute-center {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
}
.overlay {
  background: rgba($overlay-color, .9);
  @include absolute-center;
}
.spinner {
  font-size: $spinner-size;
  position: relative;
  display: inline-block;
  width: 1em;
  height: 1em;
  &.center {
    @include absolute-center;
  }
}
.spinner-blade {
  position: absolute;
  left: .4629em;
  bottom: 0;
  width: .074em;
  height: .2777em;
  border-radius: .5em;
  background-color: transparent;
  transform-origin: center -.2222em;
  animation: spinner-fade 1s infinite linear;
  $animation-delay: 0s;
  $blade-rotation: 0deg;
  @for $i from 1 through 12 {
    &:nth-child(#{$i}) {
      animation-delay: $animation-delay;
      transform: rotate($blade-rotation);
      $blade-rotation: $blade-rotation + 30;
      $animation-delay: $animation-delay + .083;
    }
  }
}
@keyframes spinner-fade {
  0% {
    background-color: $spinner-color;
  }
  100% {
    background-color: transparent;
  }
}

Customize the spinner

The three Sass variables control the main visual settings. Change them before compiling the stylesheet.

  • $spinner-size sets the overall spinner size.
  • $spinner-color sets the blade color.
  • $overlay-color sets the overlay color. The .9 alpha value controls its opacity.

Change the animation speed

The default animation lasts one second and offsets each blade by .083s, which is approximately one-twelfth of the full cycle. Reduce both values proportionally to keep the 12 blades evenly staggered.

For a faster 0.6-second spinner, use a 0.6-second animation and a 0.05-second delay increment:

.spinner-blade {
  animation: spinner-fade .6s infinite linear;
  $animation-delay: 0s;
  $blade-rotation: 0deg;
  @for $i from 1 through 12 {
    &:nth-child(#{$i}) {
      animation-delay: $animation-delay;
      transform: rotate($blade-rotation);
      $blade-rotation: $blade-rotation + 30;
      $animation-delay: $animation-delay + .05;
    }
  }
}

Keep the overlay fixed to the viewport

The original overlay uses absolute positioning. A positioned ancestor can limit the overlay to that ancestor. For a viewport-level loading screen, override the positioning with position: fixed and inset: 0.

.overlay {
  position: fixed;
  inset: 0;
}

Alternatives:

You Might Be Interested In:


One thought on “iOS & OS X Style Pure CSS Loading Spinner

Leave a Reply