How to add gradient to the triangle? - css

How would I be able to apply a gradient color to the triangle?
https://jsfiddle.net/otz9ewm8/
.spinner::before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 27px solid #B76BF0;
transform: translateX(4px);
z-index: 0;
}
How would this be done in the code?
.spinner {
-webkit-appearance: none;
appearance: none;
border: none;
padding: 0;
display: block;
cursor: pointer;
/*background: rgba(255, 255, 255, 0.1);*/
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
box-sizing: border-box;
background-clip: padding-box;
/* -webkit-mask: linear-gradient(rgba(0, 0, 0, 0.1), #000000 90%);*/
width: 90px;
height: 90px;
border-radius: 50%;
transform-origin: 50% 55%;
transform: perspective(90px) rotateX(30deg);
animation: spinner-wiggle 5.2s infinite;
}
.spinner::before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 27px solid #B76BF0;
transform: translateX(4px);
z-index: 0;
}
#keyframes spinner-wiggle {
30% {
transform: perspective(90px) rotateX(10deg);
}
40% {
transform: perspective(90px) rotateX(7deg);
}
50% {
transform: perspective(90px) rotateX(10deg);
}
60% {
transform: perspective(90px) rotateX(8deg);
}
}
.color-circle {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 90px;
height: 90px;
transform-origin: 50% 50%;
background: -webkit-gradient(linear,
left top,
left bottom,
color-stop(50%, #25d8fb),
color-stop(100%, #4f66bb));
border-radius: 50%;
z-index: 0;
box-shadow: inset 0 24px 18px -10px rgba(0, 0, 140, 0.3),
inset 0 0 22px -2px rgba(0, 0, 0, 0.4);
cursor: pointer;
background: linear-gradient(100deg, #24A4EA, #379DEB 25%, #B76BF0);
-webkit-mask-image: radial-gradient(circle, transparent 0 36px, black 36px);
mask-image: radial-gradient(circle, transparent 0 50px, black 20px);
}
.spinner:hover .color-circle {
background: -webkit-gradient(linear,
left top,
left bottom,
color-stop(50%, rgba(34, 204, 0, 0.9)),
color-stop(100%, #55ff00));
}
.color-circle:before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 72px;
height: 72px;
border-radius: 50%;
background-color: #353198;
z-index: 0;
}
.spinner:hover .color-circle {
animation: spin 1.7s infinite linear;
}
#-webkit-keyframes spin {
0% {
transform: rotateZ(0deg);
}
100% {
transform: rotateZ(360deg);
}
}
<div class=" spinner">
<span class="color-circle"></span>
</div>

You can use clip-path instead of borders
background-image: linear-gradient(100deg, #24A4EA, #379DEB 25%, #B76BF0);
clip-path: polygon(0% 0%, 100% 50%, 0% 100%);

Related

how to animate a variable change in css keyframes

I want to animate the waves to go up when i click on the div i cant get the wave to animate when i change the heigt on the animation it self.
.tsx
<div className={styles.circle}>
<div className={styles.wave}></div>
</div>
.css
.circle {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-190%, -50%);
width: 25%;
height: 60%;
background: #ccc;
box-shadow: 0 0 0 5px #fff;
border-radius: 50%;
overflow: hidden;
}
.wave {
position: relative;
width: 100%;
height: 100%;
background: #4973ff;
border-radius: 50%;
box-shadow: inset 0 0 50px rgba(0, 0, 0, 0.5);
}
.wave:before,
.wave:after {
content: "";
position: absolute;
width: 200%;
height: 200%;
top: 0;
left: 50%;
transform: translate(-50%, -75%);
background: #000;
}
.wave:before {
border-radius: 45%;
background: rgb(255, 255, 255);
animation: animate 5s linear infinite;
}
.wave:after {
border-radius: 40%;
background: rgb(255, 255, 255, 0.5);
animation: animate 10s linear infinite;
}
#keyframes animate {
0% {
transform: translate(-50%, var(--water)) rotate(0deg);
}
100% {
transform: translate(-50%, var(--water)) rotate(360deg);
}
}
I tried putting translate: transform 2s linear but that didnt work for me eighter do you guys have any idea beaces when i change the
:root {
--water: -90%
}
to
:root {
--water: -80%
}
it will just snap and not animate

overflow absolute positioned psuedo element of a relative positioned parent set to overflow:hidden

I'm making a skull wearing a hat via CSS (jolly roger) which can be found at this codepen.
In the hat section, the lower edge of it has to be overflowed out of the parent div while the stripe in hat has to have overflow:hidden.
You may open the codepen link in both firefox and chrome to spot the difference.
While my code works fine in Firefox, this doesn't seem to work in chrome. I've tried many solutions that tells about how to position absolute items in a relative parent with overflow:hidden but none of those seem to work. Maybe I'm missing something important.
HTML
<div class="skull">
<div class="skull__face skull__face--animate">
<div class="skull__upper">
<div class="skull__hat"></div>
<div class="skull__nose"></div>
</div>
<div class="skull__lower">
<div class="skull__jaw"></div>
</div>
</div>
<div class="skull__bone skull__bone--left"></div>
<div class="skull__bone skull__bone--right"></div>
</div>
CSS
.skull__upper, .skull__lower {
background-color: white;
border: 7px solid black;
display: flex;
}
.skull__lower::before, .skull__jaw::before, .skull__jaw::after {
content: "";
width: 7px;
height: 6rem;
background-color: black;
display: inline-block;
position: absolute;
bottom: -1.6rem;
left: 0px;
right: 0px;
margin: auto;
}
#-webkit-keyframes boneDance {
0% {
-webkit-transform-origin: 49% 0%;
transform-origin: 49% 0%;
}
50% {
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
100% {
-webkit-transform-origin: 51% 0%;
transform-origin: 51% 0%;
}
}
#keyframes boneDance {
0% {
-webkit-transform-origin: 49% 0%;
transform-origin: 49% 0%;
}
50% {
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
100% {
-webkit-transform-origin: 51% 0%;
transform-origin: 51% 0%;
}
}
#-webkit-keyframes skullDance {
0% {
-webkit-transform: rotate(1deg);
transform: rotate(1deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-1deg);
transform: rotate(-1deg);
}
}
#keyframes skullDance {
0% {
-webkit-transform: rotate(1deg);
transform: rotate(1deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-1deg);
transform: rotate(-1deg);
}
}
#-webkit-keyframes blink {
from {
opacity: 0.4;
}
to {
opacity: 1;
}
}
#keyframes blink {
from {
opacity: 0.4;
}
to {
opacity: 1;
}
}
body {
background-color: #191919;
}
#media only screen and (max-width: 600px) {
body {
font-size: 12px;
}
}
.skull {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10vh;
}
.skull__face {
display: flex;
flex-direction: column;
align-items: center;
z-index: 50;
position: relative;
}
.skull__face::after {
content: "";
width: 13rem;
border-radius: 50%;
box-shadow: 0px 0px 12rem 0 white;
position: absolute;
display: block;
height: 100%;
opacity: 0;
transition: opacity 1s ease-in-out;
}
.skull__face--animate:hover {
-webkit-animation: skullDance 1s steps(3) infinite alternate;
animation: skullDance 1s steps(3) infinite alternate;
cursor: none;
}
.skull__face--animate:hover::after {
opacity: 1;
-webkit-animation: blink 1s linear infinite alternate;
animation: blink 1s linear infinite alternate;
}
.skull__face--animate:hover ~ .skull__bone {
-webkit-animation: boneDance 1s steps(3) infinite alternate;
animation: boneDance 1s steps(3) infinite alternate;
}
.skull__upper {
width: 20rem;
height: 20rem;
border-radius: 50%;
z-index: 50;
position: relative;
}
.skull__upper::before, .skull__upper::after {
content: "";
display: block;
}
.skull__upper::before {
position: absolute;
border-radius: 50%;
box-shadow: 5.5rem 13.5rem 0px 2.8rem black, 14.5rem 13.5rem 0px 2.8rem black;
width: 1px;
height: 1px;
background-color: transparent;
}
.skull__hat {
justify-content: center;
background-color: #FFD020;
width: 20rem;
height: 10rem;
z-index: 45;
border-top-left-radius: calc(10rem + 7px);
border-top-right-radius: calc(10rem + 7px);
overflow: hidden;
}
.skull__hat::before, .skull__hat::after {
content: "";
display: block;
left: 0px;
right: 0px;
margin: auto;
}
.skull__hat::after {
height: 1rem;
background-color: #FFD020;
position: absolute;
border: 7px solid black;
border-radius: 1rem;
width: 30rem;
left: -5.5rem;
}
.skull__hat::before {
width: 18.5rem;
height: 0;
position: relative;
border-bottom: 3rem solid #FF0012;
border-left: 0.75rem solid transparent;
border-right: 0.75rem solid transparent;
margin-top: 5.35rem;
box-shadow: 0px 0px 0px 0px #191919, 0px -7px 0px 0px black;
}
.skull__lower {
width: 14rem;
height: 16rem;
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
z-index: 49;
margin-top: -7rem;
overflow: hidden;
position: relative;
}
.skull__lower::before {
bottom: 4.5rem;
z-index: 40;
}
.skull__nose {
width: 3rem;
height: 2rem;
background: black;
border-radius: 50%;
position: absolute;
bottom: 2rem;
left: 0px;
right: 0px;
margin: auto;
}
.skull__jaw {
width: 21rem;
height: 21rem;
border-radius: 50%;
border: 7px solid black;
position: absolute;
margin: auto;
top: -12.5rem;
left: -4rem;
box-shadow: 0px 1.8rem 0px 0px white, 0px 2.2rem 0px 0px black;
}
.skull__jaw::before {
margin-left: 6.6rem;
-webkit-transform: rotate(10deg);
transform: rotate(10deg);
}
.skull__jaw::after {
margin-right: 6.6rem;
-webkit-transform: rotate(-10deg);
transform: rotate(-10deg);
}
.skull__bone {
background: white;
height: 3rem;
width: 36rem;
position: absolute;
border: 7px solid black;
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
.skull__bone::before, .skull__bone::after {
content: "";
position: absolute;
border-radius: 50%;
top: -1.5rem;
width: 3rem;
height: 3rem;
background: white;
}
.skull__bone::before {
left: -1.5rem;
}
.skull__bone::after {
right: -1.5rem;
}
.skull__bone--left {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.skull__bone--left::before {
box-shadow: 0 3rem 0 white, -2px 3.1rem 0px 2px black, -2px -0.1rem 0px 2px black;
}
.skull__bone--left::after {
box-shadow: 0 3rem 0 white, 3px 3.1rem 0px 1px black, 2px -0.1rem 0px 2px black;
}
.skull__bone--right {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.skull__bone--right::before {
box-shadow: 0 3rem 0 white, -2px 3.1rem 0px 2px black, -2px -0.1rem 0px 2px black;
}
.skull__bone--right::after {
box-shadow: 0 3rem 0 white, 3px 3.1rem 0px 1px black, 2px -0.1rem 0px 2px black;
}
Any suggestions to make it work at least in Firefox and Chrome.
Just removing the z-index from the .skull__hat class did the trick.
.skull__upper, .skull__lower {
background-color: white;
border: 7px solid black;
display: flex;
}
.skull__lower::before, .skull__jaw::before, .skull__jaw::after {
content: "";
width: 7px;
height: 6rem;
background-color: black;
display: inline-block;
position: absolute;
bottom: -1.6rem;
left: 0px;
right: 0px;
margin: auto;
}
#-webkit-keyframes boneDance {
0% {
-webkit-transform-origin: 49% 0%;
transform-origin: 49% 0%;
}
50% {
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
100% {
-webkit-transform-origin: 51% 0%;
transform-origin: 51% 0%;
}
}
#keyframes boneDance {
0% {
-webkit-transform-origin: 49% 0%;
transform-origin: 49% 0%;
}
50% {
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
100% {
-webkit-transform-origin: 51% 0%;
transform-origin: 51% 0%;
}
}
#-webkit-keyframes skullDance {
0% {
-webkit-transform: rotate(1deg);
transform: rotate(1deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-1deg);
transform: rotate(-1deg);
}
}
#keyframes skullDance {
0% {
-webkit-transform: rotate(1deg);
transform: rotate(1deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-1deg);
transform: rotate(-1deg);
}
}
#-webkit-keyframes blink {
from {
opacity: 0.4;
}
to {
opacity: 1;
}
}
#keyframes blink {
from {
opacity: 0.4;
}
to {
opacity: 1;
}
}
body {
background-color: #191919;
}
#media only screen and (max-width: 600px) {
body {
font-size: 12px;
}
}
.skull {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10vh;
}
.skull__face {
display: flex;
flex-direction: column;
align-items: center;
z-index: 50;
position: relative;
}
.skull__face::after {
content: "";
width: 13rem;
border-radius: 50%;
box-shadow: 0px 0px 12rem 0 white;
position: absolute;
display: block;
height: 100%;
opacity: 0;
transition: opacity 1s ease-in-out;
}
.skull__face--animate:hover {
-webkit-animation: skullDance 1s steps(3) infinite alternate;
animation: skullDance 1s steps(3) infinite alternate;
cursor: none;
}
.skull__face--animate:hover::after {
opacity: 1;
-webkit-animation: blink 1s linear infinite alternate;
animation: blink 1s linear infinite alternate;
}
.skull__face--animate:hover ~ .skull__bone {
-webkit-animation: boneDance 1s steps(3) infinite alternate;
animation: boneDance 1s steps(3) infinite alternate;
}
.skull__upper {
width: 20rem;
height: 20rem;
border-radius: 50%;
z-index: 50;
position: relative;
}
.skull__upper::before, .skull__upper::after {
content: "";
display: block;
}
.skull__upper::before {
position: absolute;
border-radius: 50%;
box-shadow: 5.5rem 13.5rem 0px 2.8rem black, 14.5rem 13.5rem 0px 2.8rem black;
width: 1px;
height: 1px;
background-color: transparent;
}
.skull__hat {
justify-content: center;
background-color: #FFD020;
width: 20rem;
height: 10rem;
border-top-left-radius: calc(10rem + 7px);
border-top-right-radius: calc(10rem + 7px);
overflow: hidden;
}
.skull__hat::before, .skull__hat::after {
content: "";
display: block;
left: 0px;
right: 0px;
margin: auto;
}
.skull__hat::after {
height: 1rem;
background-color: #FFD020;
position: absolute;
border: 7px solid black;
border-radius: 1rem;
width: 30rem;
left: -5.5rem;
}
.skull__hat::before {
width: 18.5rem;
height: 0;
position: relative;
border-bottom: 3rem solid #FF0012;
border-left: 0.75rem solid transparent;
border-right: 0.75rem solid transparent;
margin-top: 5.35rem;
box-shadow: 0px 0px 0px 0px #191919, 0px -7px 0px 0px black;
}
.skull__lower {
width: 14rem;
height: 16rem;
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
z-index: 49;
margin-top: -7rem;
overflow: hidden;
position: relative;
}
.skull__lower::before {
bottom: 4.5rem;
z-index: 40;
}
.skull__nose {
width: 3rem;
height: 2rem;
background: black;
border-radius: 50%;
position: absolute;
bottom: 2rem;
left: 0px;
right: 0px;
margin: auto;
}
.skull__jaw {
width: 21rem;
height: 21rem;
border-radius: 50%;
border: 7px solid black;
position: absolute;
margin: auto;
top: -12.5rem;
left: -4rem;
box-shadow: 0px 1.8rem 0px 0px white, 0px 2.2rem 0px 0px black;
}
.skull__jaw::before {
margin-left: 6.6rem;
-webkit-transform: rotate(10deg);
transform: rotate(10deg);
}
.skull__jaw::after {
margin-right: 6.6rem;
-webkit-transform: rotate(-10deg);
transform: rotate(-10deg);
}
.skull__bone {
background: white;
height: 3rem;
width: 36rem;
position: absolute;
border: 7px solid black;
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
.skull__bone::before, .skull__bone::after {
content: "";
position: absolute;
border-radius: 50%;
top: -1.5rem;
width: 3rem;
height: 3rem;
background: white;
}
.skull__bone::before {
left: -1.5rem;
}
.skull__bone::after {
right: -1.5rem;
}
.skull__bone--left {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.skull__bone--left::before {
box-shadow: 0 3rem 0 white, -2px 3.1rem 0px 2px black, -2px -0.1rem 0px 2px black;
}
.skull__bone--left::after {
box-shadow: 0 3rem 0 white, 3px 3.1rem 0px 1px black, 2px -0.1rem 0px 2px black;
}
.skull__bone--right {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.skull__bone--right::before {
box-shadow: 0 3rem 0 white, -2px 3.1rem 0px 2px black, -2px -0.1rem 0px 2px black;
}
.skull__bone--right::after {
box-shadow: 0 3rem 0 white, 3px 3.1rem 0px 1px black, 2px -0.1rem 0px 2px black;
}
<div class="skull">
<div class="skull__face skull__face--animate">
<div class="skull__upper">
<div class="skull__hat"></div>
<div class="skull__nose"></div>
</div>
<div class="skull__lower">
<div class="skull__jaw"></div>
</div>
</div>
<div class="skull__bone skull__bone--left"></div>
<div class="skull__bone skull__bone--right"></div>
</div>

Add border to scaling circles animation

I'm implementing waves animation similar to this:
I want to make the 2px border for each transparent wave circle - what is the best way to achieve this (preferably without width/height animation)?
Currently I'm animating box-shadow property and seems I'm unable(?) to use several shadows to imitate the border as long as I need them to be half-transparent. Also I'm unable to use scale as border-width will be scaled as well. The only way I see here is to animate the actual width/height of each <i> element but I don't think this animation will be smooth on all devices(?)
:root {
--size: 6px;
--duration: 1000ms;
}
body {
background: #333;
}
.blinker {
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
position: absolute;
z-index: 3;
background: #fdfdf9;
width: var(--size);
height: var(--size);
border-radius: 50%;
}
.blinker i {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
content: "";
width: 6px;
height: 6px;
border-radius: 50%;
opacity: 1;
}
.blinker i:nth-child(1) {
animation: blinkBoxShadow var(--duration) ease-out infinite;
display: block;
border: 1px solid white;
}
#keyframes blinkBoxShadow {
from {
box-shadow: 0 0 0 30px trasparent;
background: transparent;
opacity: 1;
}
to {
box-shadow: 0 0 0 30px rgba(255, 255, 255, 0.7);
background: rgba(255, 255, 255, 0.7);
opacity: 0;
}
}
.blinker i:nth-child(2) {
transform: translateX(-50%) translateY(-50%);
width: 61px;
height: 61px;
animation: blinkBoxShadow2 var(--duration) ease-out infinite;
animation-delay: calc(var(--duration) - 200ms);
}
#keyframes blinkBoxShadow2 {
from {
box-shadow: 0 0 0 0px rgba(255, 179, 117, 0.7);
opacity: 0;
}
50% {
opacity: 0.5;
}
to {
box-shadow: 0 0 0 50px rgba(255, 179, 117, 0);
opacity: 0;
}
}
.blinker i:nth-child(3) {
background: white;
}
<div class="blinker">
<i></i>
<i></i>
<i></i>
</div>
If I'm understanding correctly - You can't use box-shadow property, because of it's non-transparent?
If yes, you can set the color of the shadow by using rgba() function, where the last parameter is alpha (transparency) channel value. You can see how it's done on CodePen projects when you type in search bar - 'pulse'.
If no, if you would use JS to animate width/height I think it wouldn't be a efficiency problem on most mobile devices.
I think border should work. Remove box-shadow and animate it on width and height.
See the Snippet below:
:root {
--size: 6px;
--duration: 1000ms;
}
body {
background: #333;
}
.blinker {
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
position: absolute;
z-index: 3;
background: #fdfdf9;
width: var(--size);
height: var(--size);
border-radius: 50%;
}
.blinker i {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
content: "";
width: 6px;
height: 6px;
border-radius: 50%;
opacity: 1;
}
.blinker i:nth-child(1) {
animation: blinkBoxShadow var(--duration) ease-out infinite;
display: block;
border: 2px solid rgba(255, 255, 255, 0.5);
}
#keyframes blinkBoxShadow {
from {
/*box-shadow: 0 0 0 30px trasparent;*/
background: transparent;
opacity: 1;
width:0px;
height:0px;
}
to {
/*box-shadow: 0 0 0 30px rgba(255, 255, 255, 0.7);*/
background: rgba(255, 255, 255, 0.7);
opacity: 0;
width:61px;
height:61px;
}
}
.blinker i:nth-child(2) {
transform: translateX(-50%) translateY(-50%);
width: 61px;
height: 61px;
animation: blinkBoxShadow2 var(--duration) ease-out infinite;
animation-delay: calc(var(--duration) - 500ms);
}
#keyframes blinkBoxShadow2 {
from {
/*box-shadow: 0 0 0 0px rgba(255, 179, 117, 0.7);*/
background:transparent;
opacity: 0;
border:2px solid rgba(255, 179, 117, 0);
width: 61px;
height: 61px;
}
50% {
opacity: 0.5;
}
to {
/*box-shadow: 0 0 0 50px rgba(255, 179, 117, 0);*/
background:rgba(255, 179, 117, 0.2);
opacity: 0;
width:140px;
height:140px;
border:2px solid rgba(255, 179, 117, 0.2);
}
}
.blinker i:nth-child(3) {
background: white;
}
<div class="blinker">
<i></i>
<i></i>
<i></i>
</div>

