1

I am working on an animation that I can't seem to get it anything I am trying to do. I am trying to show a red dot turn into three stars and for the stars to end in separate places. I am running into three main issues.

  1. I can't get more than one star to show up.

  2. I want the star from 10% - 100% to show sliding into place. Right now it shows in position at 10%, then at the final point.

  3. The red dot shows the image of the star, so the image is taking place before the percentage I introduce it.

Does anyone see anything I am doing wrong to create these errors.

Note - I only have CSS for two stars at this point.

    body {
    background-color: #F5F5F5;
    color: #555;
    height: 100vh;
    width: 100%;
    font-size: 1.1em;
    font-family: 'Lato', sans-serif;
  }
  
  .star-container {
    background-color: green;
    color: white;
    width: 70%;
    height: 80%;
    margin: 10% auto;
    text-align: justify;
    position: relative;
  }
  
  .star1 {
    width: 250px;
    height: 250px;
    text-align: justify;
    -webkit-animation-name: star1;
    -webkit-animation-duration: 4s;
    -webkit-animation-iteration-count: 1;
    -webkit-animation-fill-mode: forwards;
    /*-webkit-animation-timing-function: linear;*/
    animation-name: star1;
    animation-duration: 4s;
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
    /*animation-timing-function: linear;*/
  }
  /* Chrome, Safari, Opera */
  
  @-webkit-keyframes star1 {
    0%,
    5% {
      background-color: red;
      position: absolute;
      left: 50%;
      top: 50%;
      height: 50px;
      width: 50px;
      border-radius: 50%;
      background-image: none;
    }
    5.1%,
    10% {
      background-color: red;
      position: absolute;
      left: 50%;
      top: 90%;
      height: 50px;
      width: 50px;
      border-radius: 50%;
      background-image: none;
    }
    10.1% {
      background-image: url('http://optimumwebdesigns.com/images/star.png');
      background-repeat: no-repeat;
      background-size: 100%;
      height: 50px;
      width: 50px;
    }
    100% {
      background-image: url('http://optimumwebdesigns.com/images/star.png');
      background-repeat: no-repeat;
      background-size: 100%;
      height: 50px;
      width: 50px;
    }
    /* Standard syntax */
    @keyframes star1 {
      0%,
      5% {
        background-color: red;
        position: absolute;
        left: 50%;
        top: 50%;
        height: 50px;
        width: 50px;
        border-radius: 50%;
      }
      5.1%,
      10% {
        background-color: red;
        position: absolute;
        left: 50%;
        top: 90%;
        height: 50px;
        width: 50px;
        border-radius: 50%;
      }
  10.1% {
      background-image: url('http://optimumwebdesigns.com/images/star.png');
      background-repeat: no-repeat;
      background-size: 100%;
      height: 50px;
      width: 50px;
    }
    100% {
      background-image: url('http://optimumwebdesigns.com/images/star.png');
      background-repeat: no-repeat;
      background-size: 100%;
      height: 50px;
      width: 50px;
    }
    }
    
    
 .star2 {
    width: 200px;
    height: 200px;
    text-align: justify;
    -webkit-animation-name: star2;
    -webkit-animation-duration: 4s;
    -webkit-animation-iteration-count: 1;
    -webkit-animation-fill-mode: forwards;
    /*-webkit-animation-timing-function: linear;*/
    animation-name: star2;
    animation-duration: 4s;
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
    /*animation-timing-function: linear;*/
  }
  /* Chrome, Safari, Opera */
  
  @-webkit-keyframes star2 {
    0%,
    5% {
      background-color: red;
      position: absolute;
      left: 50%;
      top: 50%;
      height: 40px;
      width: 40px;
      border-radius: 50%;
      background-image: none;
    }
    5.1%,
    10% {
      background-color: red;
      position: absolute;
      left: 50%;
      top: 90%;
      height: 40px;
      width: 40px;
      border-radius: 50%;
      background-image: none;
    }
    10.1%,
    100% {
      background-image: url('http://optimumwebdesigns.com/images/star.png');
      background-repeat: no-repeat;
      background-size: 100%;
      height: 40px;
      width: 40px;
      top: 5%;
      right: 5%;
    }
    /* Standard syntax */
    @keyframes star2 {
      0%,
      5% {
        background-color: red;
        position: absolute;
        left: 50%;
        top: 50%;
        height: 40px;
        width: 40px;
        border-radius: 50%;
      }
      5.1%,
      10% {
        background-color: red;
        position: absolute;
        left: 50%;
        top: 90%;
        height: 40px;
        width: 40px;
        border-radius: 50%;
      }
      10.1%,
      100% {
        background-image: url('http://optimumwebdesigns.com/images/star.png');
        background-repeat: no-repeat;
        background-size: 100%;
        height: 40px;
        width: 40px;
       top: 5%;
       right: 5%;
      }
    }
<div class="star-container">
  <div class="star1"></div>
  <div class="star2"></div>
  <div class="star3"></div>
</div>
Harry
  • 87,580
  • 25
  • 202
  • 214
Becky
  • 2,283
  • 2
  • 23
  • 50

1 Answers1

1

Answers to your questions:

I can't get more than one star to show

That seems to be because of a typo error. Your code is missing a } after both @-webkit-keyframes rules and thus @keyframes is getting nested under it. If this error is corrected, both starts do show up.

I want the star from 10% - 100% to show sliding into place. Right now it shows in position at 10%, then at the final point.

That is because you are changing the position attribute within the keyframes. It is not an animatable property and hence causes the jump. At 10%, the element is positioned absolutely at left: 50% and top: 90% but after that neither the position property nor the positioning attributes have been given a value within keyframes. There is no value for these attributes in the default state of the element also. Because of this, the element goes from being absolutely positioned at 10% to static positioning (which is the default) at 100%. Since position attribute cannot be animated (as mentioned earlier), it jumps.

Also, don't change the positioning attributes of the element from left to right or top to bottom during the course of an animation (or a transition). That change also cannot be animated and hence would result in a jump.

The red dot shows the image of the star, so the image is taking place before the percentage I introduce it.

I am not quite sure what you mean by this. The image is appearing at the correct point only. I think you are assuming it to be a problem with the image but (if my understanding of the question is correct) it is a problem with the background-color.

The background-color is red at 10% and there is no value for it either in any keyframe after that or in default state and hence it also animates (red to transparent). If you want to avoid this, then you should set background-color as transparent in the 10.1% keyframe.


Solution:

Based on my understanding, the below is what you are looking for. The whole thing can be achieved using a single animation itself. Just do the following changes:

  • Add position: absolute and final value for the positioning attributes (like top: 5%, left: 5%) in the default state itself. Set all of them using left and top in-order to avoid jumps.
  • Specify the height and width of the element also in the default state itself. As per your current code, the element will never get height: 250px or width: 250px because, at 0% it is 50 x 50px and it is the same at the end of the animation also. So replace height and width in default state with the expected value and remove them from the keyframes.
  • Set the final position of the elements in their default states and don't specify any positioning value after the 10.1% keyframe. This would mean that the element would slide to its final position. This would also enable us to re-use animations instead of writing one for each element.
  • Set background-color: transparent in the 10.1% keyframe if you don't want the color to slowly fade from red to transparent. Else, ignore it.
  • Set background-image: none in the 0%, 5% and 5.1%, 10% keyframes to be safe. Else, image will appear in-between and that could also give the appearance of the image appearing before it should.
  • Finally, create a common class (like star in the snippet) and set all common properties under it. Change your current class attribute to id and set all the unique properties using id selector.

body {
  background-color: #F5F5F5;
  color: #555;
  height: 100vh;
  width: 100%;
  font-size: 1.1em;
  font-family: 'Lato', sans-serif;
}
.star-container {
  background-color: green;
  color: white;
  width: 70%;
  height: 90%;
  margin: 10% auto;
  text-align: justify;
  position: relative;
}
.star{
  position: absolute;
  text-align: justify;
  animation-name: star1;
  animation-duration: 4s;
  animation-iteration-count: 1;
  animation-fill-mode: forwards;
}  
#star1 {
  left: 5%;
  top: 5%;
  height: 50px;
  width: 50px;
}
#star2 {
  left: 85%;
  top: 5%;
  height: 40px;
  width: 40px;
}
#star3 {
  left: 85%;
  top: 85%;
  height: 40px;
  width: 40px;
}
@keyframes star1 {
  0%, 5% {
    left: 50%;
    top: 50%;
    background-color: red;
    border-radius: 50%;
    background-image: none;
  }
  5.1%,
  10% {
    background-color: red;
    left: 50%;
    top: 90%;
    border-radius: 50%;
    background-image: none;
  }
  10.1% {
    left: 50%;
    top: 90%;
    background-image: url('http://optimumwebdesigns.com/images/star.png');
    background-repeat: no-repeat;
    background-size: 100%;
    background-color: transparent;
  }
  100% {
    background-image: url('http://optimumwebdesigns.com/images/star.png');
    background-repeat: no-repeat;
    background-size: 100%;
  }
}
<div class="star-container">
  <div class="star" id="star1"></div>
  <div class="star" id="star2"></div>
  <div class="star" id="star3"></div>
