71

How can I get a CSS Animation to play with a JavaScript onClick? I currently have:

.classname {
  -webkit-animation-name: cssAnimation;
  -webkit-animation-duration:3s;
  -webkit-animation-iteration-count: 1;
  -webkit-animation-timing-function: ease;
  -webkit-animation-fill-mode: forwards;
}
@-webkit-keyframes cssAnimation {
  from {
    -webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(100px);
  }
  to {
    -webkit-transform: rotate(0deg) scale(2) skew(0deg) translate(100px);
  }
}

How can I apply an onClick?

Gibolt
  • 42,564
  • 15
  • 187
  • 127
tekknolagi
  • 10,663
  • 24
  • 75
  • 119

11 Answers11

74

Are you sure you only display your page on webkit? Here is the code, passed on safari. The image (id='img') will rotate after button click.

function ani() {
  document.getElementById('img').className = 'classname';
}
.classname {
  -webkit-animation-name: cssAnimation;
  -webkit-animation-duration: 3s;
  -webkit-animation-iteration-count: 1;
  -webkit-animation-timing-function: ease;
  -webkit-animation-fill-mode: forwards;
}

@-webkit-keyframes cssAnimation {
  from {
    -webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(100px);
  }
  to {
    -webkit-transform: rotate(0deg) scale(2) skew(0deg) translate(100px);
  }
}
<input name="" type="button" onclick="ani()" value="Click">
<img id="img" src="https://i.stack.imgur.com/vghKS.png" width="328" height="328" />
biberman
  • 5,606
  • 4
  • 11
  • 35
Shisoft
  • 4,197
  • 7
  • 44
  • 61
  • 49
    Just be mindful that using `.className` will wipe out all of your other classes on the given element. If this is undesired, use `document.getElementById('img').classList.add('classname');` – Drew Kennedy Nov 01 '16 at 21:05
  • 3
    This animates only the first time уоu click. Subsequent clicks do nothing. Use `sad comrade` method below to enable multiple clicks. – Max S. Mar 23 '22 at 22:55
63

You just use the :active pseudo-class. This is set when you click on any element.

.classname:active {
    /* animation css */
}
Paul Fisher
  • 9,618
  • 5
  • 37
  • 53
35

Found solution on css-tricks

const element = document.getElementById('img')

element.classList.remove('classname'); // reset animation
void element.offsetWidth; // trigger reflow
element.classList.add('classname'); // start animation
sad comrade
  • 1,341
  • 19
  • 21
  • Triggering the reflow on the middle line is a nifty trick. just what i needed – he77kat_ Apr 18 '20 at 14:25
  • 1
    How does triggering the reflow work? – vanya Jul 29 '22 at 12:24
  • @he77kat_ I don't even know what reflow means, nor can I find a good explanation. Care to oblige? – ptrcao Jan 02 '23 at 01:19
  • 2
    @ptrcao reflow is the name of the web browser process for re-calculating the positions and geometries of the elements in the HTML document, for the purpose of re-rendering part or all of the document. Certain browser APIs or doc properties cause this process to restart, and `elem.offsetWidth` is one of them – he77kat_ Jan 02 '23 at 18:08
23

You can achieve this by binding an onclick listener and then adding the animate class like this:

$('#button').onClick(function(){
    $('#target_element').addClass('animate_class_name');
});
YakovL
  • 7,557
  • 12
  • 62
  • 102
  • 1
    Basically, what you're telling jQuery to do is the following: First line: jQuery targets the element that has ID of button, and creates a function for when the user clicks the element. Second line: This is the element that'll get effected by the click. It targets the element with an id of target_element, and adds the class animate_class_name to that element. Trust me, this solution works, I've used it in the past. – John Fish Dec 07 '11 at 04:12
18

CSS ONLY solution that works on every click and plays the animation to the end:

All you have to do is to add the animation to the :focus pseudo class and set it to none in :active pseudo class.

If your element isn't focusable add tabindex="0" attribute to the html element:

