Using CSS3 transforms/animations with font-face produces "wobbly" spinner gif-like

11,341

Solution 1

By default, CSS transforms things about their vertical and horizontal center with the property transform-origin. A short-hand syntax for this default value is 50% 50%, which represents the x and then y value of the origin.

For this icon, I found that shifting the y origin to 38% smooths it out a bit, but you'll need to play around with it to get the precise values. View on JSFiddle

i.icon-repeat {
  -webkit-transform-origin:50% 38%;
  -moz-transform-origin:50% 38%;
  -ms-transform-origin:50% 38%;
  -o-transform-origin:50% 38%;
  transform-origin: 50% 38%;
}

For more on the transform-origin property, I recommend the MDN article on the property.

Solution 2

Try setting a specific height and width on the element. Through trial and error, I found that adding:

#iconRepeatMain {
    width: 26px;
    height: 19px;
}

centers the font pretty well and seems to eliminate the wobbling. However, it's possible this is dependent on which browser is being used -- test it thoroughly.

http://jsfiddle.net/mblase75/pGhFX/13/

Solution 3

I don't see it documented in the pages at Font Awesome's site, but the CSS source shows an icon-spin class which rotates an icon endlessly, and for your icon-repeat logo, has virtually no wobble.

<i class="icon-repeat icon-spin"></i>

...though I'm guessing it's really intended for the icon-spinner icon:

<i class="icon-spinner icon-spin"></i>

Edit: d'oh... this relies on a more recent font-awesome.css than the one in your example. So maybe the answer is just that they fixed the wobble themselves. The icon-spin class is new though.

Share:
11,341

Related videos on Youtube

tim peterson
Author by

tim peterson

web programming-javascript, php, mysql, css, html-is my thang

Updated on September 15, 2022

Comments

  • tim peterson
    tim peterson over 1 year

    I'm using CSS transforms/animations with font-face (twitter bootstrap/font-awesome) to produce a spinner gif-like icon.

    The problem is that the icon wobbles as it revolves around 360degrees. See this JSFiddle to see what I mean. Does anyone know how to make it not wobble? Or at least make it rotate a little more smoothly?

    Here's the code for that below:

    CSS:

    i.icon-repeat {
      -webkit-animation: Rotate 500ms infinite linear;
      -moz-animation: Rotate 500ms infinite linear;
      -ms-animation: Rotate 500ms infinite linear;
      -o-animation: Rotate 500ms infinite linear;
      animation: Rotate 500ms infinite linear;
    }
    @-o-keyframes Rotate {
      from {-o-transform:rotate(0deg);}
      to {-o-transform:rotate(360deg);}
    }
    @-moz-keyframes Rotate {
     from {-moz-transform:rotate(0deg);}
     to {-moz-transform:rotate(360deg);}
    }
    @-ms-keyframes Rotate {
      from {-ms-transform:rotate(0deg);}
      to {-ms-transform:rotate(360deg);}
    }
    @-webkit-keyframes Rotate {
      from {-webkit-transform:rotate(0deg);}
      to {-webkit-transform:rotate(360deg);}
    }
    @keyframes Rotate {
      from { transform:rotate(0deg);}
      to { transform:rotate(360deg);}
    }
    #iconRepeatMain{
      display: inline-block;    
      position: absolute;
      z-index:10007;
      left: 50%;
      top: 50%;
      margin-left: -24px; /* -1 * image width / 2 */
      margin-top: -24px;  /* -1 * image height / 2 */
      font-size:36px;
    }​
    

    HTML:

    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.no-icons.min.css" rel="stylesheet">
    <link href="//netdna.bootstrapcdn.com/font-awesome/2.0/css/font-awesome.css" rel="stylesheet">
    <i id='iconRepeatMain' class='icon-repeat' style='font-size:36px; color:red'></i>​
    

    Note: if anyone wants to use this code in your own web app, please be sure to remove this spinner from the DOM when the action it was needed for is done. Keeping this icon rotating in the background burns up CPU regardless of the browser like you won't believe. Also, simply toggling its visibility, i.e., display:none, doesn't work. You need to remove it from the DOM like with this: $('#iconRepeatMain').remove();

    • Forty-Two
      Forty-Two over 11 years
      That's awesome. I wouldn't change a thing!
    • Blazemonger
      Blazemonger over 11 years
      I assume the problem is that the font isn't perfectly centered itself. Using an image instead might be best.
    • tim peterson
      tim peterson over 11 years
      @Forty-Two believe me, over time you'll get annoyed with how rickety it looks. The spinner is supposed to convey progress toward success. This looks like a car that is about to have its wheels fall off and go over a cliff.
  • Blazemonger
    Blazemonger over 11 years
    Updated again. In Chrome, 26-by-19-pixels eliminates the wobble entirely. Use your browser's web inspector to nudge the height and width until you see what you like.
  • Kosta
    Kosta over 11 years
    Yup, with width:25px; height:15px; it looks great :)
  • Kosta
    Kosta over 11 years
    But it would be much cleaner to use image.
  • Blazemonger
    Blazemonger over 11 years
    @Kosta I don't know about 'cleaner', but it'll certainly be more reliable.
  • tim peterson
    tim peterson over 11 years
    "But it would be much cleaner to use image"- @Kosta I think you could be right.
  • Blazemonger
    Blazemonger over 11 years
    +1 - This is a better solution than mine, in that it addresses the real problem (centering) in the most direct way. Incidentally, 47% 41% works even better for me.
  • tim peterson
    tim peterson over 11 years
    Other things which I find help with the wobbliness is to use icon-refresh instead of icon-repeat and to speed up the rotation from 500ms to 250ms as shown in this JSFiddle. The symmetry of the icon-refresh arrowheads compared with icon-repeat seems more visually appealing when the icon is rotating. Regarding speed of rotation, usually the spinner isn't noticed b/c pages load so fast. But if the spinner is apparent(page is doing heavy-lifting), I decided it was better to indicate the server was working "fast"=hard rather than "slow"="lazy.