Patrickkx
Patrickkx

Reputation: 1870

Animation breaks blocks alignment

My problem is visible in the snippet below. My animation works fine, but it destroyrs items alignment here. If you remove the animation from it, you will see that the elements are stick together, creating a marker together. However if I add a simple moving animation, it breaks woefully.

What can I do so the after element sticks to the parent? Thanks

working snippet:

.wrapper {
  position: relative;
  height: 100px;
}

@keyframes jump {
  0% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(20px);
  }
  100% {
    transform: translateY(0);
  }
}

.p {
  border-radius: 50%;
  border: 2px solid red;
  background: #ccc;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.p::after {
  position: absolute;
  content: '';
  width: 0;
  z-index: -1;
  height: 0;
  bottom: 32px;
  left: 12px;
  border: 10px solid transparent;
  border-top: 17px solid red;
}
<div class='wrapper'>
  <div class='p' />
</div>

not working snippet (bug with alignment)

.wrapper {
  position: relative;
  height: 100px;
}

@keyframes jump {
  0% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(20px);
  }
  100% {
    transform: translateY(0);
  }
}

.p {
  border-radius: 50%;
  border: 2px solid red;
  background: #ccc;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: jump 2s infinite;
}

.p::after {
  position: absolute;
  content: '';
  width: 0;
  z-index: -1;
  height: 0;
  bottom: 32px;
  left: 12px;
  border: 10px solid transparent;
  border-top: 17px solid red;
}
<div class='wrapper'>
  <div class='p' />
</div>

Upvotes: 0

Views: 85

Answers (2)

Temani Afif
Temani Afif

Reputation: 273458

Adding transform using animation will have the p element becoming a containing block for the pseudo elementref. So the pseudo element will be positioned relatively to the p and no more to the wrapper. You need to make p position:relative and correct the position of the pseudo element. Doing this you will always have the pseudo element positioned relatively to p with and without animation:

.wrapper {
  position: relative;
  height: 100px;
}

@keyframes jump {
  0% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(20px);
  }
  100% {
    transform: translateY(0);
  }
}

.p {
  border-radius: 50%;
  border: 2px solid red;
  background: #ccc;
  width: 40px;
  height: 40px;
  position:relative;
  animation: jump 2s infinite;
}

.p::after {
  position: absolute;
  content: '';
  width: 0;
  z-index: -1;
  height: 0;
  top:100%;
  left: 10px;
  border: 10px solid transparent;
  border-top: 17px solid red;
}
<div class='wrapper'>
  <div class='p' ></div>
</div>

Without animation:

.wrapper {
  position: relative;
  height: 100px;
}

.p {
  border-radius: 50%;
  border: 2px solid red;
  background: #ccc;
  width: 40px;
  height: 40px;
  position:relative;
}

.p::after {
  position: absolute;
  content: '';
  width: 0;
  z-index: -1;
  height: 0;
  top:100%;
  left: 10px;
  border: 10px solid transparent;
  border-top: 17px solid red;
}
<div class='wrapper'>
  <div class='p' ></div>
</div>

Upvotes: 1

Uli
Uli

Reputation: 311

the thing is that the absolute positioned element is relative to wrapper, not the p. I applied the animation on that element and now it seems fine, hope it helps!

.wrapper {
  position: relative;
  height: 100px;
  -webkit-animation: jump 5s infinite; /*this is the fix*/
  -moz-animation:    jump 5s infinite; 
  -o-animation:      jump 5s infinite; 
  animation: jump 5s infinite;

}

@keyframes jump {
  0% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(20px);
  }
  100% {
    transform: translateY(0);
  }
}

.p {
  border-radius: 50%;
  border: 2px solid red;
  background: #ccc;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.p::after {
  position: absolute;
  content: '';
  width: 0;
  z-index: -1;
  height: 0;
  bottom: 32px;
  left: 12px;
  border: 10px solid transparent;
  border-top: 17px solid red;
}
<div class='wrapper'>
  <div class='p' />
</div>

Upvotes: 1

Related Questions