0

I have two spinners, one with borders and a keyframes animation, the other one blank. If I target both spinners with jQuery, only the blank spinner is working.

I thought that maybe the ::before pseudo element was blocking the "click" when you hover over the element, but as you can see here, that's also on the second spinner.

What (else) can be the problem?

$(".spinner").click(function() {
  $(this).toggleClass("scale");
});
*,
*::before,
*::after {
  box-sizing: border-box;
}

body,
html {
  height: 100%;
  margin: 0;
}

body {
  background: #ccc;
}

.spinner {
  width: 100px;
  height: 100px;
  background: #E2E2E2;
  border-radius: 50%;
  position: relative;
  margin: 50px;
  display: inline-block;
  transition: transform .2s ease-in-out;
}

.spinner:after,
.spinner:before {
  content: "";
  display: block;
  width: 100px;
  height: 100px;
  border-radius: 50%;
}

.spinner-1 {
  border-left: 2px solid red;
  border-right: 2px solid blue;
  border-top: none;
  border-bottom: none;
  animation: spin-1 1s ease-in-out infinite;
}

@keyframes spin-1 {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.scale {
  transform: scale(1.1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="spinner spinner-1"></div>
<div class="spinner spinner-2"></div>
Jos van Weesel
  • 2,128
  • 2
  • 12
  • 27
  • 1
    because the transform of the animation is more specific and overriding the transform of the class ... it's an XY problem, you are targetting both but the issue is somewhere else [I commenting until I find the dup, I know one ...] – Temani Afif Jun 12 '18 at 21:57
  • the need part in the duplicate answer is the reference to the specification – Temani Afif Jun 12 '18 at 22:07

2 Answers2

1

The problem is that the transform defined by the scale class is overwritten by the transform defined in the class of the first element.

$(".spinner").click(function() {
  $(this).toggleClass("scale");
});
*,
*::before,
*::after {
  box-sizing: border-box;
}

body,
html {
  height: 100%;
  margin: 0;
}

body {
  background: #ccc;
}

.spinner {
  width: 100px;
  height: 100px;
  background: #E2E2E2;
  border-radius: 50%;
  position: relative;
  margin: 50px;
  display: inline-block;
  transition: transform .2s ease-in-out;
}

.spinner:after,
.spinner:before {
  content: "";
  display: block;
  width: 100px;
  height: 100px;
  border-radius: 50%;
}

.spinner-1 {
  border-left: 2px solid red;
  border-right: 2px solid blue;
  border-top: none;
  border-bottom: none;
  animation: spin-1 1s ease-in-out infinite;
}

@keyframes spin-1 {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.scale {
  transform: scale(1.1);
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="spinner spinner-1"></div>
<div class="spinner spinner-2"></div>

The problem can be solved by adding an additional css rule:

$(".spinner").click(function() {
  $(this).toggleClass("scale");
});
*,
*::before,
*::after {
  box-sizing: border-box;
}

body,
html {
  height: 100%;
  margin: 0;
}

body {
  background: #ccc;
}

.spinner {
  width: 100px;
  height: 100px;
  background: #E2E2E2;
  border-radius: 50%;
  position: relative;
  margin: 50px;
  display: inline-block;
  transition: transform .2s ease-in-out;
}

.spinner:after,
.spinner:before {
  content: "";
  display: block;
  width: 100px;
  height: 100px;
  border-radius: 50%;
}

.spinner-1 {
  border-left: 2px solid red;
  border-right: 2px solid blue;
  border-top: none;
  border-bottom: none;
  animation: spin-1 1s ease-in-out infinite;
}

@keyframes spin-1 {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
@keyframes spin-1-scaled {
  from {
    transform: scale(1.1) rotate(0deg);
  }
  to {
    transform: scale(1.1) rotate(360deg);
  }
}

.scale {
  transform: scale(1.1);
}
.scale.spinner-1 {
  animation: spin-1-scaled 1s ease-in-out infinite;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="spinner spinner-1"></div>
<div class="spinner spinner-2"></div>
Lukas Bach
  • 3,559
  • 2
  • 27
  • 31
  • Thanks! I hadn't even thought of the transform property overwriting the already existing transform property. I am aware that you need to implement all transforms into one property, but it just didn't occur to me :) – Jos van Weesel Jun 13 '18 at 10:42
0

Your issue has to do with the transform.

I created a jsfiddle of your code:

https://jsfiddle.net/ethanryan/w3tkyuar/

And added background-color: green to .scale in the css:

.scale {
  transform: scale(1.1);
  background-color: green;
}

As you can see on click, each spinner changes color to green.

So the issue is not with the toggleClass.

If you comment out the @keyframes spin-1, you'll see that the .scale works.

Ethan Ryan
  • 467
  • 10
  • 16