</div>

Note: As discussed in comments, IE and Firefox don't support animation on background-image. The images specified within the @keyframes rules don't even appear in them. The solution to this problem is to add the image at start itself but hide it using negative value for background-position like here. It would work in all browsers and at all screen sizes as long as the background position offset is greater than or equal to (-1 * width of widest element).

The reason for the problem in Firefox and IE can be found here.

Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
  • 1
    Thanks for the great answer! That is perfect. So, if I wanted to rotate a single star, during the 10.1-100% animation, I would have to create a single keyframe for the star itself, correct? – Becky Mar 14 '16 at 13:56
  • 1
    @Becky: [Here](https://jsfiddle.net/y6qjosrn/) is the sample. As you can see, I've added a second animation (`rotate`) just to the `#star1` and added the rotate transform within it. By applying same animation settings to both animations, we can synchronize them and so 10.1% within second animation will be at the same time as 10.1% within first animation :) – Harry Mar 14 '16 at 14:07
  • 1
    Gotcha! That would have saved me a bunch of time because I would have probably made a bunch more keyframes. Can I give each id ( `star1`, `star2`, and `star3`) as many different keyframe animations as I want? ie: `animation-name: star1, rotate, color, etc;` ? – Becky Mar 14 '16 at 14:24
  • Great! Thanks again for this great answer and help! – Becky Mar 14 '16 at 14:29
  • I thought I fully grasped your answer..I guess not. I want the beginning circle to look as if it is coming from the bottom left corner and go to about `left: 30%` and `top: 70%` and then look as if it exploded and the starts go different directions. From my 0-10%, it looks as if it does nothing? https://jsfiddle.net/y6qjosrn/ – Becky Mar 14 '16 at 15:15
  • 1
    @Becky: You mean like [this](https://jsfiddle.net/y6qjosrn/1/)? I have just modified the `top`, `left` within the keyframes. (*Note:* I have removed the 5%, 5.1% keyframes to give it a slide effect. If you want the original jump effect, you could uncomment them). – Harry Mar 14 '16 at 15:22
  • 1
    Gotcha, so whenever I have commas in the keyframes with the distances being almost right after each other, that is what causes it to jump? That was it...thanks again! – Becky Mar 14 '16 at 15:28
  • Shouldn't this work in firefox with `webkit`s added? – Becky Mar 14 '16 at 16:03
  • @Becky: Nope. `-webkit-` is for Chrome, Safari and Opera. Firefox used to use `-moz-` but animations and keyframes work even without it in the latest versions. That is, the standard `animation` and `@keyframes` are enough. – Harry Mar 14 '16 at 16:05
  • Because right now it doesn't work with Firefox/Internet Explorer and I put the webkits in...I'm not sure why it doesn't work in those browsers. It works up until the stars should show up. – Becky Mar 14 '16 at 16:06
  • If it is standard now, why won't it work on Firefox or Internet Explorer? – Becky Mar 14 '16 at 16:11
  • 1
    @Becky: It is really interesting that FF and IE don't seem to work well when `background-image` is set within the keyframes. They are just not at all displaying the image (!?). I have no clue why but there is a solution to that. Instead of having no image at start and then adding the image at 10.1%, we can set the image in default state but hide it using negative `background-position` and then show it at 10.1%. [This](https://jsfiddle.net/n1pau4ea/) seems to work in all three browsers. – Harry Mar 14 '16 at 16:25
  • Have you heard about this before? I wouldn't think that setting a new background-image in a keyframe is something unheard of? So would this `background-position: -100px 0%;` work despite the screen size? – Becky Mar 14 '16 at 16:32
  • You're right, though. Another animation I have on my site isn't working with Firefox as I have the `background-image` within the keyframes. – Becky Mar 14 '16 at 16:33
  • Nope @Becky I was stumped by this problem too. I never expected it to not work because all were standard properties and settings. `background-position: -100px 0%` would work on all screen sizes as long as the `.star` element is not more than 100px wide. Just set the negative of the widest star element to the `background-position`. That is, if there is a star who is 200px wide then set `background-position: -200px 0%`. Basically it is to offset the background to the left such that it becomes completely invisible. – Harry Mar 14 '16 at 16:35
  • Ok, thanks again! I will have to look into this matter, seems pretty odd. – Becky Mar 14 '16 at 17:42