Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS breathing <button> stop text from shaking

Tags:

html

css

I have a round breathing click me button beneath, here I am using @keyframes to animate the button breathing - so far all good!

But as you can tell the click me text is shaking during the breathing animation.

Is there a way to avoid this from happening?

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) 
}

button.circle {
  --startSize: 65vh;
  --endSize: 85vh;
  width: var(--startSize);
  height: var(--startSize);
  background: teal;
  border-radius: 100%;
  animation-name: breathe;
  animation-play-state: running;
  animation-duration: 4.5s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
    border: none;

}

@keyframes breathe {
  
  0% {
    width: var(--startSize); 
    height: var(--startSize);
  }
  
  25% {
    width: var(--startSize); 
    height: var(--startSize);
  }

  75% {
    width: var(--endSize);
    height: var(--endSize);
  }
  
  100% {
    width: var(--endSize);
    height: var(--endSize);
  }
}
<a href="https://www.w3schools.com"><button class="circle centered">Click me</button></a>
like image 530
Fjott Avatar asked Jan 08 '19 18:01

Fjott


1 Answers

Perhaps a better way to animate this would be to use transform: scale(...) on the ::after pseudo-element. Using this method we get the following benefits:

  1. The animation no longer affects document flow1. When animating, prefer transform and opacity over properties like width or height. The latter will affect the elements around it (the document flow). Transforms are purely visual - they have no affect on other elements in terms of placement, which means improved performance.
  2. The text is separate from the animation which means no more shakiness.

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) 
}

button.circle {
  width: 65vh;
  height: 65vh;
  border: 0;
  background-color: transparent;
}

button.circle::after {
  z-index: -1;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  content: '';
  display: block;
  background: teal;
  border-radius: 100%;
  animation: breathe 4.5s ease infinite alternate running;
}

@keyframes breathe {
  from { transform: scale(1); }
  to { transform: scale(1.4); }
}
<a href="https://www.w3schools.com"><button class="circle centered">Click me</button></a>

Note: Browser support for this method


1. I realize the button is centered and positioned absolute which means it isn't affecting document flow to begin with. That said, this method of animating with transforms is more flexible for either scenario.

like image 193
chazsolo Avatar answered Oct 16 '22 06:10

chazsolo