martellalex martellalex - 5 months ago 16
CSS Question

CSS animation shifting position with transform

I have a div element called

announcement
which I have positioned thusly with CSS:

#announcement{
position: fixed;
bottom:50px;
width: 340px;
height: 90px;
left: 50%;
transform:translate(-50%,0);
z-index:3;
font-family: Courier, monospace;
font-size:15px;
font-weight:400;
line-height:1.6;
}


Check out this codepen: http://codepen.io/martellalex/pen/WxGjeX



body {
box-sizing: border-box
}
#announcement {
position: fixed;
bottom: 50px;
width: 340px;
height: 90px;
left: 50%;
transform: translate(-50%, 0);
z-index: 3;
font-family: Courier, monospace;
font-size: 15px;
font-weight: 400;
line-height: 1.6;
}
#announcement-1 {
width: 100%;
height: 100%;
background-color: hsla(0, 0%, 7%, 0.85);
border-radius: 45px;
color: #fff;
box-shadow: 0 0 5px 0 hsla(0, 0%, 7%, 0.35)l
}
#announcement-1-1 {
float: left;
width: 64px;
margin-top: 13px;
margin-left: 15px;
}
#announcement-1-1-1 {
transition: color 0.2s ease-in-out, opacity 0.2s ease-in-out;
background-color: transparent;
}
#announcement-1-1-1-1 {
width: 64px;
height: 64px;
border: 0;
border-radius: 50%;
}
#announcement-1-2 {
float: left;
margin-top: 10px;
margin-left: 15px;
width: 210px;
}
#announcement-1-2 h4 {
margin: 0;
padding: 0;
font-size: 12px;
font-weight: bold;
margin-bottom: 3px;
}
#announcement-1-2 p {
color: #999;
line-height: 1.1;
margin-top: 3px;
font-size: 12px;
margin: 0;
padding: 0;
display: block;
}
#announcement-1-2-3 {
position: absolute;
bottom: 8px;
font-size: 12px;
}
#announcement-1-2-3-1 {
color: #fff
}
#announcement-1-2-3-2 {
font-family: Courier, monospace;
font-size: 12px;
font-weight: 400;
background: none;
border: 0;
text-decoration: underline;
color: #fff;
}
.run-animation.flipInX {
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
-webkit-animation-name: flipInX 1s;
animation: flipInX 1s;
}
@keyframes flipInX {
from {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
to {
-webkit-transform: perspective(400px);
transform: perspective(400px);
}
}

<div id='announcement' class='run-animation flipInX'>
<div id='announcement-1'>
<div id='announcement-1-1'>
<a href="https://google.com" title="More info" id="announcement-1-1-1">
<img id="announcement-1-1-1-1" src="https://images.unsplash.com/announcement-1466017995174-05cef779d74b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&fit=crop&h=128&w=128&s=834e52d3266c089e2260f3029e801ad1" alt="" />
</a>
</div>
<div id='announcement-1-2'>
<h4>Buy this book</h4>
<p>Awesome reason why.</p>
<div id="announcement-1-2-3">
<a href="https://google.com" id='announcement-1-2-3-1'>More info</a>
<button id="announcement-1-2-3-2">Dismiss</button>
</div>
</div>
</div>
</div>





Note that I have centred using
left: 50%; transform:translate(-50%,0)
. EDIT: note I have also positioned the div at 50px above the bottom of the screen using
bottom: 50px
.

My problem: I'm trying to animate with
flipInX
taken from
animate.css
. The element animates but during the animation it shifts right and then at the end of the animation it goes back to the original position.

How do I get it to remain in the centred position during animation?

I have extracted the animation CSS for
flipInX
and included it in the codepen:

.run-animation.flipInX {
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
-webkit-animation-name: flipInX 1s;
animation: flipInX 1s;
}

@keyframes flipInX {
from {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}

40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}

60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}

80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}

to {
-webkit-transform: perspective(400px);
transform: perspective(400px);
}
}

Answer

You can wrap <div id='announcement'> to another div, e.g.

<div id='announcement-wrapper'>
  <div id='announcement' class='run-animation flipInX'>
    ...
  </div>
</div>

And move the relevant style to that wrapper div, so that the animation only happens to #announcement not the wrapper.

body {
  box-sizing: border-box
}
#announcement-wrapper {
  position: fixed;
  bottom: 50px;
  width: 340px;
  height: 90px;
  left: 50%;
  transform: translate(-50%, 0);
  z-index: 3;
  font-family: Courier, monospace;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.6;
}
#announcement {
  height: inherit;
}
#announcement-1 {
  width: 100%;
  height: 100%;
  background-color: hsla(0, 0%, 7%, 0.85);
  border-radius: 45px;
  color: #fff;
  box-shadow: 0 0 5px 0 hsla(0, 0%, 7%, 0.35);
}
#announcement-1-1 {
  float: left;
  width: 64px;
  margin-top: 13px;
  margin-left: 15px;
}
#announcement-1-1-1 {
  transition: color 0.2s ease-in-out, opacity 0.2s ease-in-out;
  background-color: transparent;
}
#announcement-1-1-1-1 {
  width: 64px;
  height: 64px;
  border: 0;
  border-radius: 50%;
}
#announcement-1-2 {
  float: left;
  margin-top: 10px;
  margin-left: 15px;
  width: 210px;
}
#announcement-1-2 h4 {
  margin: 0;
  padding: 0;
  font-size: 12px;
  font-weight: bold;
  margin-bottom: 3px;
}
#announcement-1-2 p {
  color: #999;
  line-height: 1.1;
  margin-top: 3px;
  font-size: 12px;
  margin: 0;
  padding: 0;
  display: block;
}
#announcement-1-2-3 {
  position: absolute;
  bottom: 8px;
  font-size: 12px;
}
#announcement-1-2-3-1 {
  color: #fff
}
#announcement-1-2-3-2 {
  font-family: Courier, monospace;
  font-size: 12px;
  font-weight: 400;
  background: none;
  border: 0;
  text-decoration: underline;
  color: #fff;
}
.run-animation.flipInX {
  -webkit-backface-visibility: visible !important;
  backface-visibility: visible !important;
  -webkit-animation-name: flipInX 1s;
  animation: flipInX 1s;
}
@keyframes flipInX {
  from {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
    opacity: 0;
  }
  40% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  60% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
    opacity: 1;
  }
  80% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
  }
  to {
    -webkit-transform: perspective(400px);
    transform: perspective(400px);
  }
}
<div id='announcement-wrapper'>
  <div id='announcement' class='run-animation flipInX'>
    <div id='announcement-1'>
      <div id='announcement-1-1'>
        <a href="https://google.com" title="More info" id="announcement-1-1-1">
          <img id="announcement-1-1-1-1" src="https://images.unsplash.com/announcement-1466017995174-05cef779d74b?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&fit=crop&h=128&w=128&s=834e52d3266c089e2260f3029e801ad1" alt="" />
        </a>
      </div>
      <div id='announcement-1-2'>
        <h4>Buy this book</h4>
        <p>Awesome reason why.</p>
        <div id="announcement-1-2-3">
          <a href="https://google.com" id='announcement-1-2-3-1'>More info</a>
          <button id="announcement-1-2-3-2">Dismiss</button>
        </div>
      </div>
    </div>
  </div>
</div>