Becky
Becky

Reputation: 2275

CSS animation - transform issue

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>

Upvotes: 1

Views: 575

Answers (1)

Harry
Harry

Reputation: 89780

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.

Upvotes: 1

Related Questions