Faded border loading spinner in CSS

How can I make the last part of the spinner lighter (ie. fading):
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 5px solid transparent;
border-top-color: #aaa;
border-right-color: #aaa;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="loader-wrapper">
<div id="loader"></div>
</div>
I tried using gradient but it converts it to a square
You can apply the gradient to a pseudo-element like so:
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 5px solid transparent;
border-top-color: #aaa;
border-right-color: #aaa;
animation: spin 2s linear infinite;
}
#loader::after {
content: '';
width: 85%;
height: 85%;
background: linear-gradient(45deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) 40%, rgba(255, 255, 255, 0.7) 60%, rgba(255, 255, 255, 0) 100%);
position: absolute;
top: 0;
left: 0;
transform: translate(-5%, -5%);
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="loader-wrapper">
<div id="loader"></div>
</div>
Here is another idea with less code and without using pseudo element.
.loader {
--border-width: 5px;
height: 150px;
width: 150px;
border-radius: 50%;
/* 0.5px's are needed to avoid hard-stopping */
--mask: radial-gradient(
farthest-side,
transparent calc(100% - var(--border-width) - 0.5px),
#000 calc(100% - var(--border-width) + 0.5px)
);
-webkit-mask: var(--mask);
mask: var(--mask);
background: linear-gradient(#aaa 30%, transparent 80%) 0 0/50% 100% no-repeat; /* this is our border image */
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div class="loader"></div>
And this is the comparison of my answer with #Ricky's answer by setting background to body:
#Ricky's way:
body {
background: pink; /* just added this */
}
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 5px solid transparent;
border-top-color: #aaa;
border-right-color: #aaa;
animation: spin 2s linear infinite;
}
#loader::after {
content: '';
width: 85%;
height: 85%;
background: linear-gradient(45deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) 40%, rgba(255, 255, 255, 0.7) 60%, rgba(255, 255, 255, 0) 100%);
position: absolute;
top: 0;
left: 0;
transform: translate(-5%, -5%);
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="loader-wrapper">
<div id="loader"></div>
</div>
My way:
body {
background: pink; /* just added this */
}
.loader {
--border-width: 5px;
height: 150px;
width: 150px;
border-radius: 50%;
/* 0.5px's are needed to avoid hard-stopping */
--mask: radial-gradient(
farthest-side,
transparent calc(100% - var(--border-width) - 0.5px),
#000 calc(100% - var(--border-width) + 0.5px)
);
-webkit-mask: var(--mask);
mask: var(--mask);
background: linear-gradient(#aaa 30%, transparent 80%) 0 0/50% 100% no-repeat; /* this is our border image */
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div class="loader"></div>

CSS3 border animation ghost

I have this little border animation but has a ghost in the left top corner, a black dot, I don't know how to get rid of it... You can check it here: http://codepen.io/xaeoc/pen/xGRgze
body {
background-color: #333;
height: 230px;
}
.lluv {
width: 230px;
height: 230px;
border: solid red 1px;
position: absolute;
left: calc(50% - 115px);
}
.ondas1 {
border-radius: 50%;
border-width: 3px;
border-style: solid;
position: absolute;
animation: ondas1 1s ease-out;
}
#keyframes ondas1 {
0% {
width: 0px;
height: 0px;
top: calc(50% - 0px);
left: calc(50% - 0px);
border-color: rgba(255, 255, 255, .7);
}
100% {
width: 200px;
height: 200px;
top: calc(50% - 100px);
left: calc(50% - 100px);
border-color: rgba(255, 255, 255, 0);
}
}
use forwards should be animation: ondas1 1s ease-out forwards;
demo - http://codepen.io/victorfdes/pen/EjNWNY
more explanation about animation-fill-mode
after the animation is complete it goes to default state which has border 3px thats the reason you are seeing the rounded element at the left top once you use forwards the animation doesnt go the the default stated instead it goes to the last state in the keyframe
It's due to the border in ondas1. This should remedy your issue.
Sample
CSS
body {
background-color: #333;
height: 230px;
}
.lluv {
width: 230px;
height: 230px;
border: solid red 1px;
position: relative;
overflow: hidden;
left: calc(50% - 115px);
}
.ondas1 {
border-radius: 50%;
border-width: 3px;
border-style: solid;
left:-10px;
position: absolute;
animation: ondas1 1s ease-out;
}
#keyframes ondas1 {
0% {
width: 0px;
height: 0px;
top: calc(50% - 0px);
left: calc(50% - 0px);
border-color: rgba(255, 255, 255, .7);
}
100% {
width: 200px;
height: 200px;
top: calc(50% - 100px);
left: calc(50% - 100px);
border-color: rgba(255, 255, 255, 0);
}
}

Resources