'keyframes are not animating the transforms property properly
So, I am making an animated toggle component in react js, and to achieve that I am using keyframes to animate the properties, but it is not working as expected.
Here is the slow-motion video of the animation I want to achieve. video link
Here is the video of what my animation actually does video link
As you can see that there is a glitch, when it unchecks, this is because the dot in the center scales to 0 before the border width has fully occupied the space
Here is the link for the codesandbox
Here is the code for the CSS
*,
*::after,
*::before {
box-sizing: border-box;
}
.App {
font-family: sans-serif;
text-align: center;
}
.payment-container {
position: absolute;
right: 4%;
top: 12%;
width: 300px;
/* width: 25%; */
height: 80%;
border-radius: 4px;
background-color: #ececec;
/* background-color: rgba(209, 209, 209, 0.5); */
padding: 1rem;
}
.payment-container h2 {
margin-block: 0;
font-family: "Poppins", sans-serif;
}
.payment-method {
display: flex;
flex-direction: column;
}
.payment-container .subtitle {
color: rgb(107, 107, 107);
font-family: "Poppins", sans-serif;
font-weight: 500;
font-size: 15px;
}
.radio_button_input {
opacity: 0;
position: absolute;
padding: 0;
z-index: 1;
margin-top: 6px;
cursor: pointer;
transform: scale(1.25);
}
.circle {
position: relative;
display: inline-block;
width: 20px;
height: 20px;
vertical-align: middle;
background-color: inherit;
color: #017b5f;
border: 2px solid #b9b9b9;
border-radius: 24px;
opacity: 1;
}
.circle::after {
content: "";
display: block;
position: relative;
top: 13%;
left: 13%;
width: 12px;
z-index: 5;
height: 12px;
background-color: #727171;
border-radius: 12px;
}
.radio_button_input:checked + .circle::after {
background-color: #01a982;
}
.radio_button_input:not(:checked) + .circle::after {
background-color: #b9b9b9;
animation: borderDot 2s linear;
animation-fill-mode: forwards;
}
@keyframes borderDot {
0% {
transform: scale(1);
}
24% {
transform: scale(1.35);
}
25% {
transform: scale(0);
}
100% {
transform: scale(0);
}
}
.radio_button_input:checked + .circle {
border-color: #01a982;
transition: all 1s;
}
.circle {
transform: scale(0.85);
}
.radio_button_input:not(:checked) + .circle {
animation: borderWidths 2s linear;
animation-fill-mode: forwards;
}
@keyframes borderWidths {
0% {
transform: scale(0.85);
border-width: 2px;
}
24% {
border-width: 2px;
}
25% {
transform: scale(0.75);
border-width: 10px;
}
50% {
transform: scale(0.85);
border-width: 2px;
}
75% {
}
100% {
transform: scale(0.85);
border-width: 2px;
}
}
.flex-container {
display: flex;
align-items: center;
gap: 1rem;
margin-top: 0.5rem;
}
Here is the js code
import { useState } from "react";
import "./styles.css";
import { CreditCard } from "react-feather";
export default function App() {
const [method, setMethod] = useState({
pay_method: "card"
});
const handleChange = (e) => {
const { name, value } = e.target;
setMethod({
pay_method: name
});
};
return (
<div className="App">
<div className="payment-container">
<h2>Payment Info.</h2>
<div className="payment-method">
<span className="subtitle">Payment Method:</span>
<div className="flex-container">
<div>
<input
type="radio"
className="radio_button_input"
id="card_radio"
name="card"
checked={method?.pay_method == "card"}
onChange={handleChange}
/>
<span className="circle"></span>
</div>
<CreditCard size={"18px"} />
<span>Credit Card</span>
</div>
<div className="flex-container">
<input
type="radio"
className="radio_button_input"
id="paypal_radio"
name="paypal"
checked={method?.pay_method == "paypal"}
onChange={handleChange}
/>
<span className="circle"></span>
<svg
width={"18px"}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 384 512"
>
<path d="M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z" />
</svg>
<span className="radio-button-label">Paypal</span>
</div>
</div>
</div>
</div>
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