@keyframes beat {
  0% {
    -webkit-transform: scale(1, 1);
            transform: scale(1, 1);
  }
  100% {
    -webkit-transform: scale(0.8,0.8);
            transform: scale(0.8, 0.8);
  }
}
.className {
  background-color:#07d;  
  color: #fff;
  font-family: sans-serif;
  font-size: 20px;
  padding: 20px;
  margin:5px;
  -webkit-transform: scale(1, 1);
          transform: scale(1, 1);
}
.className:focus {
  -webkit-animation: beat 1s ease-in-out backwards;
          animation: beat 1s ease-in-out backwards;
}
.className:active {
  -webkit-animation: none;
          animation: none;
}
body {
  text-align: center;
} 
<h3>Any element with tabindex="0", like a div:</h3>
<div tabindex="0" class="className"> Click me many times!</div>
<h3>Any focusable element like a button:</h3>
<button class="className"> Click me many times!</button>
Abbas Hosseini
  • 1,545
  • 8
  • 21
  • 4
    the one issue I see with this: if I click either of the demo controls then switch tabs, then switch back, the animation plays without clicking it. – Wil Nov 09 '21 at 22:14
6

var  abox = document.getElementsByClassName("box")[0];
function allmove(){
        abox.classList.remove("move-ltr");
        abox.classList.remove("move-ttb");
       abox.classList.toggle("move");
}
function ltr(){
        abox.classList.remove("move");
        abox.classList.remove("move-ttb");
       abox.classList.toggle("move-ltr");
}
function ttb(){
       abox.classList.remove("move-ltr");
       abox.classList.remove("move");
       abox.classList.toggle("move-ttb");
}
.box {
  width: 100px;
  height: 100px;
  background: red;
  position: relative;
}
.move{
  -webkit-animation: moveall 5s;
  animation: moveall 5s;
}
.move-ltr{
   -webkit-animation: moveltr 5s;
  animation: moveltr 5s;
}
.move-ttb{
    -webkit-animation: movettb 5s;
  animation: movettb 5s;
}
@keyframes moveall {
  0%   {left: 0px; top: 0px;}
  25%  {left: 200px; top: 0px;}
  50%  {left: 200px; top: 200px;}
  75%  {left: 0px; top: 200px;}
  100% {left: 0px; top: 0px;}
}
@keyframes moveltr {
  0%   { left: 0px; top: 0px;}
  50%  {left: 200px; top: 0px;}
  100% {left: 0px; top: 0px;}
}
@keyframes movettb {
  0%   {left: 0px; top: 0px;}
  50%  {top: 200px;left: 0px;}
  100% {left: 0px; top: 0px;}
}
<div class="box"></div>
<button onclick="allmove()">click</button>
<button onclick="ltr()">click</button>
<button onclick="ttb()">click</button>
R.K. Roy
  • 71
  • 1
  • 2
5

Add a

-webkit-animation-play-state: paused;

to your CSS file, then you can control whether the animation is running or not by using this JS line:

document.getElementById("myDIV").style.WebkitAnimationPlayState = "running";

if you want the animation to run once, every time you click. Remember to set

-webkit-animation-iteration-count: 1;
Marin Atanasov
  • 3,266
  • 3
  • 35
  • 39
NoteTheNote
  • 473
  • 6
  • 12
2

You can do that by using following code

$('#button_id').on('click', function(){
$('#element_want_to_target').addClass('.animation_class');});
Junaid Raza
  • 171
  • 1
  • 2
  • 8
1

Try this:

<div>
 <p onclick="startAnimation()">Start</p><!--O botão para iniciar (start)-->
 <div id="animation">Hello!</div> <!--O elemento que você quer animar-->
</div>

<style>
@keyframes animationName {
from {margin-left:-30%;}
}
</style>

<script>
function startAnimation() {
    document.getElementById("animation").style.animation = "animationName 2s linear 1";
}
</script>
armatita
  • 12,825
  • 8
  • 48
  • 49
0

Add the animation and remove it after the animation-duration ends using setTimeout()

const elem = document.querySelector(".element");
elem.onclick = () => {
    elem.style.animation="YOUR_ANIMATION";
    setTimeout(()=>{
        elem.style.animation="none";
    },YOUR_ANIMATION_DURATION);
}
Sumit
  • 11
  • 3
0

function start(){
  document.querySelector('#popup-promocoes').style.bottom='-110px';
  document.querySelector('#popup-promocoes').style.display='flex';
  document.querySelector('#popup-promocoes').classList.add('dv-promocoes-show');
}
.dv-promocoes-show {
  animation-name: up;
  animation-duration: 2s;
  animation-fill-mode: forwards;
}

@keyframes up {
  from {opacity:0;bottom:-200px;}
  to {opacity:0.7;bottom:-10px;}
}
<div id="popup-promocoes" style="position:fixed;width:100px;height:100px;background-color:black;display:none;">
</div>
<button onclick="start()">Show</button>
danilo
  • 7,680
  • 7
  • 43
  • 46