Reputation: 74008
I need to create a loading spinner, at the moment I am using the following code.
I would like to know if is possible to rewrite it using an alternative syntax for keyframes
(maybe transitions?).
Unfortunately I am using a build tool which rewrite keyframes
properties adding bugs and the CSS generated is not working so I would like to work around the problem.
A JS solution is also possible, adding CSS inline.
.loadingSpinner {
width: 50px;
height: 50px;
border: 5px solid #3498db;
border-top-color: rgba(0, 0, 0, 0);
border-left-color: rgba(0, 0, 0, 0);
border-radius: 50%;
-moz-animation: loadingSpinner 0.7s infinite linear;
-o-animation: loadingSpinner 0.7s infinite linear;
-webkit-animation: loadingSpinner 0.7s infinite linear;
animation: loadingSpinner 0.7s infinite linear;
}
@-moz-keyframes loadingSpinner {
0% {
-moz-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
}
}
@-o-keyframes loadingSpinner {
0% {
-o-transform: rotate(0deg);
}
100% {
-o-transform: rotate(360deg);
}
}
@-webkit-keyframes loadingSpinner {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes loadingSpinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div class="loadingSpinner"></div>
Upvotes: 5
Views: 3433
Reputation: 29521
You can create an infinite CSS transition
using a single CSS Custom Property, the value of which you can update every time the JavaScript transitionend
event fires.
In the CSS stylesheet, we can start with the following transform
and transition
:
transform: var(--rotation);
transition: transform 0.7s linear;
We will need to initialise --rotation
, so we can do that at the top of the stylesheet:
:root {
--rotation: rotate(0deg);
}
So far, so good. Now we need a JS function which moves the rotation value up by 360deg
every time the transition completes:
const rotateSpinner = () => {
let loadingSpinnerStyles = window.getComputedStyle(loadingSpinner);
let rotation = loadingSpinnerStyles.getPropertyValue('--rotation');
rotation = parseInt(rotation.replace('rotate(', '').replace('deg)', '')) + 360;
rotation = 'rotate(' + rotation + 'deg)';
loadingSpinner.style.setProperty('--rotation', rotation);
}
When we put everything together, we get the working example below.
Working Example:
const loadingSpinner = document.querySelector('.loadingSpinner');
const rotateSpinner = () => {
let loadingSpinnerStyles = window.getComputedStyle(loadingSpinner);
let rotation = loadingSpinnerStyles.getPropertyValue('--rotation');
rotation = parseInt(rotation.replace('rotate(', '').replace('deg)', '')) + 360;
rotation = 'rotate(' + rotation + 'deg)';
loadingSpinner.style.setProperty('--rotation', rotation);
}
loadingSpinner.addEventListener('transitionend', rotateSpinner);
window.addEventListener('load', rotateSpinner);
:root {
--rotation: rotate(0deg);
}
.loadingSpinner {
width: 50px;
height: 50px;
border: 5px solid #3498db;
border-top-color: rgba(0, 0, 0, 0);
border-left-color: rgba(0, 0, 0, 0);
border-radius: 50%;
transform: var(--rotation);
transition: transform 0.7s linear;
}
<div class="loadingSpinner"></div>
Upvotes: 0
Reputation: 457
what about only css solution?
@keyframes spinner {
to {transform: rotate(360deg);}
}
@-webkit-keyframes spinner {
to {-webkit-transform: rotate(360deg);}
}
.spinner {
min-width: 30px;
min-height: 30px;
}
.spinner:before {
content: 'Loading…';
position: absolute;
top: 50%;
left: 50%;
width: 50px;
height: 50px;
margin-top: -13px;
margin-left: -13px;
}
.spinner:not(:required):before {
content: '';
border-radius: 50%;
border: 5px solid #ccc;
border-top-color: #03ade0;
animation: spinner .7s linear infinite;
-webkit-animation: spinner .7s linear infinite;
}
<div class="spinner"></div>
Upvotes: 0
Reputation: 3194
You could use a very long transition and trigger it with a quick js line. For example, add a .start class that triggers a 60 second transition that rotates the spinner several times (for example, 36000deg).
.loadingSpinner {
width: 50px;
height: 50px;
border: 5px solid #3498db;
border-top-color: rgba(0, 0, 0, 0);
border-left-color: rgba(0, 0, 0, 0);
border-radius: 50%;
transform: rotate(0deg);
transition: transform 60s;
}
.loadingSpinner.start {
transform: rotate(36000deg);
}
Example: https://jsfiddle.net/6tkf1f95/1/
Upvotes: 3