Playing with web technologies, I developed a dice using just HTML and CSS (without JavaScript). It's a simple system: a series of radio buttons and labels that simulate the dice by changing their positioning (with z-index
) so every time that you click on the dice, there's a "random" number.
This is a minimal version of the code:
@keyframes changeOrder {
from { z-index: 6;}
to { z-index: 1; }
}
@-webkit-keyframes changeOrder {
from { z-index: 6; }
to { z-index: 1; }
}
label {
display: block;
position: absolute;
display: block;
width: 50px;
height: 50px;
line-height:50px;
background: #eeeeee;
text-align: center;
animation: changeOrder 1.2s infinite;
}
label:nth-of-type(1) { animation-delay: 0s; }
label:nth-of-type(2) { animation-delay: -0.2s; }
label:nth-of-type(3) { animation-delay: -0.4s; }
label:nth-of-type(4) { animation-delay: -0.6s; }
label:nth-of-type(5) { animation-delay: -0.8s; }
label:nth-of-type(6) { animation-delay: -1.0s; }
<input type="radio" name="cb" id="cb1" value="1"/>
<input type="radio" name="cb" id="cb2" value="2"/>
<input type="radio" name="cb" id="cb3" value="3"/>
<input type="radio" name="cb" id="cb4" value="4"/>
<input type="radio" name="cb" id="cb5" value="5"/>
<input type="radio" name="cb" id="cb6" value="6"/>
<label for="cb1">1</label>
<label for="cb2">2</label>
<label for="cb3">3</label>
<label for="cb4">4</label>
<label for="cb5">5</label>
<label for="cb6">6</label>
The problem happens when, even when the dice is rolling, it not always takes action when the label
is clicked on, and the radio button associated to the label
is not activated. Sometimes it does, sometimes it doesn't.
I thought it could be because of the animation I used, and (unsuccessfully) played with the times to see if that would fix the problem... but it basically remains the same. I noticed that if I extend the times, the issue "disappears" (i.e. changing the times to 3s and delays in 0.5s or higher). But if I do that, it is more predictable (the goal is not to make it perfect but at least simulate some pseudo-randomness).
Why could this be happening? What can I do to fix it?
As you already noticed it, the issue is due to how fast the animation is. The changes is faster than the click because a click is two actions: mousedown
and mouseup
and both should be done on the same element.
Here is a better illustration of the issue where you can NEVER make the input checked by clicking on the labels:
label {
display: block;
position: absolute;
display: block;
width: 50px;
height: 50px;
line-height:50px;
background: #eeeeee;
text-align: center;
}
label:active {
background:red;
z-index:-1;
}
<input type="radio" name="cb" id="cb1" value="1">
<input type="radio" name="cb" id="cb2" value="2">
<label for="cb1">1</label>
<label for="cb2">2</label>
When clicking, the element will be hidden and the mouseup
will no more be on the same element thus the click event is not done. The same is happening with your example is some cases.
An Idea to fix this is to allow the click to end by making the clicked element on the top until the end of the click event.
Here is an idea where I rely on a pseudo element with a big z-index
so I can keep the click event on the needed element. You can also make the animation faster!
.container {
position:relative;
}
label {
display:block;
position: absolute;
top:0;
left:0;
width: 50px;
height: 50px;
line-height:50px;
background: #eeeeee;
text-align: center;
animation: changeOrder 0.6s infinite;
}
@keyframes changeOrder {
from { z-index: 6;}
to { z-index: 1; }
}
label:nth-of-type(1) { animation-delay: 0s; }
label:nth-of-type(2) { animation-delay: -0.1s; }
label:nth-of-type(3) { animation-delay: -0.2s; }
label:nth-of-type(4) { animation-delay: -0.3s; }
label:nth-of-type(5) { animation-delay: -0.4s; }
label:nth-of-type(6) { animation-delay: -0.5s; }
label:active {
/*Mandatory to break the stacking context and allow
the pseudo element to be above everything*/
position:static;
/*For illustration*/
margin-left: 50px;
background:red;
}
label:active::before {
content:"";
position:absolute;
top:0;
right:0;
left:0;
bottom:0;
z-index:10;
}
<input type="radio" name="cb" id="cb1" value="1">
<input type="radio" name="cb" id="cb2" value="2">
<input type="radio" name="cb" id="cb3" value="3">
<input type="radio" name="cb" id="cb4" value="4">
<input type="radio" name="cb" id="cb5" value="5">
<input type="radio" name="cb" id="cb6" value="6">
<div class="container">
<label for="cb1">1</label>
<label for="cb2">2</label>
<label for="cb3">3</label>
<label for="cb4">4</label>
<label for="cb5">5</label>
<label for="cb6">6</label>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With