Related
Just like the above image or an idea or reference to achieve this design, I appreciate the help or suggestion given by community thank you
I have got reference of progress bar which is circular but not able find an approach to solve it.
const boxes = document.querySelectorAll(".box");
const colors = ['red', 'blue', 'green', 'yellow', 'orange', 'violet']
boxes.forEach((box) => {
const insideContent = box.innerText;
box.style.border = `6px solid ${colors[insideContent]}`
})
#app {
display: flex;
}
.box {
width: 50px;
height: 50px;
margin: 10px;
background-color: cyan;
display: flex;
justify-content: center;
align-items: center;
}
<div id="app">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
As per your question I think this is what you are trying to achieve.
First define a pseudo class root
:root {
--color-val: blue;
}
Note: In order to use the --color-val you need to write it as color: var(--color-var) in CSS
Second use JavaScript to update the variable --color-val
let colors =
var root = document.querySelector(':root');
const delay = ms => new Promise(res => setTimeout(res, ms));
const colorChange = async () => {
await delay(1000);
color = colors[Math.floor(Math.random() * colors.length)]
console.log(color)
root.style.setProperty('--color-val', color);
};
colorChange()
Note:
Add the color list you want to select from or go to CodePen for a list of 1000+ hex codes.
Promise are used for asynchronous function and can be skipped by using setTimeOut for a delayed loop or if used with another eventlistener.
I apologize if I misunderstood the question. Wrote in a hurry and without beautyful visualisation, if you disassemble the principle, you can customize it.
h1 {
display: block;
margin:0 auto;
text-align: center;
padding-top:20%;
}
.container {
display:flex;
width: 150px;
height: 150px;
border: 1px solid black;
z-index: 110;
margin:0;
margin: -10px;
}
.top {
display:block;
background-color: green;
height: 24px;
width: 150px; /* gorizontal top */
animation: top 1s linear;
animation-fill-mode: forwards;
}
#keyframes top {
0% {
width: 0px;
}
100% {
width: 150px;
}
}
.right {
background-color: green;
height: 0%;/* right */
width: 32px;
animation: right 1s linear;
animation-fill-mode: forwards;
animation-delay: 1s;
z-index: 10;
}
#keyframes right {
0% {
height: 0%;
}
100% {
height: 100%;
}
}
.box {
position: fixed;
top: 32.5px;
left: 32.5px;
width: 100px;
height: 100px;
border: 1px solid black;
margin: auto;
z-index: 120;
margin: -10px -10px;
}
.bottom {
position: absolute;
top: 123px;
left: 150px;
background-color: green;
width: 0px;
height: 27px;
z-index: 10;
animation: bottom 1s linear;
animation-fill-mode: forwards;
animation-delay: 2s;
/* animation-direction: reverse; */
}
#keyframes bottom {
0% {
transform: translate(0,0);
}
100% {
transform: translate(-250px,0);
-webkit-transform: translate(-250px,0); /** Safari & Chrome **/
-o-transform: translate(-250px,0); /** Opera **/
-moz-transform: translate(-250px,0); /** Firefox **/
width: 250px;
}
}
.left {
position: absolute;
top: 122px;
background-color: green;
width: 25px;
height: 0px;
animation: left 1s linear;
animation-fill-mode: forwards;
animation-delay: 3s;
}
#keyframes left {
0% {
transform: translate(0,0);
}
100% {
transform: translate(0,-250px);
-webkit-transform: translate(0,-250px); /** Safari & Chrome **/
-o-transform: translate(0,-250px); /** Opera **/
-moz-transform: translate(0,-250px); /** Firefox **/
height: 277px;
}
}
<div class='head'>
<div class='container'>
<div class='top'></div>
<div class='box'>
<h1 id='timer'>
1
</h1>
</div>
<div class='right'></div>
<div class='bottom'></div>
<div class='left'></div>
</div>
</div>
<script type="text/javascript">
init()
function init()
{
sec = 0;
setInterval(tick, 1000);
}
function tick()
{ if (sec<3) { sec++
document.getElementById("timer").
childNodes[0].nodeValue = sec;
} else {
clearInterval(0);
}
}
</script>
Also, instead of the SetInterval script, you can take values from your block width and height styles and output a mathematical calculation in h1 instead of a stopwatch.
upd: After your comment, I decided to do what I wrote about above. You can play with values and math, I add a snippet of another solution that changes the progress bar from the entered values within the entered range. (of course, it would be easier on react than on pure js)
function grade () {
let grade = +document.getElementById("grade").value;
let range = +document.getElementById("range").value;
document.getElementById("timer").innerHTML = `${grade}/${range}`;
progress(grade,range)
}
function progress (value, grade) {
document.getElementById('1').style.backgroundColor = `white`
document.getElementById("left").className = "noactive";
document.getElementById('top').style.width = `0%`
document.getElementById('right').style.height = `0%`
document.getElementById('bottom').style.width = `0%`
let GradeValuSide = grade/4;
if (value <= GradeValuSide) {
document.getElementById('top').style.width =
`${value/GradeValuSide*100}%`
} else if (value > GradeValuSide && value <= (GradeValuSide*2)) {
document.getElementById('top').style.width = `100%`
document.getElementById('right').style.height =
`${(value-GradeValuSide)/GradeValuSide*100}%`
} else if (value >= grade/2 && value < (grade/4)*3) {
document.getElementById('top').style.width = `100%`
document.getElementById('right').style.height = `100%`
document.getElementById('bottom').style.width =
`${((((value-(GradeValuSide*2)) / GradeValuSide) *100) / 100) *27}%`
} else if (value >= grade-(grade/4) /* && value < value + 1 */) {
document.getElementById('top').style.width = `100%`
document.getElementById('right').style.height = `100%`
document.getElementById('bottom').style.width = `100%`
document.getElementById('1').style.backgroundColor = `green`
document.getElementById("left").className = "left";
document.getElementById('left').style.height =
`${(40 - (40 * ((((value-(GradeValuSide*3)) * 100) / GradeValuSide)/ 100)))}%`
}
}
h1 {
font-size:20px;
position: absolute;
left: 40px;
display: block;
margin: 0 auto;
align-items: center;
padding-top:10%;
}
.container {
display:flex;
width: 150px;
height: 150px;
border: 1px solid black;
margin:0;
margin: -10px;
}
div.top {
display:block;
background-color: green;
height: 24px;
width: 0%; /* gorizontal top */
z-index:999;
}
div.right {
position:relative;
background-color: green;
height: 0%;/* right */
width: 32px;
z-index: 9999;
}
.box {
position: fixed;
top: 32.5px;
left: 32.5px;
background-color:white;
width: 100px;
height: 100px;
border: 1px solid black;
margin: auto;
z-index: 120;
margin: -10px -10px;
}
.wrap{
position: relative;
}
div.bottom {
position: absolute;
top: 123px;
background-color: green;
width: 0%; /* 27 = 100% */
height: 27px;
float: right;
right: 78vw;
z-index: 100;
}
div.left {
position: absolute;
background-color: white;
width: 23px;
height: 40%;
top: 23px;
bottom: 10px;
left: 0;
float: top;
}
div.noactive {
position: absolute;
background-color: white;
width: 23px;
height: 0%;
top: 23px;
bottom: 10px;
left: 0;
float: top;
}
.items {
margin-top: 50px;
text-align: center;
}
.grade,
.value {
height: 15px;
width: 50px;
align-items: center;
}
<div class='head'>
<div id='1' class='container'>
<div id='top' class='top'></div>
<div class='box'>
<h1 id='timer'>1</h1>
<div class='items'>
value<input id='grade' class='grade' type=number oninput="grade()"/>
range<input id='range' class='value' type=number oninput="grade()"/>
</div>
</div>
<div id='right' class='right'></div>
<div id='bottom' class='bottom'></div>
<div id='left' class='noactive'></div>
</div>
</div>
<script src='app.js'></script>
I found this great tool but it's awkward to implement in my project: https://github.com/vydimitrov/react-countdown-circle-timer
I want to create a reusable button component that onClick, starts a similar countdown effect with its border, giving the user a chance to 'undo' their decision (similar to forwarding a message in fb messenger). I can figure out the react logic but no clue where to start with css
Thanks in advance
Browsing the code of the component you mention, I noticed it uses an SVG element with animated stroke to create and animate the circular progress bar.
This article is my favourite one about this specific problem:
https://css-tricks.com/building-progress-ring-quickly/
Here is the code from that article for future reference. This is not my code, kudos to the original author of the article:
var circle = document.querySelector('circle');
var radius = circle.r.baseVal.value;
var circumference = radius * 2 * Math.PI;
circle.style.strokeDasharray = `${circumference} ${circumference}`;
circle.style.strokeDashoffset = `${circumference}`;
function setProgress(percent) {
const offset = circumference - percent / 100 * circumference;
circle.style.strokeDashoffset = offset;
}
const input = document.querySelector('input');
setProgress(input.value);
input.addEventListener('change', function(e) {
if (input.value < 101 && input.value > -1) {
setProgress(input.value);
}
})
html, body {
background-color: #2962FF;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
position: relative;
}
.progress-ring {
}
.progress-ring__circle {
transition: 0.35s stroke-dashoffset;
// axis compensation
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
input {
position: fixed;
top: 10px;
left: 10px;
width: 80px;
}
<svg
class="progress-ring"
width="120"
height="120">
<circle
class="progress-ring__circle"
stroke="white"
stroke-width="4"
fill="transparent"
r="52"
cx="60"
cy="60"/>
</svg>
<input
value="35"
type="number"
step="5"
min="0"
max="100"
placeholder="progress"
>
This is a pure css pie timer which looks pretty similar to one of your timers mentioned in the link.
See it in full screen
var time = 11;
{
var func = setInterval(function() {
if (time != 0) {
document.getElementsByClassName('time')[0].innerHTML = time;
time--;
if (time < 5) {
document.getElementsByClassName('warning')[0].style.display = "block";
}
} else {
document.getElementsByClassName('time')[0].innerHTML = "0";
document.getElementsByClassName('warning')[0].style.display = "none";
clearInterval(func);
}
}, 1000);
}
.timer {
height: 200px;
width: 200px;
border-radius: 50%;
background-color: black;
animation: time 5s infinite;
margin-left: 570px;
margin-top: 200px;
}
.bar {
position: absolute;
}
.left_progress {
position: absolute;
height: 200px;
width: 200px;
background: linear-gradient(90deg, #00d2ff 0%, #3a47d5 100%);
border-radius: 50%;
clip: rect(0px 100px 200px 0px);
animation: rotate_right 6s 6s linear both;
}
#keyframes rotate_right {
100% {
transform: rotateZ(180deg);
}
}
.left_progress_bar {
position: absolute;
height: 200px;
width: 200px;
background-color: #E9E9E9;
border-radius: 50%;
clip: rect(0px 100px 200px 0px);
z-index: 1;
animation: mid-way 4s linear both;
}
.right_progress {
position: absolute;
height: 200px;
width: 200px;
background-color: #E9E9E9;
border-radius: 50%;
clip: rect(0px 100px 200px 0px);
transform: rotateZ(180deg);
animation: rotate_left 6s linear both;
}
#keyframes rotate_left {
100% {
transform: rotateZ(360deg);
}
}
.right_progress_bar {
position: absolute;
height: 200px;
width: 200px;
background: linear-gradient(90deg, #00d2ff 0%, #3a47d5 100%);
border-radius: 50%;
clip: rect(0px 100px 200px 0px);
transform: rotateZ(180deg);
z-index: 1;
}
.main_content {
position: absolute;
height: 180px;
width: 180px;
border-radius: 50%;
background-color: white;
z-index: 4;
margin-top: 10px;
margin-left: 10px;
font-family: 'arial';
text-align: center;
}
.timer_content {
position: absolute;
margin-top: 40px;
margin-left: 45px;
}
.content {
font-size: 15px;
margin: 0px;
color: #6B6C6D;
}
.time {
font-size: 55px;
margin: 0px;
background: -webkit-linear-gradient(90deg, #00d2ff 0%, #3a47d5 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.warning {
position: absolute;
height: 180px;
width: 180px;
border-radius: 50%;
background-color: #DBDBDB;
animation: warning_bell 1s infinite;
display: none;
}
#keyframes warning_bell {
from {
transform: scale(0);
opacity: 1;
}
to {
transform: scale(1);
opacity: 0;
}
}
<div class="timer">
<div class="right_progress_bar">
<div class="right_progress"></div>
</div>
<div class="left_progress_bar">
<div class="left_progress"></div>
</div>
<div class="main_content">
<div class="warning"></div>
<div class="timer_content">
<p class="content">You can do in</p>
<p class="time">12</p>
<p class="content">seconds</p>
</div>
</div>
</div>
I've got this little UI I'm working on and I'm just now applying some animation to it so it can be activated via keypress in-game. I've sort of got both animations I want, I just can't get them working together, at the same time.
I'm not really familiar with CSS animations, If I could just do this all with after effects, I'd be dandy, but nevertheless.
I have created this image to sort of provide a brief explanation of what I'm looking for and I've got a JSFiddle with the slideout code, plus I'll include a snippet for the fade-in code.
Brief Explanation of What I'm Looking For:
Here is the JSFiddle for the slideout animation
Here is the JSFiddle with additions made since posting
Below is the Snippet for the FadeIn Animation
.positive {
color: rgb(114, 204, 114);
}
.negative {
color: rgb(224, 50, 50);
}
.tempbg {
background-color: #3f3f3f;
}
.portrait {
background-image: url("https://gdurl.com/VKq8");
position: fixed;
top: 34px;
left: 560px;
width: 120px;
height: 120px;
border-radius: 110px;
z-index: 2;
display: block;
opacity: 1;
}
.container {
background-color: rgba(0, 0, 0, 0.288);
position: absolute;
top: 50px;
left: 660px;
width: 260px;
height: 85px;
border-radius: 50px;
border-bottom-left-radius: 0%;
border-top-left-radius: 0%;
z-index: 1;
}
/*#heal, #armor, #hunger, #thirst, #stamina, #voice {
}*/
#boxHeal, #boxArmor, #boxStamina, #boxHunger, #boxThirst, #boxVoice {
width: 100%;
height: 100%;
transition: 0.2s ease-in-out;
}
#heal {
position: absolute;
left: 26px;
bottom: 70px;
width: 140px;
height: 10px;
padding: 0;
float:left;
}
#armor {
position: absolute;
left: 27px;
bottom: 54px;
width: 140px;
height: 10px;
}
#hunger {
position: absolute;
left: 62px;
bottom: 28px;
width: 113px;
height: 10px;
}
.iconhunger {
position: relative;
left: -40px;
bottom: 10px;
z-index: 3;
align-content: left;
}
#thirst {
position: absolute;
left: 22px;
bottom: 54px;
width: 113px;
height: 10px;
padding: 0;
float:left;
}
.iconthirst {
position: relative;
left: 0.5px;
bottom: -29.5px;
z-index: 3;
align-content: left;
}
#stamina {
position: absolute;
left: 62.5px;
bottom: 1px;
width: 113px;
height: 10px;
padding: 0;
float:left;
}
.iconstamina {
position: absolute;
z-index: 3;
align-content: left;
left: -36px;
bottom: -3px;
}
#voice {
position: absolute;
left: 200px;
bottom: -00px;
width: 107.5px;
height: 10px;
padding: 0;
float:left;
}
.fa-microphone {
position: absolute;
z-index: 3;
left: 69px;
bottom: 25px;
color: #525151;
font-size: 38px;
}
.fa-microphonebg {
position: absolute;
top: 0px;
left: 140px;
width: 121px;
height: 85px;
background-image:
radial-gradient(circle at 0% 50%, rgba(0,0,0,0) 50px, #fff 51px);
border-top-right-radius: 40px;
border-bottom-right-radius: 40px;
z-index: 2;
}
#boxHeal {
background: rgb(97, 191, 92);
border: solid 0.3px rgb(97, 191, 92);
border-radius: 30px;
}
#boxArmor {
background: rgb(96, 136, 220);
border: solid 0.3px rgb(96, 136, 220);
border-radius: 180px;
border: -5px;
}
#boxHunger {
background: rgb(255, 255, 255);
position: absolute;
left: -10px;
bottom: 7px;
border: solid 0.3px #ffffff;
border-radius: 30px;
}
#boxThirst {
background:rgb(255, 255, 255);
position: absolute;
left: 30px;
bottom: -34px;
border: solid 0.3px #ffffff;
border-radius: 30px;
}
#boxStamina {
background: rgb(255, 255, 255);
position: absolute;
left: -10px;
bottom: 4px;
border: solid 0.3px #ffffff;
border-radius: 30px;
}
#boxVoice {
background: rgb(180, 180, 180);
position: absolute;
z-index: 4;
height: 27px;
width: 14.1px;
left: 215px;
bottom: 36.5px;
border-radius: 30px;
}
#boxVoice.active {
background: rgb(46, 196, 66);
}
.position {
font-family: "gta-ui", Verdana, Tahoma;
font-size: 30px;
position: absolute;
bottom: 0.35%;
left: 16%;
text-shadow: -1px 1px 2px #000, 1px 1px 2px #000, 1px -1px 0 #000, -1px -1px 0 #000;
color: #ffffff;
}
.seperator {
color: rgb(224, 50, 50);
}
.seperator2 {
color: rgb(240, 200, 80);
}
#slideout {
position: fixed;
top: 100px;
left: -25px;
animation-delay: : 2s;
-webkit-transition-duration: 0.3s;
-moz-transition-duration: 0.3s;
-o-transition-duration: 0.3s;
transition-duration: 0.3s;
}
#slideout_tab {
position: relative;
top: 0;
left: 0;
}
#slideout_inner {
position: absolute;
top: -100px;
left: 26px;
}
#showblock:not(:checked)+#slideout {
left: -195px;
opacity: 0;
display: none;
}
#showblock:checked+#slideout {
opacity: 1;
display: block;
-webkit-animation: fadeInFromNone 0.5s ease-out;
-moz-animation: fadeInFromNone 0.5s ease-out;
-o-animation: fadeInFromNone 0.5s ease-out;
animation: fadeInFromNone 0.5s ease-out;
}
#-webkit-keyframes fadeInFromNone {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
opacity: 0;
}
100% {
display: block;
opacity: 1;
}
}
#-moz-keyframes fadeInFromNone {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
opacity: 0;
}
100% {
display: block;
opacity: 1;
}
}
#-o-keyframes fadeInFromNone {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
opacity: 0;
}
100% {
display: block;
opacity: 1;
}
}
#keyframes fadeInFromNone {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
opacity: 0;
}
100% {
display: block;
opacity: 1;
}
}
#showblock {
opacity: 1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>SoL RP UI</title>
<link href="css/style.css" rel="stylesheet" type="text/css"/>
<link rel="stylesheet" href="https://icono-49d6.kxcdn.com/icono.min.css">
<script src="https://kit.fontawesome.com/3f31cfc768.js"></script>
</head>
<body class="tempbg">
<div class="portrait">
</div>
<input type="checkbox" id="showblock">
<div id="slideout">
<label id="slideout_tab" for="showblock" title="Admin Slider">
</label>
<div id="slideout_inner">
<div class="container">
<div id="heal">
<div id="boxHeal"></div>
</div>
<div id="armor">
<div id="boxArmor"></div>
</div>
<div id="hunger">
<svg class="iconhunger" width="36" height="12" viewBox="0 0 14 12" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M9.44096 7.09788L12.0944 4.62314C13.9855 2.86906 14.0734 1.25095 13.9708 0.462298C13.9561 0.407908 13.9268 0.353518 13.8828 0.312725C13.7656 0.203945 13.5897 0.203945 13.4724 0.312725L12.6954 1.03339L2.94672 10.0893C2.62421 10.3885 2.62421 10.8916 2.94672 11.1907C3.26923 11.4899 3.81164 11.4899 4.13415 11.1907L4.33939 10.946C4.70588 10.4973 6.58232 7.98172 6.86086 7.58739C6.97813 7.42422 7.09541 7.32904 7.18337 7.28825C7.32997 7.23386 7.44724 7.30185 7.44724 7.30185C8.09227 7.65538 8.91321 7.58739 9.44096 7.09788Z" fill="white"/>
<path d="M4.95508 6.20047C5.49749 5.9965 5.86398 6.17327 6.09854 6.36364L6.86084 5.65657C6.65561 5.43901 6.46503 5.08547 6.68493 4.59596C6.99278 3.90249 7.242 3.45377 6.17184 2.37957C5.131 1.29176 3.4598 0.285548 2.68283 0.0679876C2.50692 0.027195 2.331 0 2.19906 0C2.1844 0 2.1844 0 2.16974 0C2.12577 0 2.09645 0.0135975 2.06713 0.0407925C1.99383 0.10878 1.99383 0.21756 2.06713 0.27195L4.70587 2.7195C4.83781 2.84188 4.83781 3.04584 4.70587 3.18182C4.57393 3.3042 4.35404 3.3042 4.20744 3.18182L3.89959 2.89627L3.21058 2.25719C2.69749 1.78127 2.36032 1.46853 2.03781 1.22378C1.26084 0.625486 0.95299 0.611888 0.95299 0.611888C0.95299 0.611888 0.835713 0.598291 0.733095 0.679876C0.645137 0.775058 0.659797 0.883838 0.659797 0.883838C0.659797 0.883838 0.674456 1.16939 1.33414 1.90365C1.59802 2.2028 1.93519 2.51554 2.44828 2.99145L3.13728 3.63054L3.44514 3.91608C3.57707 4.03846 3.57707 4.24242 3.44514 4.3784C3.3132 4.50078 3.0933 4.50078 2.94671 4.3784L0.307964 1.93085C0.234666 1.86286 0.117388 1.86286 0.0587496 1.93085C0.0294302 1.95804 0.0147705 1.98524 0.0147705 2.02603C0.0147705 2.02603 0.0147705 2.03963 0.0147705 2.05322C0.0147705 2.1756 0.0440899 2.33877 0.0880689 2.50194C0.307964 3.22261 1.40744 4.75913 2.58022 5.75175C3.73833 6.71717 4.20744 6.48601 4.95508 6.20047Z" fill="white"/>
<path d="M9.51434 7.737C9.1625 7.95456 8.73737 8.07694 8.29758 8.07694C8.03371 8.07694 7.78449 8.03614 7.53528 7.95456L10.6138 11.3539C11.0683 11.7619 11.7866 11.7619 12.2264 11.3539C12.6662 10.946 12.6662 10.2661 12.2264 9.85821L9.51434 7.737Z" fill="white"/>
</g>
</svg>
<div id="boxHunger">
</div>
</div>
<div id="thirst">
<svg class="iconthirst" width="36" height="14" viewBox="0 0 8 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.74196 0.100677C3.72525 0.0356591 3.65843 -0.013104 3.57491 0.00315034C3.52479 0.0194047 3.49138 0.0519134 3.47467 0.100677C2.9067 4.55437 0 5.46462 0 8.5692C0.0501155 10.5035 1.68722 12.0476 3.67514 11.9989C5.61294 11.9664 7.16652 10.4385 7.19993 8.5692C7.21663 5.48087 4.30993 4.55437 3.74196 0.100677ZM3.19069 5.02575C3.15728 5.15579 3.10716 5.30207 3.07375 5.44836C2.82317 6.34235 2.52248 7.35013 2.52248 8.52044C2.52248 9.15436 2.13826 9.38192 1.77075 9.38192C1.35312 9.38192 1.01902 9.05683 1.01902 8.65048C1.01902 7.26885 1.70393 6.35861 2.30531 5.56215C2.48907 5.31833 2.67283 5.07451 2.82317 4.84695C2.88999 4.74943 3.00693 4.73317 3.10716 4.79819C3.12387 4.81444 3.14057 4.8307 3.15728 4.84695C3.19069 4.89572 3.20739 4.96073 3.19069 5.02575Z" fill="white"/>
</svg>
<div id="boxThirst"></div>
</div>
<div id="stamina">
<svg class="iconstamina" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" width="22px" height="22px" viewBox="0 0 487.811 487.81" style="enable-background:new 0 0 487.811 487.81;" xml:space="preserve">
<g>
<g>
<g id="_x33_6_24_">
<g>
<path d="M150.463,109.521h150.512c3.955,0,7.16-3.206,7.16-7.161c0-3.955-3.205-7.161-7.16-7.161H150.463 c-3.955,0-7.161,3.206-7.161,7.161C143.302,106.315,146.508,109.521,150.463,109.521z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#FFFFFF"/>
<path d="M15.853,179.537h150.511c3.955,0,7.161-3.206,7.161-7.161s-3.206-7.16-7.161-7.16H15.853 c-3.955,0-7.161,3.205-7.161,7.16S11.898,179.537,15.853,179.537z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#FFFFFF"/>
<path d="M56.258,253.214c0,3.955,3.206,7.162,7.161,7.162H213.93c3.955,0,7.161-3.207,7.161-7.162s-3.206-7.16-7.161-7.16H63.419 C59.464,246.054,56.258,249.259,56.258,253.214z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#FFFFFF"/>
<path d="M142.396,336.44H7.161C3.206,336.44,0,339.645,0,343.6s3.206,7.161,7.161,7.161h135.235c3.955,0,7.161-3.206,7.161-7.161 S146.351,336.44,142.396,336.44z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#FFFFFF"/>
<path d="M385.729,154.418c21.6,0,39.111-17.513,39.111-39.114s-17.512-39.113-39.111-39.113 c-21.605,0-39.119,17.513-39.119,39.113C346.609,136.905,364.123,154.418,385.729,154.418z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#FFFFFF"/>
<path d="M450.066,143.155c-22.459,31.459-52.533,35.102-84.895,15.89c-2.203-1.306-11.977-6.691-14.141-7.977 c-52.061-30.906-104.061-18.786-138.934,30.05c-14.819,20.771,19.455,40.459,34.108,19.93 c18.018-25.232,40.929-32.533,65.986-24.541c-12.83,22.27-24.047,44.405-39.875,75.853 c-15.832,31.448-50.787,56.562-84.374,36.92c-24.235-14.165-46.09,20.651-21.928,34.772 c45.854,26.799,99.619,10.343,127.066-24.493c0.952,0.509,1.958,0.968,3.062,1.354c22.422,7.812,51.814,28.61,60.77,35.981 c8.953,7.371,24.336,44.921,33.471,63.788c11.082,22.893,46.871,6.219,35.748-16.771c-10.355-21.406-27.736-64.129-41.293-74.938 c-10.875-8.669-31.988-24.803-49.895-33.956c12.115-23.466,24.729-46.679,38.008-69.491 c42.328,12.969,82.561-2.308,111.215-42.446C498.996,142.312,464.73,122.624,450.066,143.155z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#FFFFFF"/>
</g>
</g>
</g>
</g>
</svg>
<div id="boxStamina"></div>
</div>
<div id="voice">
<div class="fa-microphonebg">
<i class="fas fa-microphone"></i>
</div>
<div id="boxVoice"></div>
</div>
</div> /*container*/
</div> /*slideout_inner*/
</div> /*slideout*/
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js">
</script>
<script src="js/app.js">
</script>
</body>
</html>
Your question is very broad, however I think one can sum it up to two methods:
Use classes to describe the state of the elements (e.g. the circle in the middle or on the left)
Use transform: translateX() together with the transition property.
For example, in the following snippet the right class is toggled upon clicking the red box:
const box = document.getElementById('box');
box.addEventListener('click', () => {
box.classList.toggle('right');
});
#container {
width: 80px;
height: 40px;
background-color: gray;
}
#box {
display: inline-block;
width: 40px;
height: 40px;
background-color: red;
margin: auto;
transition: all 0.4s;
}
.right {
transform: translateX(100%); /* When an element has the 'right' class,
it would move to the right by 100% */
transition: all 0.4s;
}
<div id="container">
<div id="box"></div>
</div>
You can modify this minimal example and play with the properties that vary among the "states" of your objects: their width, opacity and - of course - translate, as mentioned above.
I'm trying to change the color every image on click but they are not properly selectable because of overlying each other with positioning and z-index...
code is working as you can check by clicking on top right corner it change color...tried different methods of CSS, not JavaScript... newbie in JavaScript.
body,div,p,h1,h2,h3,h4,h5,h6,span {
margin: 0;
}
div.nav {
height: 100px;
width: 100%;
padding: 20px 0;
background-color: #615d5d;
text-align: center;
}
.screens_wrap {
display: inline-block;
margin: 0 auto;
height: 100%;
position: relative;
}
.screen_inner {
position: relative;
height: 100%;
margin: 0 auto;
width: 150px;
}
.screen {
position: absolute;
width:100px;
height: 58px;
border: 3px solid #aeaeae;
}
/* transparent style -------------------------------------------------------------------*/
.nav .screen.screen1 {
bottom: 0;
left: 0;
z-index: 3;
background-color: #00ad63;
}
.nav a .screen.screen2 {
bottom: 15px;
left: 15px;
z-index: 2;
background-color: transparent;
}
.nav a .screen.screen2:hover{
background-color: #4f025a;
}
.nav .screen.screen3 {
bottom: 30px;
left: 30px;
z-index: 1;
background-color: transparent;
}
.nav .screen.screen3:hover{
background-color: #ffec36;
}
.nav .screen2:hover, .screen3:hover {
-webkit-animation-name: hover;
-webkit-animation-duration: 1s;
animation-name: hover;
animation-duration: 4s;
-webkit-animation-fill-mode: forwards;
opacity: 1;
width: 100px;
}
.nav.nav6 {
height: 200px;
}
.screen_inner a.screenanchors:first-child img {
position: absolute;
left: 0;
top: 0;
z-index: 1;
}
.screen_inner a.screenanchors:nth-child(2) img{
position: absolute;
left: 20px;
top: 20px;
z-index: 2;
}
.screen_inner a.screenanchors:nth-child(3) img{
position: absolute;
left: 40px;
top: 40px;
z-index: 3;
}
.screenanchors img {
overflow: hidden;
}
#keyframes spinning {
from {
transform: translateZ(-5em) rotateY(0deg);
}
to {
transform: translateZ(-5em) rotateY(180deg);
}
}
#keyframes skewing {
from {
transform: translateZ(-5em) skew(-3deg, -25deg);
}
to {
transform: translateZ(-5em) skew(-3deg, 0deg);
width: 100%;
height: 100px;
z-index: 9999999;
bottom: 0;
}
}
/* Standard syntax */
#keyframes hover {
0% {
margin-bottom:+10px;
bottom: unset;
}
100% {
margin-bottom:+10px;
bottom: unset;
}
}
<div class="nav nav6" style="margin-top: 25px;">
<div class="screens_wrap">
<div class="screen_inner">
<img id="imgName" src="https://imageshack.com/i/plylrZh4p" onclick="changeSrc()" width="100px">
<img id="imgName1" src="https://imageshack.com/i/pljaZE0Gp" onclick="changeSrc1()" width="100px">
<img id="imgName2" src="https://imageshack.com/i/plm9slyTp" onclick="changeSrc2()" width="100px">
</div>
</div>
</div>
<script>
function changeSrc(){
document.getElementById("imgName").src="https://imageshack.com/i/plm9slyTp";
document.getElementById("imgName1").src="https://imageshack.com/i/plylrZh4p";
document.getElementById("imgName2").src="https://imageshack.com/i/pljaZE0Gp";
}
function changeSrc1(){
document.getElementById("imgName").src="https://imageshack.com/i/pljaZE0Gp";
document.getElementById("imgName1").src="https://imageshack.com/i/plm9slyTp";
document.getElementById("imgName2").src="https://imageshack.com/i/plylrZh4p";
}
function changeSrc2(){
document.getElementById("imgName").src="https://imageshack.com/i/plylrZh4p";
document.getElementById("imgName1").src="https://imageshack.com/i/pljaZE0Gp";
document.getElementById("imgName2").src="https://imageshack.com/i/plm9slyTp";
}
</script>
it should work by clicking every where on single image, no overlay effecting clickable space...
Just to Help out others, I fixed the issue using area mapping...
I have searched this website to find progress bars, but the ones I have been able to found show animated circles that go to the full 100%.
I would like it to stop at certain percentages like in the screenshot below. Is there any way I can do that using only CSS?
I created a fiddle using only CSS.
.wrapper {
width: 100px; /* Set the size of the progress bar */
height: 100px;
position: absolute; /* Enable clipping */
clip: rect(0px, 100px, 100px, 50px); /* Hide half of the progress bar */
}
/* Set the sizes of the elements that make up the progress bar */
.circle {
width: 80px;
height: 80px;
border: 10px solid green;
border-radius: 50px;
position: absolute;
clip: rect(0px, 50px, 100px, 0px);
}
/* Using the data attributes for the animation selectors. */
/* Base settings for all animated elements */
div[data-anim~=base] {
-webkit-animation-iteration-count: 1; /* Only run once */
-webkit-animation-fill-mode: forwards; /* Hold the last keyframe */
-webkit-animation-timing-function:linear; /* Linear animation */
}
.wrapper[data-anim~=wrapper] {
-webkit-animation-duration: 0.01s; /* Complete keyframes asap */
-webkit-animation-delay: 3s; /* Wait half of the animation */
-webkit-animation-name: close-wrapper; /* Keyframes name */
}
.circle[data-anim~=left] {
-webkit-animation-duration: 6s; /* Full animation time */
-webkit-animation-name: left-spin;
}
.circle[data-anim~=right] {
-webkit-animation-duration: 3s; /* Half animation time */
-webkit-animation-name: right-spin;
}
/* Rotate the right side of the progress bar from 0 to 180 degrees */
#-webkit-keyframes right-spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(180deg);
}
}
/* Rotate the left side of the progress bar from 0 to 360 degrees */
#-webkit-keyframes left-spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
/* Set the wrapper clip to auto, effectively removing the clip */
#-webkit-keyframes close-wrapper {
to {
clip: rect(auto, auto, auto, auto);
}
}
<div class="wrapper" data-anim="base wrapper">
<div class="circle" data-anim="base left"></div>
<div class="circle" data-anim="base right"></div>
</div>
Also check this fiddle here (CSS only)
#import url(http://fonts.googleapis.com/css?family=Josefin+Sans:100,300,400);
.arc1 {
width: 160px;
height: 160px;
background: #00a0db;
-webkit-transform-origin: -31% 61%;
margin-left: -30px;
margin-top: 20px;
-webkit-transform: translate(-54px,50px);
-moz-transform: translate(-54px,50px);
-o-transform: translate(-54px,50px);
}
.arc2 {
width: 160px;
height: 160px;
background: #00a0db;
-webkit-transform: skew(45deg,0deg);
-moz-transform: skew(45deg,0deg);
-o-transform: skew(45deg,0deg);
margin-left: -180px;
margin-top: -90px;
position: absolute;
-webkit-transition: all .5s linear;
-moz-transition: all .5s linear;
-o-transition: all .5s linear;
}
.arc-container:hover .arc2 {
margin-left: -50px;
-webkit-transform: skew(-20deg,0deg);
-moz-transform: skew(-20deg,0deg);
-o-transform: skew(-20deg,0deg);
}
.arc-wrapper {
width: 150px;
height: 150px;
border-radius:150px;
background: #424242;
overflow:hidden;
left: 50px;
top: 50px;
position: absolute;
}
.arc-hider {
width: 150px;
height: 150px;
border-radius: 150px;
border: 50px solid #e9e9e9;
position:absolute;
z-index:5;
box-shadow:inset 0px 0px 20px rgba(0,0,0,0.7);
}
.arc-inset {
font-family: "Josefin Sans";
font-weight: 100;
position: absolute;
font-size: 413px;
margin-top: -64px;
z-index: 5;
left: 30px;
line-height: 327px;
height: 280px;
-webkit-mask-image: -webkit-linear-gradient(top, rgba(0,0,0,1), rgba(0,0,0,0.2));
}
.arc-lowerInset {
font-family: "Josefin Sans";
font-weight: 100;
position: absolute;
font-size: 413px;
margin-top: -64px;
z-index: 5;
left: 30px;
line-height: 327px;
height: 280px;
color: white;
-webkit-mask-image: -webkit-linear-gradient(top, rgba(0,0,0,0.2), rgba(0,0,0,1));
}
.arc-overlay {
width: 100px;
height: 100px;
background-image: linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
background-image: -o-linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
background-image: -moz-linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
background-image: -webkit-linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
padding-left: 32px;
box-sizing: border-box;
-moz-box-sizing: border-box;
line-height: 100px;
font-family: sans-serif;
font-weight: 400;
text-shadow: 0 1px 0 #fff;
font-size: 22px;
border-radius: 100px;
position: absolute;
z-index: 5;
top: 75px;
left: 75px;
box-shadow:0px 0px 20px rgba(0,0,0,0.7);
}
.arc-container {
position: relative;
background: #e9e9e9;
height: 250px;
width: 250px;
}
<div class="arc-container">
<div class="arc-hider"></div>
<div class="arc-inset">
o
</div>
<div class="arc-lowerInset">
o
</div>
<div class="arc-overlay">
35%
</div>
<div class="arc-wrapper">
<div class="arc2"></div>
<div class="arc1"></div>
</div>
</div>
Or this beautiful round progress bar with HTML5, CSS3 and JavaScript.
What about that?
HTML
<div class="chart" id="graph" data-percent="88"></div>
Javascript
var el = document.getElementById('graph'); // get canvas
var options = {
percent: el.getAttribute('data-percent') || 25,
size: el.getAttribute('data-size') || 220,
lineWidth: el.getAttribute('data-line') || 15,
rotate: el.getAttribute('data-rotate') || 0
}
var canvas = document.createElement('canvas');
var span = document.createElement('span');
span.textContent = options.percent + '%';
if (typeof(G_vmlCanvasManager) !== 'undefined') {
G_vmlCanvasManager.initElement(canvas);
}
var ctx = canvas.getContext('2d');
canvas.width = canvas.height = options.size;
el.appendChild(span);
el.appendChild(canvas);
ctx.translate(options.size / 2, options.size / 2); // change center
ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); // rotate -90 deg
//imd = ctx.getImageData(0, 0, 240, 240);
var radius = (options.size - options.lineWidth) / 2;
var drawCircle = function(color, lineWidth, percent) {
percent = Math.min(Math.max(0, percent || 1), 1);
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
ctx.strokeStyle = color;
ctx.lineCap = 'round'; // butt, round or square
ctx.lineWidth = lineWidth
ctx.stroke();
};
drawCircle('#efefef', options.lineWidth, 100 / 100);
drawCircle('#555555', options.lineWidth, options.percent / 100);
and CSS
div {
position:relative;
margin:80px;
width:220px; height:220px;
}
canvas {
display: block;
position:absolute;
top:0;
left:0;
}
span {
color:#555;
display:block;
line-height:220px;
text-align:center;
width:220px;
font-family:sans-serif;
font-size:40px;
font-weight:100;
margin-left:5px;
}
http://jsfiddle.net/Aapn8/3410/
Basic code was taken from Simple PIE Chart http://rendro.github.io/easy-pie-chart/
Check this out :)
I made this one using conic-gradient.
background: conic-gradient(
SomeColor1 80%,
SomeColor2 80%
);
You can create a pie chart using conic-gradient.
div {
background: conic-gradient(
red 36deg, orange 36deg 170deg, yellow 170deg);
border-radius: 50%
}
I select only two colors for the pie chart.
background: conic-gradient(
rgb(3, 133, 255) 80%,
rgb(242, 242, 242) 80%
);
then place a div on top of the pie chart to make it looks like a circular progress indicator. Then set progress using HTML DOM innerHTML option.
Then you can use incrementProgress() and decrementProgress() fuctions to change progress dynamically.
Follow my complete example to get some idea :)
You can make upload/download progress indicators, charts for dashboards, etc. using this.
<html>
<head>
<style>
body {
display: flex;
align-items: center;
justify-content: center;
}
#progress-spinner {
border-radius: 50%;
height: 100px;
width: 100px;
}
#middle-circle {
position: absolute;
border-radius: 50%;
height: 80px;
width: 80px;
background-color: rgb(248, 248, 248);
display: flex;
align-items: center;
justify-content: center;
font-size: large;
font-weight: bold;
}
</style>
</head>
<body>
<div
style="
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
"
>
<div
style="
position: relative;
display: flex;
justify-content: center;
align-items: center;
"
>
<div id="middle-circle"></div>
<div id="progress-spinner"></div>
</div>
<div style="margin-top: 30px">
<button type="button" id="incbtn">+</button>
<button type="button" id="decbtn">-</button>
</div>
</div>
<script>
var progress = 0;
document
.getElementById("incbtn")
.addEventListener("click", incrementProgress);
document
.getElementById("decbtn")
.addEventListener("click", decrementProgress);
function incrementProgress() {
if (progress != 100) {
progress = progress + 10;
console.log(progress);
setProgress();
}
}
function decrementProgress() {
if (progress != 0) {
progress = progress - 10;
console.log(progress);
setProgress();
}
}
function setProgress() {
document.getElementById("progress-spinner").style.background =
"conic-gradient(rgb(3, 133, 255) " +
progress +
"%,rgb(242, 242, 242) " +
progress +
"%)";
document.getElementById("middle-circle").innerHTML =
progress.toString() + "%";
}
window.onload = function () {
setProgress();
};
</script>
</body>
</html>
Another pure css based solution that is based on two clipped rounded elements that i rotate to get to the right angle:
http://jsfiddle.net/maayan/byT76/
That's the basic css that enables it:
.clip1 {
position:absolute;
top:0;left:0;
width:200px;
height:200px;
clip:rect(0px,200px,200px,100px);
}
.slice1 {
position:absolute;
width:200px;
height:200px;
clip:rect(0px,100px,200px,0px);
-moz-border-radius:100px;
-webkit-border-radius:100px;
border-radius:100px;
background-color:#f7e5e1;
border-color:#f7e5e1;
-moz-transform:rotate(0);
-webkit-transform:rotate(0);
-o-transform:rotate(0);
transform:rotate(0);
}
.clip2
{
position:absolute;
top:0;left:0;
width:200px;
height:200px;
clip:rect(0,100px,200px,0px);
}
.slice2
{
position:absolute;
width:200px;
height:200px;
clip:rect(0px,200px,200px,100px);
-moz-border-radius:100px;
-webkit-border-radius:100px;
border-radius:100px;
background-color:#f7e5e1;
border-color:#f7e5e1;
-moz-transform:rotate(0);
-webkit-transform:rotate(0);
-o-transform:rotate(0);
transform:rotate(0);
}
and the js rotates it as required.
quite easy to understand..
Hope it helps,
Maayan
A minimalistic approach using just one element and a couple of attributes:
Use data-progress to define the internal label and --progress to define the progress from 0deg to 360deg.
<div data-progress="36" style="--progress: 36deg;">36%</div>
div {
display: flex;
width: 100px;
height: 100px;
border-radius: 50%;
background: conic-gradient(red var(--progress), gray 0deg);
font-size: 0;
}
div::after {
content: attr(data-progress) '%';
display: flex;
justify-content: center;
flex-direction: column;
width: 100%;
margin: 10px;
border-radius: 50%;
background: white;
font-size: 1rem;
text-align: center;
}
<div data-progress="36" style="--progress: 36deg;">36%</div>
Here's a naïve approach to the animation, again all CSS, no JS and just one element:
div {
display: flex;
width: 100px;
height: 100px;
border-radius: 50%;
background: conic-gradient(red var(--progress), gray 0deg);
font-size: 0;
animation: .4s ease-out turn_in reverse;
}
div::after {
content: attr(data-progress);
display: flex;
justify-content: center;
flex-direction: column;
width: 100%;
margin: 10px;
border-radius: 50%;
background: white;
font-size: 1rem;
text-align: center;
}
#keyframes turn_in {
5% {
background: conic-gradient(red calc(var(--progress) * .95), gray 0deg);
}
10% {
background: conic-gradient(red calc(var(--progress) * .9), gray 0deg);
}
15% {
background: conic-gradient(red calc(var(--progress) * .85), gray 0deg);
}
20% {
background: conic-gradient(red calc(var(--progress) * .8), gray 0deg);
}
25% {
background: conic-gradient(red calc(var(--progress) * .75), gray 0deg);
}
30% {
background: conic-gradient(red calc(var(--progress) * .7), gray 0deg);
}
35% {
background: conic-gradient(red calc(var(--progress) * .65), gray 0deg);
}
40% {
background: conic-gradient(red calc(var(--progress) * .6), gray 0deg);
}
45% {
background: conic-gradient(red calc(var(--progress) * .55), gray 0deg);
}
50% {
background: conic-gradient(red calc(var(--progress) * .5), gray 0deg);
}
55% {
background: conic-gradient(red calc(var(--progress) * .45), gray 0deg);
}
60% {
background: conic-gradient(red calc(var(--progress) * .4), gray 0deg);
}
65% {
background: conic-gradient(red calc(var(--progress) * .35), gray 0deg);
}
70% {
background: conic-gradient(red calc(var(--progress) * 0.3), gray 0deg);
}
75% {
background: conic-gradient(red calc(var(--progress) * 0.25), gray 0deg);
}
80% {
background: conic-gradient(red calc(var(--progress) * .2), gray 0deg);
}
85% {
background: conic-gradient(red calc(var(--progress) * .15), gray 0deg);
}
90% {
background: conic-gradient(red calc(var(--progress) * .1), gray 0deg);
}
95% {
background: conic-gradient(red calc(var(--progress) * .05), gray 0deg);
}
100% {
background: conic-gradient(gray 0deg);
}
}
<div data-progress="85%" style="--progress: 85%;">85%</div>
Disclaimer: cross-browsing not tested.
A different idea with new #property. See the support table
#property --a {
syntax: '<angle>';
inherits: false;
initial-value: 90deg;
}
.circle {
width: 120px;
height: 120px;
padding: 12px;
box-sizing: border-box;
-webkit-mask:
conic-gradient(#000 var(--a), transparent var(--a)),
linear-gradient(#000, #000) content-box;
-webkit-mask-composite: source-out;
mask-composite: subtract;
background: tomato;
border-radius: 50%;
animation: progress 1s .3s linear forwards;
}
#keyframes progress {
to {
--a: 250deg;
}
}
<div class="circle"></div>
And I saw a more powerful example by Alvaro Montoro. Be sure to check this out.
acceding your data you can change process like <div ... data-num="50"> output 50% that go to the show fully animated circles and number.
change in data-num="/* 0-100 */".
you can add multiple process like 5,10.
using Javascript,CSS,Html with animated circle and number.
Output
Code
let items = document.querySelectorAll('.progress-item');
const counters = Array(items.length);
const intervals = Array(items.length);
counters.fill(0);
items.forEach((number,index) => {
intervals[index] = setInterval(() => {
if(counters[index] == parseInt(number.dataset.num)){
clearInterval(intervals[index]);
}else{
counters[index] += 1;
number.style.background = "conic-gradient(red calc(" + counters[index] + "%), gray 0deg)";
number.setAttribute('data-value', counters[index] + "%");
number.innerHTML = counters[index] + "%";
}
}, 15);
});
#progress{
display: flex;
justify-content: space-around;
}
.progress-item {
display: flex;
width: 100px;
height: 100px;
border-radius: 50%;
font-size: 0;
animation: .4s ease-out reverse;
}
.progress-item::after {
content: attr(data-value);
display: flex;
justify-content: center;
flex-direction: column;
width: 100px;
margin: 10px;
border-radius: 50%;
background: white;
font-size: 1rem;
text-align: center;
}
<div id="progress" >
<div data-num="40" class="progress-item">sd</div>
<div data-num="80" class="progress-item">sd</div>
<div data-num="57" class="progress-item">sd</div>
<div data-num="83" class="progress-item">sd</div>
<div data-num="90" class="progress-item">ds</div>
</div>
Flexible SVG solution for radial progress-bar (CSS only): the solution in calculating(via calc) border length of circle inside SVG.
Progress-circle in samples is overlay on element, and may be transparent.
jQuery(function($){
setTimeout(() => $('#element1 [data-role="radial-progress"]').css('--progress-percent', '100'), 1000);
$('#element2 [data-role="radial-progress"]').css('--progress-percent', '80');
$('#element3 [data-role="radial-progress"]').css('--progress-percent', '100');
let progress4 = 0;
let progress4incrementor = setInterval(() => {
progress4++;
$('#element4 .value').html(progress4 + '%');
$('#element4 [data-role="radial-progress"]').css('--progress-percent', progress4.toString());
if (progress4 >= 100) clearInterval(progress4incrementor);
}, 100);
});
.element
{
position: relative;
}
[data-role="radial-progress"]
{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
--progress-percent: 0;
--progress-color: #CC000077;
--progress-bar-width: 100%;
}
[data-role="radial-progress"] > circle
{
stroke-width: var(--progress-bar-width);
stroke-dasharray: calc(100% * 3.141592);
stroke-dashoffset: calc(100% * (100 - var(--progress-percent))/100 * 3.141592);
stroke: var(--progress-color);
}
/*Just for animate --data-percent */
#element1 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 4s linear;
}
#element2 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 2s linear;
}
#element3 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 6s linear;
}
#element4 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 0.1s linear;
}
/*Сode that does not depend on radial-progress*/
.element
{
background-image: url(https://static.wikia.nocookie.net/dune/images/2/2f/Duneii-wind-trap.jpg/revision/latest);
background-size: 100% 100%;
display: inline-block;
width: 180px;
height: 110px;
border: 2px solid red;
text-align: center;
color: red;
}
#element3
{
width: 110px;
}
#element3 [data-role="radial-progress"]
{
transform: rotate(-90deg);
}
#element4
{
display: inline-flex;
align-items: center;
justify-content: center;
}
#element4 .value
{
font-size: 2em;
font-weight: bold;
z-index: 2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="element1" class="element">
Content
<svg data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="50%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>
<div id="element2" class="element">
Content
<svg style="--progress-percent:30" data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="50%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>
<div id="element3" class="element">
Content
<svg style="--progress-bar-width:10px;--progress-color:red;" data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="44%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>
<div id="element4" class="element">
<span class="value">0%</span>
<svg data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="50%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>