So I'm trying to create a custom checkbox using CSS and clip-path. I have that creating and working just fine. Now the problem is when I check the box the border disappears. Not sure why this is happening. Any help would be great. Also, here is a link to the codepen that I'm currently working on. https://codepen.io/Brushel/pen/qPovdB?editors=0110
body {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
margin-top: 2em;
}
.title {
text-align: center;
font-weight: 300;
}
label[for="checked"] {
padding-right: 10px;
padding-left: 10px;
}
#checked[type="checkbox"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 1px solid #333;
height: 25px;
width: 25px;
cursor: pointer;
}
#checked[type="checkbox"]:after {
-webkit-clip-path: polygon(21% 40%, 21% 40%, 8% 54%, 25% 68%, 36% 77%, 47% 65%, 48% 64%, 64% 47%, 75% 35%, 93% 13%, 81% 4%, 36% 54%);
clip-path: polygon(21% 40%, 21% 40%, 8% 54%, 25% 68%, 36% 77%, 47% 65%, 48% 64%, 64% 47%, 75% 35%, 93% 13%, 81% 4%, 36% 54%);
background: #333;
height: 25px;
width: 25px;
}
#checked[type="checkbox"]:checked {
-webkit-clip-path: polygon(21% 40%, 21% 40%, 8% 54%, 25% 68%, 36% 77%, 47% 65%, 48% 64%, 64% 47%, 75% 35%, 93% 13%, 81% 4%, 36% 54%);
clip-path: polygon(21% 40%, 21% 40%, 8% 54%, 25% 68%, 36% 77%, 47% 65%, 48% 64%, 64% 47%, 75% 35%, 93% 13%, 81% 4%, 36% 54%);
background: #333;
height: 25px;
width: 25px;
-webkit-transition-duration: .3s;
transition-duration: .3s;
}
label[for="customcheckbox"] {
padding-right: 10px;
padding-left: 10px;
}
#customcheckbox[disabled="disabled"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 0.5px solid #b3b3b3;
height: 25px;
width: 25px;
cursor: not-allowed;
}
#customcheckbox[disabled="disabled"] {
background: #ccc;
}
#three[type="checkbox"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 1px solid #333;
height: 25px;
width: 25px;
}
#three[type="checkbox"]:not(:checked) {
background: white;
}
#three[type="checkbox"]:checked {
-webkit-clip-path: polygon(21% 40%, 21% 40%, 8% 54%, 25% 68%, 36% 77%, 47% 65%, 48% 64%, 64% 47%, 75% 35%, 93% 13%, 81% 4%, 36% 54%);
clip-path: polygon(21% 40%, 21% 40%, 8% 54%, 25% 68%, 36% 77%, 47% 65%, 48% 64%, 64% 47%, 75% 35%, 93% 13%, 81% 4%, 36% 54%);
background: #333;
height: 25px;
width: 25px;
}
#three[type="checkbox"]:after {
-webkit-clip-path: polygon(21% 40%, 21% 40%, 8% 54%, 25% 68%, 36% 77%, 47% 65%, 48% 64%, 64% 47%, 75% 35%, 93% 13%, 81% 4%, 36% 54%);
clip-path: polygon(21% 40%, 21% 40%, 8% 54%, 25% 68%, 36% 77%, 47% 65%, 48% 64%, 64% 47%, 75% 35%, 93% 13%, 81% 4%, 36% 54%);
background: #333;
height: 25px;
width: 25px;
}
<body>
<div class='container'>
<h4 class='title'>Checkboxes Via Clip-Path</h4>
<label for='checked' id='plus'>This</label>
<input id='checked' type='checkbox'>
<label for='checked' id='plus'>That</label>
<input id='checked' type='checkbox'>
<!-- / Start of the second checkbox -->
<h4 class='title'>Disabled Checkbox</h4>
<label for='customcheckbox' id='plus'>This</label>
<input disabled='disabled' id='customcheckbox' type='checkbox'>
<label for='customcheckbox' id='plus'>That</label>
<input disabled='disabled' id='customcheckbox' type='checkbox'>
<h4 class='title'>Checkbox via SVG</h4>
<label for='three'>This</label>
<input id='three' type='checkbox'>
<label for='three'>That</label>
<input id='three' type='checkbox'>
</div>
</body>
Related
When I try to activate any effect on a picture in my master page it just messes the whole order of the page and just ruins it. How can I fix it?
I just want a cool effect on my website.
body {
padding: 0;
margin: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #000;
}
.glitch {
position: relative;
overflow: hidden;
}
.glitch img {
position: relative;
z-index: 1;
display: block;
}
.glitch__layers {
position: absolute;
z-index: 2;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.glitch__layer {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-image: url(https://images.unsplash.com/photo-1561019733-a84b4e023910?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80);
background-repeat: no-repeat;
background-position: 0 0;
}
.glitch__layer:nth-child(1) {
transform: translateX(-5%);
animation: glitch-anim-1 2s infinite linear alternate;
}
.glitch__layer:nth-child(2) {
transform: translateX(3%) translateY(3%);
animation: glitch-anim-2 2.3s -.8s infinite linear alternate;
}
.glitch__layer:nth-child(3) {
transform: translateX(5%);
animation: glitch-anim-flash 1s infinite linear;
}
#keyframes glitch-anim-1 {
0% {
clip-path: polygon(0 0%, 100% 0%, 100% 5%, 0 5%);
}
10% {
clip-path: polygon(0 15%, 100% 15%, 100% 15%, 0 15%);
}
20% {
clip-path: polygon(0 10%, 100% 10%, 100% 20%, 0 20%);
}
30% {
clip-path: polygon(0 1%, 100% 1%, 100% 2%, 0 2%);
}
40% {
clip-path: polygon(0 35%, 100% 35%, 100% 35%, 0 35%);
}
50% {
clip-path: polygon(0 45%, 100% 45%, 100% 46%, 0 46%);
}
60% {
clip-path: polygon(0 50%, 100% 50%, 100% 70%, 0 70%);
}
70% {
clip-path: polygon(0 70%, 100% 70%, 100% 70%, 0 70%);
}
80% {
clip-path: polygon(0 80%, 100% 80%, 100% 80%, 0 80%);
}
90% {
clip-path: polygon(0 50%, 100% 50%, 100% 55%, 0 55%);
}
100% {
clip-path: polygon(0 60%, 100% 60%, 100% 70%, 0 70%);
}
}
#keyframes glitch-anim-2 {
0% {
clip-path: polygon(0 15%, 100% 15%, 100% 30%, 0 30%);
}
15% {
clip-path: polygon(0 3%, 100% 3%, 100% 3%, 0 3%);
}
25% {
clip-path: polygon(0 8%, 100% 8%, 100% 20%, 0 20%);
}
30% {
clip-path: polygon(0 20%, 100% 20%, 100% 20%, 0 20%);
}
45% {
clip-path: polygon(0 45%, 100% 45%, 100% 45%, 0 45%);
}
50% {
clip-path: polygon(0 50%, 100% 50%, 100% 57%, 0 57%);
}
65% {
clip-path: polygon(0 60%, 100% 60%, 100% 60%, 0 60%);
}
75% {
clip-path: polygon(0 80%, 100% 80%, 100% 80%, 0 80%);
}
80% {
clip-path: polygon(0 40%, 100% 40%, 100% 60%, 0 60%);
}
95% {
clip-path: polygon(0 45%, 100% 45%, 100% 60%, 0 60%);
}
100% {
clip-path: polygon(0 11%, 100% 11%, 100% 15%, 0 15%);
}
}
#keyframes glitch-anim-flash {
0% {
opacity: .2;
}
30%,
100% {
opacity: 0;
}
}
<div class="glitch">
<img src="https://images.unsplash.com/photo-1561019733-a84b4e023910?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80" alt="">
<div class="glitch__layers">
<div class="glitch__layer"></div>
<div class="glitch__layer"></div>
<div class="glitch__layer"></div>
</div>
</div>
I'd like to create a scotch tape band design on my website. I would like it to look almost like that :
I designed yet the clean tape but I cannot manage to create the bendings (circled on the picture) properly.
this is what I have yet.
body {
overflow: hidden;
}
.duct-tape {
display: flex;
justify-content: space-around;
align-items: space-around;
transform-origin: center;
position: absolute;
top: 50%;
left: 50%;
width: 100vw;
background-color: yellow;
overflow: hidden;
}
.duct-tape:nth-of-type(1) {
transform: translate(-50%, -50%) rotateZ(-20deg);
}
.duct-tape:nth-of-type(2) {
transform: translate(-50%, -50%) rotateZ(30deg);
}
.duct-tape > .shadow {
display: block;
position: absolute;
height: .3px;
width: 50px;
transform: rotateZ(-30deg) translateX(13px);
border-radius: 100%;
box-shadow: .1em .1em .25em rgb(130, 130, 0);
}
/* debug code */
.circle {
content: "";
display: block;
border-radius: 100px;
width: 30px;
height: 30px;
border: 2px solid lightblue;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-60%, -60%);
}
<body>
<div class="duct-tape">
<span>any text</span>
<span>any text</span>
</div>
<div class="duct-tape">
<span>any text</span>
<span>any text</span>
<span class="shadow"></span>
</div>
<!-- debug code -->
<span class="circle"></span>
</body>
Yet I thought about create little shadow elements (class shadow in duct-tape in the snippet) that would act like the bendings. I thought about svg too, but it doesn't seem I can easily create such an svg. I know css packs up 3D transforms, could it help me or this is too specific to be properly done using css 3D transforms ? Any idea of easier ways to do it ?
You may take a look at clip-path, rgba() colors and gradient.
here is a quick example to show the idea.
body {
background: yellow;
}
span {
--rt: 45deg;
position: absolute;
height: var(--ht, 400px);
width: var(--wdt, 50px);
background: linear-gradient(30deg, transparent 30%, rgba(255, 255, 255, 0.3) 32%, transparent 33%), radial-gradient(circle at 60% 40%, transparent 15px, rgba(255, 255, 255, 0.25) 17%, transparent 20%) rgba(0, 0, 0, 0.075);
box-shadow: 0 0 2px rgba(255, 255, 255, 0.6);
top: 50%;
left: 50%;
margin: -200px -25px;
transform: rotate(var(--rt));
clip-path: polygon(1% 0%, 19% 1%, 30% 0%, 38% 0%, 48% 1%, 58% 3%, 62% 3%, 79% 3%, 73% 1%, 84% 0%, 87% 0%, 91% 4%, 92% 2%, 99% 0%, 96% 5%, 96% 20%, 100% 34%, 100% 46%, 99% 54%, 95% 57%, 87% 69%, 100% 77%, 100% 82%, 100% 89%, 100% 96%, 90% 99%, 76% 100%, 71% 97%, 63% 100%, 54% 99%, 51% 100%, 37% 98%, 34% 100%, 21% 99%, 17% 100%, 14% 98%, 10% 100%, 3% 98%, 3% 100%, 0% 85%, 4% 80%, 0% 74%, 4% 55%, 6% 45%, 3% 40%, 0% 34%, 6% 25%, 4% 16%, 1% 13%);
}
span:nth-child(2) {
--rt: -45deg;
--ht: 450px;
background-size: 150% 200%;
clip-path: polygon(0 0, 13% 2%, 22% 0%, 28% 0%, 34% 2%, 46% 2%, 60% 2%, 69% 3%, 79% 1%, 80% 0%, 90% 0%, 93% 3%, 100% 4%, 99% 98%, 97% 100%, 87% 99%, 80% 100%, 74% 99%, 68% 100%, 60% 99%, 50% 100%, 43% 97%, 33% 96%, 31% 98%, 24% 99%, 20% 100%, 14% 98%, 9% 100%, 0% 100%);
}
span:nth-child(3) {
--rt: -45deg;
--wdt: 40px;
--ht: 200px;
left: 25%;
background-size: 110% 200%;
}
span:nth-child(4) {
--rt:15deg;
--wdt: 40px;
--ht: 150px;
left: 25%;
background-size: 40% 50%;
clip-path: polygon(0 0, 13% 2%, 22% 0%, 28% 0%, 34% 2%, 46% 2%, 60% 2%, 69% 3%, 79% 1%, 80% 0%, 90% 0%, 93% 3%, 100% 4%, 99% 98%, 97% 100%, 87% 99%, 80% 100%, 74% 99%, 68% 100%, 60% 99%, 50% 100%, 43% 97%, 33% 96%, 31% 98%, 24% 99%, 20% 100%, 14% 98%, 9% 100%, 0% 100%);
}
<span></span>
<span></span>
<span></span>
<span></span>
gradient linear,radial and conic can be used via background and resized and repeated or not, clip-path can allow you to cut off some pieces . a usefull tool to help you https://bennettfeely.com/clippy/
mask svg is also a possibility instead clip-path or mixed with.
I need to make a circular nav with a transparent center and buttons shaped like the bars around this Iron Man thing.
Below is my attempt using clip path... is there a way to do curves to make this easier, or must I draw many more points to make this look good?
CSS
.circle-new-btn {
background: rgba(0,0,0,1.00);
height: 300px;
width: 300px;
-webkit-clip-path: polygon(52% 21%, 57% 22%, 61% 24%, 65% 28%, 68% 31%, 59% 48%, 56% 46%, 53% 44%, 49% 43%, 45% 42%, 41% 44%, 38% 47%, 34% 50%, 32% 28%, 36% 25%, 40% 24%, 46% 22%);
clip-path: polygon(52% 21%, 57% 22%, 61% 24%, 65% 28%, 68% 31%, 59% 48%, 56% 46%, 53% 44%, 49% 43%, 45% 42%, 41% 44%, 38% 47%, 34% 46%, 32% 28%, 36% 25%, 40% 24%, 46% 22%);
}
.circle-new-btn:hover {
background: rgba(111,111,0,1.00);
}
HTML
<div class="circle-new-btn"></div>
Here is an idea how you can create this shape using CSS:
.box {
width:200px;
height:100px;
padding:20px 0;
box-sizing:border-box;
color:#fff;
text-align:center;
background:
radial-gradient(circle at 50% 160%,transparent 45%,blue 44.5%,blue 85%,transparent 85%);
-webkit-clip-path: polygon(0 0, 100% 0, 75% 90%, 25% 90%);
clip-path: polygon(0 0, 100% 0, 75% 90%, 25% 90%);
}
<div class="box">
Some text
</div>
Then you can simply apply some rotation to place the buttons around the big circle.
HTML5 introduced a new "progress" element that by default is rendered as a progress bar (thermometer).
A very basic example is:
<progress max="100" value="85"></progress>
I have been experimenting with a variety of progress circle options using javascript, and also have been really impressed by some pure CSS approaches discussed here:
CSS Progress Circle
I am interested to know if anyone has successfully applied CSS to the "progress" element to provide a pie/clock/circle rendering rather than a linear display?
EDIT/ADDENDUM: The "meter" element is also quite similar to "progress" but provides for a low/high range...I mention this more for anyone who might stumble upon this post in the future and want to apply a similar technique to the HTML5 meter element.
Trying to do this in pure CSS is quite hard, so I don't think than this is the correct technique to do it.
Anyway, just as a technical exercise, let's try it. (Tested only in Chrome !)
First of all the basis. We are going to divide the circle in 4 quadrants, and for each one we will need a different style. Here we have the styles, showing in color (green, red, blue, yellow) the useful range of the progress value element. The gray area is the rest of the element, unused.
.test {
width: 100px;
height: 100px;
margin: 20px 10px 0px 20px;
border-radius: 50%;
background-image: radial-gradient(lightblue 62%, blue 40%);
position: relative;
display: inline-block;
}
.test div {
height: 30%;
transform-origin: left top;
position: absolute;
opacity: 0.5;
ackground-color: green;
}
.inner1 {
width: 25%;
left: 50%;
top: -20%;
background-color: green;
transform: rotate(45deg) scaleX(3.9598);
}
.inner2 {
width: 50%;
left: 190%;
top: -20%;
background-image: linear-gradient(to right,gray 50%, red 50%);
transform: rotate(135deg) scaleX(3.9598);
}
.inner3 {
width: 75%;
left: 190%;
top: 260%;
background-image: linear-gradient(to right,gray 66%, blue 66%);
transform: rotate(225deg) scaleX(3.9598);
}
.inner4 {
width: 100%;
left: -230%;
top: 260%;
background-image: linear-gradient(to right,gray 75%, yellow 66%);
transform: rotate(315deg) scaleX(3.9598);
}
<div class="test">
<div class="inner1"></div>
</div>
<div class="test">
<div class="inner2"></div>
</div>
<div class="test">
<div class="inner3"></div>
</div>
<div class="test">
<div class="inner4"></div>
</div>
Now, let's show a trick for creating the radial segments. This can be acomplished setting an element normal (at a right angle) to the user, and applying some perspective:
div {
width: 300px;
height: 300px;
position: relative;
}
.container {
perspective: 400px;
margin: 40px 200px;
border: solid 1px black;
}
.top {
position: absolute;
left: 0px;
top: -100%;
background-image: repeating-linear-gradient(to right, tomato 0px, white 20px);
transform: rotateX(90deg);
transform-origin: center bottom;
}
.right {
position: absolute;
left: 100%;
top: 0px;
background-image: repeating-linear-gradient( tomato 0px, white 20px);
transform: rotateY(90deg);
transform-origin: left center;
}
.bottom {
position: absolute;
left: 0px;
bottom: 0px;
background-image: repeating-linear-gradient(to right, tomato 0px, white 20px);
transform: rotateX(90deg);
transform-origin: center bottom;
}
.left {
position: absolute;
right: 100%;
top: 0px;
background-image: repeating-linear-gradient( tomato 0px, white 20px);
transform: rotateY(-90deg);
transform-origin: right center;
}
<div class="container">
<div class="top"></div>
<div class="right"></div>
<div class="bottom"></div>
<div class="left"></div>
</div>
And now, just some boring selectors (it's difficult to target values in the range 20-29 and not targetting the value 2 at the same time).
A little bit of JS, but only to control the progress value. You can use both the input and the slider to change it.
function change () {
var input = document.getElementById("input");
var progress = document.getElementById("test");
progress.value = input.value;
}
function changeNumber () {
var input = document.getElementById("number");
var progress = document.getElementById("test");
progress.value = input.value;
}
.container {
width: 500px;
height: 500px;
overflow: hidden;
margin: 10px;
}
.test {
width: 200px;
height: 200px;
margin: 10px 10px;
border-radius: 50%;
background-image: radial-gradient(lightblue 62%, transparent 40%);
box-shadow: 0px 0px 0px 500px lightblue, inset 0px 0px 0px 2px lightblue;
}
.test::-webkit-progress-bar {
background-color: transparent;
position: relative;
border-radius: 50%;
perspective: 100px;
z-index: -1;
background-repeat: no-repeat;
}
.test[value^="2"]::-webkit-progress-bar,
.test[value^="3"]::-webkit-progress-bar
{
background-image: linear-gradient(red, red);
background-size: 50% 50%;
background-position: right top;
}
.test[value^="4"]::-webkit-progress-bar,
.test[value^="5"]::-webkit-progress-bar
{
background-image: linear-gradient(purple, purple);
background-size: 50% 100%;
background-position: right top;
}
.test[value^="6"]::-webkit-progress-bar,
.test[value^="7"]::-webkit-progress-bar,
.test[value="80"]::-webkit-progress-bar
{
background-image: linear-gradient(blue, blue), linear-gradient(blue, blue);
background-size: 50% 100%, 50% 50%;
background-position: right top, left bottom;
}
.test::-webkit-progress-bar,
.test[value="2"]::-webkit-progress-bar,
.test[value="3"]::-webkit-progress-bar,
.test[value="4"]::-webkit-progress-bar,
.test[value="5"]::-webkit-progress-bar,
.test[value="6"]::-webkit-progress-bar,
.test[value="7"]::-webkit-progress-bar,
.test[value="8"]::-webkit-progress-bar {
background-image: none;
}
.test::-webkit-progress-value {
background-color: green;
height: 30%;
transform-origin: left top;
z-index: -1;
position: absolute;
}
.test[value^="2"]::-webkit-progress-value,
.test[value^="3"]::-webkit-progress-value {
background-color: red;
top: -20%;
left: 190%;
transform: rotate(135deg) rotateX(-90deg) scaleX(3.9598);
}
.test[value^="4"]::-webkit-progress-value,
.test[value^="5"]::-webkit-progress-value {
background-color: purple;
left: 190%;
top: 260%;
transform: rotate(225deg) rotateX(-90deg) scaleX(3.9598);
}
.test[value^="6"]::-webkit-progress-value,
.test[value^="7"]::-webkit-progress-value,
.test[value="80"]::-webkit-progress-value {
background-color: blue;
left: -230%;
top: 260%;
transform: rotate(315deg) rotateX(-90deg) scaleX(3.9598);
}
.test::-webkit-progress-value,
.test[value="2"]::-webkit-progress-value,
.test[value="3"]::-webkit-progress-value,
.test[value="4"]::-webkit-progress-value,
.test[value="5"]::-webkit-progress-value,
.test[value="6"]::-webkit-progress-value,
.test[value="7"]::-webkit-progress-value,
.test[value="8"]::-webkit-progress-value
{
background-color: green;
left: 50%;
top: -20%;
transform: rotate(45deg) rotateX(-90deg) scaleX(3.9598);
}
<input id="input" type="range" value="0" min="0" max="80" onchange="change()" oninput="change()"/>
<input id="number" type="number" value="0" min="0" max="80" step="1" oninput="changeNumber()"/>
<div class="container">
<progress class="test" id="test" max="80" value="0"></progress>
</div>
There is a difficulty in the overflow: hidden; and a bug in Chrome. It isn't expected for it to work on the same element where perspective is applied, but it should work applied to the progress itself. It just works half of the time ...
Also, another idea, the style is much more simpler, and I could get it to extend to the full range, but anyway it's a starting point:
function change () {
var input = document.getElementById("input");
var progress = document.getElementById("test");
progress.value = input.value;
}
function changeNumber () {
var input = document.getElementById("number");
var progress = document.getElementById("test");
progress.value = input.value;
}
.test {
width: 400px;
height: 200px;
margin: 10px 10px;
border-radius: 9999px 9999px 0px 0px;
border: solid 1px red;
ackground-image: radial-gradient(lightblue 62%, transparent 40%);
ox-shadow: 0px 0px 0px 500px lightblue;
overflow: hidden;
}
.test::-webkit-progress-bar {
background-color: transparent;
position: relative;
border-radius: 50%;
perspective: 100px;
perspective-origin: center 300px;
z-index: -1;
background-repeat: no-repeat;
}
.test::-webkit-progress-value {
height: 300%;
transform-origin: center bottom;
bottom: -20%;
z-index: -1;
position: absolute;
background-image: linear-gradient(270deg, red 2px, tomato 30px);
transform: rotateX(-90deg) scaleX(1);
}
<input id="input" type="range" value="0" min="0" max="80" onchange="change()" oninput="change()">
<input id="number" type="number" value="0" min="0" max="80" step="1" oninput="changeNumber()">
<progress class="test" id="test" max="80" value="20"></progress>
Run my code and see the result
.loader {
position: relative;
height: 100px;
width: 100px;
display: flex;
align-items: center;
justify-content: center;
color: red;
margin:30px 30px;
float:left;
}
.loader:before {
content: "";
background: white;
position:absolute;
z-index:100;
width:98px;
height:98px;
border-radius:50%;
margin:auto auto;
}
progress::-moz-progress-bar { background: transparent; }
progress::-webkit-progress-bar {background: transparent;}
progress::-moz-progress-value { background: red; }
progress::-webkit-progress-value { background: red; }
.circle {
border-radius: 100%;
overflow: hidden;
padding:0;
}
.spin {
animation: spin 2s linear infinite;
}
#keyframes spin {
to {
transform: rotate(360deg);
}
}
html {
height: 100%;
display: flex;
}
body {
margin: auto;
}
<progress max="100" value="95" class="spin circle loader"></progress>
<progress max="100" value="50" class="spin circle loader"></progress>
<progress max="100" value="10" class="spin circle loader"></progress>
Thanks to #G-Cyr, I used some part of one of his answers
(here) and mixed it with my solution to make this answer faster.
Well, that's an interesting challenge.
The element has quite some default styles applied to it, by the browser and even the OS.
<progress max="100" value="85"></progress>
So first, we should get rid of the appearance property setting it to none
progress {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
<progress max="100" value="85"></progress>
Then, additional styles are created by the browser stacking pseudo-elements. For instance, if you're looking at this answer in any webkit browser, the above snippet will still show a flat box with a green fill representing the progress.
Those pseudo-elements can be addressed in CSS too. Each browser has it's specific pseudo elements, which further complicates the issue.
Webkit stacks 3 pseudo elements, in the following hierarchy
while Gecko and Trident use a single pseudo-element for the progress fill bars, ::-moz-progress-bar and ::-ms-fill, respectively.
progress {
/*gets rid of default appearance*/
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
/*styles as any good ol' div would */
border: 1px solid black;
display:block;
width:100px; height:100px;
background:chartreuse;
}
/* gets rid of default pseudo-elements */
::-webkit-progress-inner-element {display:none}
/*for some reason, Firefox won't let the display or the content of this pseudo-element
set to none, so height:0 should do the trick. Maybe visibility:hidden too.*/
::-moz-progress-bar{height: 0;}
::-ms-fill {display:none; }
<progress max="100" value="85"></progress>
That should leave us with the progress element styled as a good ol' div, which we can use for any of the circle progress bar methods linked above, while being awesome at semantics. We might even use the default additional pseudo elements and style them as needed instead of creating nested divs and such mumbo jumbo.
This is, of course highly experimental and non-standard, so shouldn't be used for production. The support is somewhat decent though, with all major players getting some form of the appearance property, and the three major engines supporting the styling of the pseudo elements... so maybe I'll take back my previous statement and change it for a "just got to be extra careful"
Solution with conic gradient (based on #RAM solution - his pseudo element code and interactive slider idea from #vals), it use css variables (custom properties), so you can easily change the color and size.
progress_number.addEventListener('change', function() {
progress_input.value = progress.value = +progress_number.value;
});
progress_input.addEventListener('input', function() {
progress_number.value = progress.value = +progress_input.value;
});
width_number.addEventListener('change', function() {
width_input.value = width_number.value;
progress_wrapper.style.setProperty('--width', width_number.value);
});
width_input.addEventListener('input', function() {
width_number.value = width_input.value;
progress_wrapper.style.setProperty('--width', width_input.value);
});
color.addEventListener('input', function() {
progress.style.setProperty('--color', color.value);
});
background.addEventListener('input', function() {
progress.style.setProperty('--background', background.value);
});
/* controls */
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
grid-template-areas:
"A B"
"C D";
}
.grid label {
width: 90px;
display: inline-block;
text-align: right;
}
.grid > :nth-child(1) {
grid-area: A;
}
.grid > :nth-child(2) {
grid-area: C;
}
.grid > :nth-child(3) {
grid-area: B;
}
.grid > :nth-child(4) {
grid-area: D;
}
:root {
--color: #ff0000;
--background: lightblue;
--size: 100;
--width: 10;
}
.progress {
width: calc(var(--size) * 1px);
height: calc(var(--size) * 1px);
border-radius: 100%;
overflow: hidden;
padding: 0;
position: relative;
display: flex;
align-items: center;
justify-content: center;
color: transparent;
background: transparent;
margin: 30px 30px;
float: left;
}
progress {
height: 100%;
}
.progress:before {
content: "";
background: white;
position:absolute;
z-index:100;
/* parenthesis are required */
width: calc((var(--size) - (var(--width) * 2)) * 1px);
height: calc((var(--size) - (var(--width) * 2)) * 1px);
border-radius:50%;
margin:auto auto;
}
progress::-moz-progress-value { background: transparent; }
progress::-webkit-progress-value { background: transparent; }
progress::-moz-progress-bar { background: transparent; }
/* CODE FOR GOOGLE CHROME GENERATED IN JS BY
[...new Array(100)].map((_, i) => `progress[value="${i}"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% ${i}%, var(--background) ${i}% 100%); }`).join('\n')
*/
progress[value="0"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 0%, var(--background) 0% 100%); }
progress[value="1"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 1%, var(--background) 1% 100%); }
progress[value="2"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 2%, var(--background) 2% 100%); }
progress[value="3"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 3%, var(--background) 3% 100%); }
progress[value="4"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 4%, var(--background) 4% 100%); }
progress[value="5"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 5%, var(--background) 5% 100%); }
progress[value="6"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 6%, var(--background) 6% 100%); }
progress[value="7"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 7%, var(--background) 7% 100%); }
progress[value="8"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 8%, var(--background) 8% 100%); }
progress[value="9"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 9%, var(--background) 9% 100%); }
progress[value="10"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 10%, var(--background) 10% 100%); }
progress[value="11"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 11%, var(--background) 11% 100%); }
progress[value="12"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 12%, var(--background) 12% 100%); }
progress[value="13"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 13%, var(--background) 13% 100%); }
progress[value="14"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 14%, var(--background) 14% 100%); }
progress[value="15"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 15%, var(--background) 15% 100%); }
progress[value="16"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 16%, var(--background) 16% 100%); }
progress[value="17"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 17%, var(--background) 17% 100%); }
progress[value="18"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 18%, var(--background) 18% 100%); }
progress[value="19"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 19%, var(--background) 19% 100%); }
progress[value="20"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 20%, var(--background) 20% 100%); }
progress[value="21"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 21%, var(--background) 21% 100%); }
progress[value="22"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 22%, var(--background) 22% 100%); }
progress[value="23"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 23%, var(--background) 23% 100%); }
progress[value="24"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 24%, var(--background) 24% 100%); }
progress[value="25"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 25%, var(--background) 25% 100%); }
progress[value="26"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 26%, var(--background) 26% 100%); }
progress[value="27"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 27%, var(--background) 27% 100%); }
progress[value="28"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 28%, var(--background) 28% 100%); }
progress[value="29"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 29%, var(--background) 29% 100%); }
progress[value="30"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 30%, var(--background) 30% 100%); }
progress[value="31"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 31%, var(--background) 31% 100%); }
progress[value="32"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 32%, var(--background) 32% 100%); }
progress[value="33"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 33%, var(--background) 33% 100%); }
progress[value="34"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 34%, var(--background) 34% 100%); }
progress[value="35"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 35%, var(--background) 35% 100%); }
progress[value="36"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 36%, var(--background) 36% 100%); }
progress[value="37"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 37%, var(--background) 37% 100%); }
progress[value="38"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 38%, var(--background) 38% 100%); }
progress[value="39"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 39%, var(--background) 39% 100%); }
progress[value="40"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 40%, var(--background) 40% 100%); }
progress[value="41"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 41%, var(--background) 41% 100%); }
progress[value="42"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 42%, var(--background) 42% 100%); }
progress[value="43"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 43%, var(--background) 43% 100%); }
progress[value="44"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 44%, var(--background) 44% 100%); }
progress[value="45"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 45%, var(--background) 45% 100%); }
progress[value="46"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 46%, var(--background) 46% 100%); }
progress[value="47"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 47%, var(--background) 47% 100%); }
progress[value="48"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 48%, var(--background) 48% 100%); }
progress[value="49"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 49%, var(--background) 49% 100%); }
progress[value="50"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 50%, var(--background) 50% 100%); }
progress[value="51"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 51%, var(--background) 51% 100%); }
progress[value="52"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 52%, var(--background) 52% 100%); }
progress[value="53"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 53%, var(--background) 53% 100%); }
progress[value="54"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 54%, var(--background) 54% 100%); }
progress[value="55"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 55%, var(--background) 55% 100%); }
progress[value="56"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 56%, var(--background) 56% 100%); }
progress[value="57"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 57%, var(--background) 57% 100%); }
progress[value="58"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 58%, var(--background) 58% 100%); }
progress[value="59"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 59%, var(--background) 59% 100%); }
progress[value="60"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 60%, var(--background) 60% 100%); }
progress[value="61"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 61%, var(--background) 61% 100%); }
progress[value="62"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 62%, var(--background) 62% 100%); }
progress[value="63"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 63%, var(--background) 63% 100%); }
progress[value="64"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 64%, var(--background) 64% 100%); }
progress[value="65"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 65%, var(--background) 65% 100%); }
progress[value="66"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 66%, var(--background) 66% 100%); }
progress[value="67"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 67%, var(--background) 67% 100%); }
progress[value="68"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 68%, var(--background) 68% 100%); }
progress[value="69"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 69%, var(--background) 69% 100%); }
progress[value="70"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 70%, var(--background) 70% 100%); }
progress[value="71"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 71%, var(--background) 71% 100%); }
progress[value="72"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 72%, var(--background) 72% 100%); }
progress[value="73"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 73%, var(--background) 73% 100%); }
progress[value="74"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 74%, var(--background) 74% 100%); }
progress[value="75"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 75%, var(--background) 75% 100%); }
progress[value="76"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 76%, var(--background) 76% 100%); }
progress[value="77"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 77%, var(--background) 77% 100%); }
progress[value="78"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 78%, var(--background) 78% 100%); }
progress[value="79"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 79%, var(--background) 79% 100%); }
progress[value="80"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 80%, var(--background) 80% 100%); }
progress[value="81"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 81%, var(--background) 81% 100%); }
progress[value="82"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 82%, var(--background) 82% 100%); }
progress[value="83"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 83%, var(--background) 83% 100%); }
progress[value="84"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 84%, var(--background) 84% 100%); }
progress[value="85"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 85%, var(--background) 85% 100%); }
progress[value="86"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 86%, var(--background) 86% 100%); }
progress[value="87"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 87%, var(--background) 87% 100%); }
progress[value="88"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 88%, var(--background) 88% 100%); }
progress[value="89"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 89%, var(--background) 89% 100%); }
progress[value="90"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 90%, var(--background) 90% 100%); }
progress[value="91"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 91%, var(--background) 91% 100%); }
progress[value="92"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 92%, var(--background) 92% 100%); }
progress[value="93"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 93%, var(--background) 93% 100%); }
progress[value="94"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 94%, var(--background) 94% 100%); }
progress[value="95"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 95%, var(--background) 95% 100%); }
progress[value="96"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 96%, var(--background) 96% 100%); }
progress[value="97"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 97%, var(--background) 97% 100%); }
progress[value="98"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 98%, var(--background) 98% 100%); }
progress[value="99"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% 99%, var(--background) 99% 100%); }
progress[value="100"]::-webkit-progress-bar { background: var(--color); }
/* STYLE FOR FIREFOX GENERATED IN JS BY
[...new Array(100)].map((_, i) => `progress[value="${i}"] { background: conic-gradient(var(--color) 0% ${i}%, var(--background) ${i}% 100%); }`).join('\n')
*/
progress[value="0"] { background: conic-gradient(var(--color) 0% 0%, var(--background) 0% 100%); }
progress[value="1"] { background: conic-gradient(var(--color) 0% 1%, var(--background) 1% 100%); }
progress[value="2"] { background: conic-gradient(var(--color) 0% 2%, var(--background) 2% 100%); }
progress[value="3"] { background: conic-gradient(var(--color) 0% 3%, var(--background) 3% 100%); }
progress[value="4"] { background: conic-gradient(var(--color) 0% 4%, var(--background) 4% 100%); }
progress[value="5"] { background: conic-gradient(var(--color) 0% 5%, var(--background) 5% 100%); }
progress[value="6"] { background: conic-gradient(var(--color) 0% 6%, var(--background) 6% 100%); }
progress[value="7"] { background: conic-gradient(var(--color) 0% 7%, var(--background) 7% 100%); }
progress[value="8"] { background: conic-gradient(var(--color) 0% 8%, var(--background) 8% 100%); }
progress[value="9"] { background: conic-gradient(var(--color) 0% 9%, var(--background) 9% 100%); }
progress[value="10"] { background: conic-gradient(var(--color) 0% 10%, var(--background) 10% 100%); }
progress[value="11"] { background: conic-gradient(var(--color) 0% 11%, var(--background) 11% 100%); }
progress[value="12"] { background: conic-gradient(var(--color) 0% 12%, var(--background) 12% 100%); }
progress[value="13"] { background: conic-gradient(var(--color) 0% 13%, var(--background) 13% 100%); }
progress[value="14"] { background: conic-gradient(var(--color) 0% 14%, var(--background) 14% 100%); }
progress[value="15"] { background: conic-gradient(var(--color) 0% 15%, var(--background) 15% 100%); }
progress[value="16"] { background: conic-gradient(var(--color) 0% 16%, var(--background) 16% 100%); }
progress[value="17"] { background: conic-gradient(var(--color) 0% 17%, var(--background) 17% 100%); }
progress[value="18"] { background: conic-gradient(var(--color) 0% 18%, var(--background) 18% 100%); }
progress[value="19"] { background: conic-gradient(var(--color) 0% 19%, var(--background) 19% 100%); }
progress[value="20"] { background: conic-gradient(var(--color) 0% 20%, var(--background) 20% 100%); }
progress[value="21"] { background: conic-gradient(var(--color) 0% 21%, var(--background) 21% 100%); }
progress[value="22"] { background: conic-gradient(var(--color) 0% 22%, var(--background) 22% 100%); }
progress[value="23"] { background: conic-gradient(var(--color) 0% 23%, var(--background) 23% 100%); }
progress[value="24"] { background: conic-gradient(var(--color) 0% 24%, var(--background) 24% 100%); }
progress[value="25"] { background: conic-gradient(var(--color) 0% 25%, var(--background) 25% 100%); }
progress[value="26"] { background: conic-gradient(var(--color) 0% 26%, var(--background) 26% 100%); }
progress[value="27"] { background: conic-gradient(var(--color) 0% 27%, var(--background) 27% 100%); }
progress[value="28"] { background: conic-gradient(var(--color) 0% 28%, var(--background) 28% 100%); }
progress[value="29"] { background: conic-gradient(var(--color) 0% 29%, var(--background) 29% 100%); }
progress[value="30"] { background: conic-gradient(var(--color) 0% 30%, var(--background) 30% 100%); }
progress[value="31"] { background: conic-gradient(var(--color) 0% 31%, var(--background) 31% 100%); }
progress[value="32"] { background: conic-gradient(var(--color) 0% 32%, var(--background) 32% 100%); }
progress[value="33"] { background: conic-gradient(var(--color) 0% 33%, var(--background) 33% 100%); }
progress[value="34"] { background: conic-gradient(var(--color) 0% 34%, var(--background) 34% 100%); }
progress[value="35"] { background: conic-gradient(var(--color) 0% 35%, var(--background) 35% 100%); }
progress[value="36"] { background: conic-gradient(var(--color) 0% 36%, var(--background) 36% 100%); }
progress[value="37"] { background: conic-gradient(var(--color) 0% 37%, var(--background) 37% 100%); }
progress[value="38"] { background: conic-gradient(var(--color) 0% 38%, var(--background) 38% 100%); }
progress[value="39"] { background: conic-gradient(var(--color) 0% 39%, var(--background) 39% 100%); }
progress[value="40"] { background: conic-gradient(var(--color) 0% 40%, var(--background) 40% 100%); }
progress[value="41"] { background: conic-gradient(var(--color) 0% 41%, var(--background) 41% 100%); }
progress[value="42"] { background: conic-gradient(var(--color) 0% 42%, var(--background) 42% 100%); }
progress[value="43"] { background: conic-gradient(var(--color) 0% 43%, var(--background) 43% 100%); }
progress[value="44"] { background: conic-gradient(var(--color) 0% 44%, var(--background) 44% 100%); }
progress[value="45"] { background: conic-gradient(var(--color) 0% 45%, var(--background) 45% 100%); }
progress[value="46"] { background: conic-gradient(var(--color) 0% 46%, var(--background) 46% 100%); }
progress[value="47"] { background: conic-gradient(var(--color) 0% 47%, var(--background) 47% 100%); }
progress[value="48"] { background: conic-gradient(var(--color) 0% 48%, var(--background) 48% 100%); }
progress[value="49"] { background: conic-gradient(var(--color) 0% 49%, var(--background) 49% 100%); }
progress[value="50"] { background: conic-gradient(var(--color) 0% 50%, var(--background) 50% 100%); }
progress[value="51"] { background: conic-gradient(var(--color) 0% 51%, var(--background) 51% 100%); }
progress[value="52"] { background: conic-gradient(var(--color) 0% 52%, var(--background) 52% 100%); }
progress[value="53"] { background: conic-gradient(var(--color) 0% 53%, var(--background) 53% 100%); }
progress[value="54"] { background: conic-gradient(var(--color) 0% 54%, var(--background) 54% 100%); }
progress[value="55"] { background: conic-gradient(var(--color) 0% 55%, var(--background) 55% 100%); }
progress[value="56"] { background: conic-gradient(var(--color) 0% 56%, var(--background) 56% 100%); }
progress[value="57"] { background: conic-gradient(var(--color) 0% 57%, var(--background) 57% 100%); }
progress[value="58"] { background: conic-gradient(var(--color) 0% 58%, var(--background) 58% 100%); }
progress[value="59"] { background: conic-gradient(var(--color) 0% 59%, var(--background) 59% 100%); }
progress[value="60"] { background: conic-gradient(var(--color) 0% 60%, var(--background) 60% 100%); }
progress[value="61"] { background: conic-gradient(var(--color) 0% 61%, var(--background) 61% 100%); }
progress[value="62"] { background: conic-gradient(var(--color) 0% 62%, var(--background) 62% 100%); }
progress[value="63"] { background: conic-gradient(var(--color) 0% 63%, var(--background) 63% 100%); }
progress[value="64"] { background: conic-gradient(var(--color) 0% 64%, var(--background) 64% 100%); }
progress[value="65"] { background: conic-gradient(var(--color) 0% 65%, var(--background) 65% 100%); }
progress[value="66"] { background: conic-gradient(var(--color) 0% 66%, var(--background) 66% 100%); }
progress[value="67"] { background: conic-gradient(var(--color) 0% 67%, var(--background) 67% 100%); }
progress[value="68"] { background: conic-gradient(var(--color) 0% 68%, var(--background) 68% 100%); }
progress[value="69"] { background: conic-gradient(var(--color) 0% 69%, var(--background) 69% 100%); }
progress[value="70"] { background: conic-gradient(var(--color) 0% 70%, var(--background) 70% 100%); }
progress[value="71"] { background: conic-gradient(var(--color) 0% 71%, var(--background) 71% 100%); }
progress[value="72"] { background: conic-gradient(var(--color) 0% 72%, var(--background) 72% 100%); }
progress[value="73"] { background: conic-gradient(var(--color) 0% 73%, var(--background) 73% 100%); }
progress[value="74"] { background: conic-gradient(var(--color) 0% 74%, var(--background) 74% 100%); }
progress[value="75"] { background: conic-gradient(var(--color) 0% 75%, var(--background) 75% 100%); }
progress[value="76"] { background: conic-gradient(var(--color) 0% 76%, var(--background) 76% 100%); }
progress[value="77"] { background: conic-gradient(var(--color) 0% 77%, var(--background) 77% 100%); }
progress[value="78"] { background: conic-gradient(var(--color) 0% 78%, var(--background) 78% 100%); }
progress[value="79"] { background: conic-gradient(var(--color) 0% 79%, var(--background) 79% 100%); }
progress[value="80"] { background: conic-gradient(var(--color) 0% 80%, var(--background) 80% 100%); }
progress[value="81"] { background: conic-gradient(var(--color) 0% 81%, var(--background) 81% 100%); }
progress[value="82"] { background: conic-gradient(var(--color) 0% 82%, var(--background) 82% 100%); }
progress[value="83"] { background: conic-gradient(var(--color) 0% 83%, var(--background) 83% 100%); }
progress[value="84"] { background: conic-gradient(var(--color) 0% 84%, var(--background) 84% 100%); }
progress[value="85"] { background: conic-gradient(var(--color) 0% 85%, var(--background) 85% 100%); }
progress[value="86"] { background: conic-gradient(var(--color) 0% 86%, var(--background) 86% 100%); }
progress[value="87"] { background: conic-gradient(var(--color) 0% 87%, var(--background) 87% 100%); }
progress[value="88"] { background: conic-gradient(var(--color) 0% 88%, var(--background) 88% 100%); }
progress[value="89"] { background: conic-gradient(var(--color) 0% 89%, var(--background) 89% 100%); }
progress[value="90"] { background: conic-gradient(var(--color) 0% 90%, var(--background) 90% 100%); }
progress[value="91"] { background: conic-gradient(var(--color) 0% 91%, var(--background) 91% 100%); }
progress[value="92"] { background: conic-gradient(var(--color) 0% 92%, var(--background) 92% 100%); }
progress[value="93"] { background: conic-gradient(var(--color) 0% 93%, var(--background) 93% 100%); }
progress[value="94"] { background: conic-gradient(var(--color) 0% 94%, var(--background) 94% 100%); }
progress[value="95"] { background: conic-gradient(var(--color) 0% 95%, var(--background) 95% 100%); }
progress[value="96"] { background: conic-gradient(var(--color) 0% 96%, var(--background) 96% 100%); }
progress[value="97"] { background: conic-gradient(var(--color) 0% 97%, var(--background) 97% 100%); }
progress[value="98"] { background: conic-gradient(var(--color) 0% 98%, var(--background) 98% 100%); }
progress[value="99"] { background: conic-gradient(var(--color) 0% 99%, var(--background) 99% 100%); }
progress[value="100"] { background: var(--color); }
<div class="grid">
<div>
<label>Progress:</label>
<input id="progress_input" type="range" value="20" min="0" max="100"/>
<input id="progress_number" type="number" value="20" min="0" max="100" step="1"/>
</div>
<div>
<label>Width:</label>
<input id="width_input" type="range" value="10" min="1" max="40"/>
<input id="width_number" type="number" value="10" min="1" max="40" step="1"/>
</div>
<div>
<label>Color:</label>
<input id="color" type="color" value="#ff0000"/>
</div>
<div>
<label>Background:</label>
<input id="background" type="color" value="#ADD8E6"/>
</div>
</div>
<div class="progress" id="progress_wrapper">
<progress id="progress" value="20" max="100"></progress>
<div>
If you can't find it in CSS above, the big part was generated with JavaScript:
// Google Chrome
[...new Array(100)].map((_, i) => `progress[value="${i}"]::-webkit-progress-bar { background: conic-gradient(var(--color) 0% ${i}%, var(--background) ${i}% 100%); }`).join('\n')
// Firefox
[...new Array(100)].map((_, i) => `progress[value="${i}"] { background: conic-gradient(var(--color) 0% ${i}%, var(--background) ${i}% 100%); }`).join('\n')
Progress from 1-99 was generated, but only full color was written as:
/* Google Chrome full color */
progress[value="100"]::-webkit-progress-bar { background: var(--color); }
/* Firefox full color */
progress[value="100"] { background: var(--color); }
Here is a link to CodePen where I use this solution https://codepen.io/jcubic/pen/yLgPpYQ
EDIT:
If you're using SCSS you can generate the CSS with this code:
#for $percent from 0 through 99 {
progress[value="#{$percent}"]::-webkit-progress-bar {
background: conic-gradient(
var(--progress-color) 0% #{$percent}%,
var(--rest-color) #{$percent}% 100%);
}
}
progress[value="100"]::-webkit-progress-bar { background: var(--progress-color); }
#for $percent from 0 through 99 {
progress[value="#{$percent}"] {
background: conic-gradient(
var(--progress-color) 0% #{$percent}%,
var(--rest-color) #{$percent}% 100%);
}
}
progress[value="100"] {
background: var(--progress-color);
}
I just refactory #jcubic's idea without wrapper.
<h4>Default</h4>
<div class="box">
<progress id="pr" value="20" max="100"></progress>
<progress id="pr" value="50" max="100"></progress>
<progress id="pr" value="80" max="100"></progress>
<progress id="pr" value="100" max="100"></progress>
</div>
<h4>Colors</h4>
<div class="box">
<progress id="pr" value="20" max="100" style="--color: red"></progress>
<progress id="pr" value="50" max="100" style="--color: orange"></progress>
<progress id="pr" value="80" max="100" style="--color: green"></progress>
<progress id="pr" value="100" max="100" style="--color: purple"></progress>
</div>
<h4>Thickness</h4>
<div class="box">
<progress id="pr" value="20" max="100" style="--thickness: 10px"></progress>
<progress id="pr" value="20" max="100" style="--thickness: 20px"></progress>
<progress id="pr" value="20" max="100" style="--thickness: 30px"></progress>
<progress id="pr" value="20" max="100" style="--thickness: 40px"></progress>
</div>
<h4>Sizes</h4>
<div class="box">
<progress id="pr" value="20" max="100" style="--radius: 50px"></progress>
<progress id="pr" value="20" max="100" style="--radius: 100px"></progress>
<progress id="pr" value="20" max="100" style="--radius: 150px"></progress>
<progress id="pr" value="20" max="100" style="--radius: 200px"></progress>
</div>
:root {
--color: greenyellow;
--track-color: #444;
--background: #111a23;
}
body {
background: var(--background);
color: white;
}
.box {
display: flex;
gap: 1em;
}
progress {
height: var(--radius, 100px);
width: var(--radius, 100px);
border-radius: 50%;
overflow: hidden;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
progress::-webkit-progress-value {
background: transparent;
}
progress::-moz-progress-bar {
background: transparent;
}
progress:before {
position: absolute;
width: calc(var(--radius, 100px) - var(--thickness, 10px) * 2);
height: calc(var(--radius, 100px) - var(--thickness, 10px) * 2);
background-color: var(--background);
color: white;
margin: auto;
content: attr(value) "%";
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
#for $percent from 0 through 99 {
progress[value="#{$percent}"]::-webkit-progress-bar {
background: conic-gradient(
var(--color) 0% #{$percent}#{"%"},
var(--track-color) #{$percent}#{"%"} 100%
);
}
}
progress[value="100"]::-webkit-progress-bar {
background: var(--color);
}
#for $percent from 0 through 99 {
progress[value="#{$percent}"] {
background: conic-gradient(
var(--color) 0% #{$percent}#{"%"},
var(--track-color) #{$percent}#{"%"} 100%
);
}
}
progress[value="100"] {
background: var(--color);
}
https://codepen.io/comfuture/pen/GRybrwq
I have a div tag overlaying an image which is animated by growing in width and increasing in opacity. I simply want a single iteration (which is the default, I know), but for whatever reason, it runs infinitely. Could I get some feedback on how to accomplish a single iteration? Thank you in advance!
markup:
<div class="capback">
</div>
css:
.capback {
background: #000;
opacity:0.7;
filter:alpha(opacity=40);
position: absolute;
height: 17px;
width: 465px;
top: 1px;
left: 1px;
color: #fff;
padding: 5 0 0 10px;
font-size: 12px;
-moz-animation: fullexpand 25s ease-out;
-moz-animation-iteration-count:1;
-webkit-animation: fullexpand 25s ease-out;
-webkit-animation-iteration-count:1;
-o-animation: fullexpand 25s ease-out;
-o-animation-iteration-count:1;
}
#-moz-keyframes fullexpand {
0%, 20%, 40%, 60%, 80%, 100% { width:0%; opacity:0; }
4%, 24%, 44%, 64%, 84% { width:0%; opacity:0.3; }
16%, 36%, 56%, 76%, 96% { width:465px; opacity:0.7; }
17%, 37%, 57%, 77%, 97% { width:465px; opacity:0.3; }
18%, 38%, 58%, 78%, 98% { width:465px; opacity:0; }
}
#-webkit-keyframes fullexpand {
0%, 20%, 40%, 60%, 80%, 100% { width:0%; opacity:0; }
4%, 24%, 44%, 64%, 84% { width:0%; opacity:0.3; }
16%, 36%, 56%, 76%, 96% { width:465px; opacity:0.7; }
17%, 37%, 57%, 77%, 97% { width:465px; opacity:0.3; }
18%, 38%, 58%, 78%, 98% { width:465px; opacity:0; }
}
#-o-keyframes fullexpand {
0%, 20%, 40%, 60%, 80%, 100% { width:0%; opacity:0; }
4%, 24%, 44%, 64%, 84% { width:0%; opacity:0.3; }
16%, 36%, 56%, 76%, 96% { width:465px; opacity:0.7; }
17%, 37%, 57%, 77%, 97% { width:465px; opacity:0.3; }
18%, 38%, 58%, 78%, 98% { width:465px; opacity:0; }
}
as the saying goes, "the problem usually lies between the keyboard and the chair". holds true in this case. :) i was causing my own woes with too many keyframes.