2

I am attempting to make the icon appear in the middle of the screen before it transitions off to the left. Here is my code at the moment:

#courseIcon {
  position: relative;
  background: url(https://placehold.it/100x100);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  width: 100px;
  height: 100px;
  top: 0;
  left: 20%;
  margin-left: -125px;
}

/* ICON TRANSITION */
.moveIcon {
  -webkit-animation: moveIcon 2s;
  animation: moveIcon 2s;
  animation-fill-mode: backwards;
  animation-delay: 3s;
}

@-webkit-keyframes moveIcon {
  from {
    -webkit-transform: translateX(500px);
  }

  to {
    -webkit-transform: translateX(0px);
  }
}

@keyframes moveIcon {
  from {
    transform: translateX(500px);
  }

  to {
    transform: translateX(0px);
  }
}
<div id="courseIcon" class="moveIcon"></div>

At the moment I have just set translatex: 500px as this is roughly half of the screen I am viewing it on. Is there a way of getting the transition to start in the centre of the page, regardless of the screensize? Here is my code in a fiddle.

Thank you for your time.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Eddie
  • 390
  • 3
  • 13

2 Answers2

3
  • Position #courseIcon absolutely
  • Use transform/translate to begin in middle of the screen
  • Animate using transform/translate for GPU-accelerated smoothness
  • Remove from clause (unnecessary)
  • To prevent the animation from resetting upon completion, use animation-fill-mode: forwards

Edit: Removed calc from animation position calculation. As @TemaniAfif smartly points out, IE11 does not support transitioning values set with calc().

#courseIcon {
  position: absolute;
  background: url(https://placehold.it/100x100);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  width: 100px;
  height: 100px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* ICON TRANSITION */
.moveIcon {
  -webkit-animation: moveIcon 2s;
  animation: moveIcon 2s;
  animation-fill-mode: forwards;
  animation-delay: 3s;
}

@-webkit-keyframes moveIcon {
  to {
    -webkit-transform: translate(-50vw, -50%);
  }
}

@keyframes moveIcon {
  to {
    transform: translate(-50vw, -50%);
  }
}
<div id="courseIcon" class="moveIcon"></div>
Andy Hoffman
  • 18,436
  • 4
  • 42
  • 61
  • 1
    @Eddie pay attention if you will target IE borwser as calc is not supported inside transform (https://caniuse.com/#search=calc) – Temani Afif Feb 28 '19 at 11:16
1

You can consider the use of left (or right) and you won't need any complex calculation:

#courseIcon {
  position: absolute;
  background: url(https://placehold.it/100x100) center/contain no-repeat;
  width: 100px;
  height: 100px;
  top: calc(50% - 50px);
  left: calc(50% - 50px);
}

/* ICON TRANSITION */
.moveIcon {
  animation: moveIcon 2s forwards 3s;
}

@keyframes moveIcon {
  to {
    left:0;
  }
}

body {
 overflow:hidden;
}
<div id="courseIcon" class="moveIcon"></div>

You can also do it like below without the use of calc() in case you need better browser support:

#courseIcon {
  position: absolute;
  background: url(https://placehold.it/100x100) center/contain no-repeat;
  width: 100px;
  height: 100px;
  top: 50%;
  left: 50%;
  transform:translate(-50%,-50%);
}

/* ICON TRANSITION */
.moveIcon {
  animation: moveIcon 2s forwards 3s;
}

@keyframes moveIcon {
  to {
    left:0;
    transform:translate(0%,-50%);
  }
}

body {
 overflow:hidden;
}
<div id="courseIcon" class="moveIcon"></div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • You'll get much better/smoother animation with `transform` over `left`. You know better! :) Also, your example isn't vertically centered, as OP stated he wants. – Andy Hoffman Feb 28 '19 at 11:11
  • @AndyHoffman you already provided the transform so I am providing an alternative solution. – Temani Afif Feb 28 '19 at 11:13
  • Thanks for vertically centering. – Andy Hoffman Feb 28 '19 at 11:14
  • Also, is `calc(-50vw - 100px)` really *more complex* than `calc(50% - 50px)`? – Andy Hoffman Feb 28 '19 at 11:16
  • @AndyHoffman `calc(50% - 50px)` is used for the centring, it's not relevant to the animation. you know that we can centre using a lot of ways (flexobox, negative margin, translate, etc etc) ... the animation is the relavant part here – Temani Afif Feb 28 '19 at 11:17
  • Yes, and your suggestion is to animate it poorly with `left`, which left me confused. – Andy Hoffman Feb 28 '19 at 11:18
  • 1
    @AndyHoffman so we should not provide another solution because you provided the *best* one? there is no *poor* or *better* solution for me on SO. There is different answers providing alternative method. Someone else may also provide an animation with margin. You will think it's a bad idea but it's simply another alternative. – Temani Afif Feb 28 '19 at 11:23
  • I see your point. Hopefully you can see mine, too. For the record, I'm a huge fan of yours. – Andy Hoffman Feb 28 '19 at 11:25
  • @AndyHoffman I see your point and I already upvoted your answer. by the way I have edited to include another way (still with left) and without any use of calc. Not *better* but it can be helpful if browser doesn't support calc. – Temani Afif Feb 28 '19 at 11:29
  • I am currently updating my example as well to remove `calc` since OP mentioned in the comments he wanted the box to stop at the edge of the screen (still visible). – Andy Hoffman Feb 28 '19 at 11:32
  • @TemaniAfif thanks for letting me know about browser support, this will be used on a variety of browsers so that's great, thanks! – Eddie Feb 28 '19 at 11:39
  • 1
    @Eddie I updated my answer so IE support is included :) – Andy Hoffman Feb 28 '19 at 11:40