Codepen animation works in Chrome but doesn't work in Mozilla, what's wrong?
The codepen code ( http://codepen.io/msisto/pen/lCofE ) displays the correct animations when it runs in Chrome, but does NOT display correctly when I open it in Mozilla Fire Fox. Is there something missing in the code block or do I need to include any lines to make the code work in Mozilla?
The CSS code looks like this: -
// Customize
$option-color: #cbd1d8;
$checked-option-color: #40e0d0;
$option-size: 40px;
$explosion-distance: 5; // Multiplied by $option-size
$explosion-duration: 0.65s;
// On-click animation
@include keyframes(click-wave) {
$offset: ((($option-size*$explosion-distance)-$option-size)/2);
0% {
@include size($option-size);
opacity: 0.35;
position: relative;
}
100% {
@include size($option-size*$explosion-distance);
margin-left: -$offset;
margin-top: -$offset;
opacity: 0.0;
}
}
// Checkbox/Radio replacement
.option-input {
@include appearance(none);
@include position($option-size/3 0 0 0);
@include size($option-size);
@include transition;
background: $option-color;
border: none;
color: #fff;
cursor: pointer;
display: inline-block;
outline: none;
position: relative;
margin-right: 0.5rem;
z-index: 1000;
&:hover {
background: darken($option-color, 15%);
}
&:checked {
background: $checked-option-color;
// The checkmark
&::before {
@include size($option-size);
@include position(absolute);
content: '\2716';
display: inline-block;
font-size: $option-size/1.5;
text-align: center;
line-height: $option-size;
}
// The "wave"
&::after {
@include animation(click-wave $explosion-duration);
background: $checked-option-color;
content: '';
display: block;
position: relative;
z-index: 100;
}
}
&.radio {
border-radius: 50%;
&::after {
border-radius: 50%;
}
}
}
// Demo styles
body {
@include box(horizontal, start, stretch);
background: #e8ebee;
color: darken($option-color, 15%);
font-family: $helvetica;
text-align: center;
div {
padding: 5rem;
}
label {
display: block;
line-height: $option-size;
}
}
source to share
Why?
The problem is with the pseudo-elements of the input tag; because they are invalid elements, they are technically not allowed pseudo-elements (which are technically children). Chrome works because it doesn't strictly follow the rules, Firefox shows the correct behavior.
To make this clear, it is that ::before
, and ::after
is similar to div:
<div>
<span>I am :before</span>
I am content of div
<span>I am :after</span>
</div>
he creates two children in him. This is not possible on input as it cannot have children.
Here is another question I answered that had the same problem and had the same solution.
Decision?
-
Create a checkbox replacement with the label element itself. The label is connected to the corresponding input with matching and identifier attributes.
-
When a checkbox is checked, the corresponding label is targeted
input:checked + label
to select only the next label after input -
The actual label text is placed in the gap so it can be pushed outside of your checkbox
It looks like this:
<input id="check-one" type="checkbox" class="option-input checkbox" CHECKED />
<label for="check-one"><span>Hello</span></label>
Working example
This is not ideal and will need to be adjusted; this is just to give you a general idea.
Here's your new code and a demo in vanilla CSS below:
input[type=checkbox],
input[type=radio] {
display: none;
}
@-webkit-keyframes click-wave {
0% {
height: 40px;
width: 40px;
opacity: 0.35;
position: relative;
}
100% {
height: 200px;
width: 200px;
margin-left: -80px;
margin-top: -80px;
opacity: 0.0;
}
}
@-moz-keyframes click-wave {
0% {
height: 40px;
width: 40px;
opacity: 0.35;
position: relative;
}
100% {
height: 200px;
width: 200px;
margin-left: -80px;
margin-top: -80px;
opacity: 0.0;
}
}
@keyframes click-wave {
0% {
height: 40px;
width: 40px;
opacity: 0.35;
position: relative;
}
100% {
height: 200px;
width: 200px;
margin-left: -80px;
margin-top: -80px;
opacity: 0.0;
}
}
.option-input + label {
-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
position: relative;
top: 13.33333px;
right: 0;
bottom: 0;
left: 0;
height: 40px;
width: 40px;
-webkit-transition: all 0.15s ease-out 0s;
-moz-transition: all 0.15s ease-out 0s;
transition: all 0.15s ease-out 0s;
background: #cbd1d8;
border: none;
color: #fff;
cursor: pointer;
display: inline-block;
outline: none;
position: relative;
margin-right: 0.5rem;
z-index: 1000;
}
.option-input + label span {
position: absolute;
left: 100%;
color: #000;
margin-left: 10px;
}
.option-input + label:hover {
background: #9faab7;
}
.option-input + label.radio {
border-radius: 50%;
}
.option-input + label.radio::after {
border-radius: 50%;
}
.option-input:checked + label {
background: #40e0d0;
}
.option-input:checked + label::before {
height: 40px;
width: 40px;
position: absolute;
content: '\2716';
display: inline-block;
font-size: 26.66667px;
text-align: center;
line-height: 40px;
left: 0;
}
.option-input:checked + label::after {
-webkit-animation: click-wave 0.65s;
-moz-animation: click-wave 0.65s;
animation: click-wave 0.65s;
background: #40e0d0;
content: '';
display: block;
position: relative;
z-index: 100;
pointer-events: none;
}
body {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-pack: start;
-moz-box-pack: start;
box-pack: start;
-ms-flex-pack: start;
-webkit-box-align: stretch;
-moz-box-align: stretch;
box-align: stretch;
-ms-flex-align: stretch;
background: #e8ebee;
color: #9faab7;
font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
text-align: center;
}
body div {
padding: 5rem;
}
body label {
display: block;
line-height: 40px;
}
<div>
<input id="check-one" type="checkbox" class="option-input checkbox" CHECKED />
<label for="check-one"><span>Hello</span>
</label>
</div>
<div>
<input id="radio-one" type="radio" class="option-input radio" name="example" />
<label for="radio-one" class="radio"><span>Hello</span>
</label>
</div>
source to share