Jan 12, 2026
Back in the day, building a circular progress bar meant suffering with SVG. Even now, opening DevTools on some of those old implementations still hurts. Today, things have become dramatically simpler.
Modern CSS lets us build a complex, flexible, and visually pleasing circular progress bar using literally a single div and a single CSS property. And all of that comes with excellent browser support.
In this article, I’ll walk through this exact technique. We’ll start with the core idea, then move on to customization options. After that, we’ll add a bit of visual “polish”, convenient control knobs, and some experimental CSS logic. Yes — at the very end, we’ll even do a bit of programming in CSS.
The core idea and a basic implementation
Let’s start with the most important part. The entire implementation revolves around a single element:
<div class="progress"></div>
And a single property — background-image with multiple background layers. The core idea is simple:
Here’s the basic CSS:
.progress {
width: 150px;
height: 150px;
background-image:
radial-gradient(
circle,
#222 0% 27%,
transparent 28% 50%,
#222 51%
),
conic-gradient(
#D64E42 0% 60%,
transparent 60%
);
}
The radial gradient on top creates the “donut” — a scale with a transparent cut-out center. The conic gradient underneath fills a sector of the circle, effectively controlling the progress.
It’s worth noting that this approach relies on old — one might even say “ancient” — CSS features: multiple backgrounds, radial and conic gradients, and hard color transitions.
Basic circular progress bar implementation
This is the key technique that forms the foundation of the progress bar. Everything that follows is just customization and layering on top of it.
Customization: scale thickness and transparency
One of the nicest things about this approach is how easy it is to customize.
Scale thickness is controlled by the parameters of the top, radial gradient. We simply tweak the color stop positions:
radial-gradient(
circle,
#222 0% 30%,
transparent 31% 54%,
#222 55%
)
Color and transparency of both the scale and the fill are controlled by the bottom, conic gradient. Change the first color stop to a semi-transparent color — and the fill becomes translucent. Change the second color stop — and the empty part of the scale changes.
conic-gradient(
rgba(214, 78, 66, 0.6) 0% 60%,
transparent 60%
)
No extra elements, no masks, no calculations. Just gradient parameters.
Adjusting scale thickness and fill transparency
Making it look good: texture, borders, and shadows
The basic version works, but it looks a bit rough. Let’s add some visual “expensiveness”.
First, we add a third background layer — a repeating conic gradient that creates subtle radial sections:
repeating-conic-gradient(
rgba(0, 0, 0, 0.3),
rgba(0, 0, 0, 0.2) 4.5%,
transparent 5%
)
Second, we make the top radial gradient more complex by adding intermediate colors to create thin borders:
radial-gradient(
circle,
#222 0% 27%,
#333,
transparent 28% 50%,
#333,
#222 51%
)
And finally, we slightly round the progress bar itself and add shadows:
.progress {
border-radius: 10px;
box-shadow: inset 0 0 1px #666, 0 0 30px black;
}
None of this affects the logic of the component — it’s purely visual.
Final styling
Control knobs: CSS variables
Now let’s make the progress bar practical for real interfaces. To do that, we introduce a CSS variable called --progress.
.progress {
--progress: 45;
--corner: calc(1% * var(--progress, 0));
background-image:
radial-gradient(
circle,
#222 0% 27%,
#333,
transparent 28% 50%,
#333,
#222 51%
),
conic-gradient(
#D64E42 0% var(--corner),
transparent var(--corner)
);
}
Now progress is expressed as a clear number from 0 to 100, and CSS automatically converts it into the required angle.
It’s easy to create multiple instances of the component:
<div class="progress" style="--progress: 15"></div>
<div class="progress" style="--progress: 50"></div>
<div class="progress" style="--progress: 90"></div>
Controlling progress with a CSS variable
Experimental CSS features: conditional logic
Now let’s take a small peek into the future of CSS. In modern versions of Chrome, you can already use conditional logic via if().
For example, you can change the scale color depending on the progress value:
.progress {
--color: if(
style(--progress <= 33): #D64E42;
style(--progress <= 66): #F5B848;
style(--progress <= 99): #58B473;
else: white;
);
}
And then use that color in the gradient:
conic-gradient(
var(--color) 0% var(--corner),
transparent var(--corner)
)
You can also add a label in the center of the progress bar that changes depending on the progress value. We add a pseudo-element and use if() in the content property to bind the label text to progress ranges. For the label color, we reuse the parent’s --color variable.
.progress {
display: flex;
justify-content: center;
align-items: center;
}
.progress::before {
content: if(
style(--progress <= 33): "low";
style(--progress <= 66): "med";
style(--progress <= 99): "high";
else: "go!";
);
color: var(--color);
}
Important: these are experimental features. If you need solid browser support, use JavaScript together with modifier classes instead.
Conditional styling based on progress
Wow factor: native animation
And finally — the fun part. This progress bar works beautifully with native CSS animations.
First, we register the --progress variable:
@property --progress {
inherits: true;
initial-value: 0;
syntax: "<number>";
}
And then animate it:
.progress {
animation: progress 10s infinite alternate;
}
@keyframes progress {
to {
--progress: 100;
}
}
During the animation, the following update automatically:
-
the fill size,
-
the scale color,
-
the center label.
In other words, all styles tied to --progress are recalculated on the fly as the native animation updates the variable.
Progress bar animation
Conclusion
The key technique throughout this article is using multiple backgrounds with radial and conic gradients. It’s simple, well-supported, and extremely flexible.
Everything else — customization, visual effects, conditional logic, animation — is just an optional layer on top.
If you need a reliable production-ready component, stick to the basic technique. If you’re in an experimental mood and browser support allows it, try the newer features — they’re already available in recent versions of Chrome.
The complete code lives in an interactive, step-by-step demo — you can go through the implementation at your own pace and play with the parameters along the way.
Hopefully, building progress bars in 2026 will feel a lot more enjoyable.
<!DOCTYPE html><html lang="en" class="no-js"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><script>var b=document.documentElement.classList;b.remove('no-js');if(!window.Promise||!window.sessionStorage||!!sessionStorage.getItem('muller.v2')){b.add('muller')}</script><link rel="dns-prefetch" href="https://assets.htmlacademy.org"><script async src="https://www.googletagmanager.com/gtag/js?id=G-MXPCRXM48C"></script><script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-MXPCRXM48C');
</script><script type="text/javascript">
(function(e,t){var n=e.amplitude||{_q:[],_iq:{}};var r=t.createElement("script")
;r.type="text/javascript"
;r.integrity="sha384-d/yhnowERvm+7eCU79T/bYjOiMmq4F11ElWYLmt0ktvYEVgqLDazh4+gW9CKMpYW"
;r.crossOrigin="anonymous";r.async=true
;r.src="https://cdn.amplitude.com/libs/amplitude-5.2.2-min.gz.js"
;r.onload=function(){if(!e.amplitude.runQueuedFunctions){
console.log("[Amplitude] Error: could not load SDK")}}
;var i=t.getElementsByTagName("script")[0];i.parentNode.insertBefore(r,i)
;function s(e,t){e.prototype[t]=function(){
this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));return this}}
var o=function(){this._q=[];return this}
;var a=["add","append","clearAll","prepend","set","setOnce","unset"]
;for(var u=0;u<a.length;u++){s(o,a[u])}n.Identify=o;var c=function(){this._q=[]
;return this}
;var l=["setProductId","setQuantity","setPrice","setRevenueType","setEventProperties"]
;for(var p=0;p<l.length;p++){s(c,l[p])}n.Revenue=c
;var d=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties","identify","clearUserProperties","setGroup","logRevenueV2","regenerateDeviceId","groupIdentify","onInit","logEventWithTimestamp","logEventWithGroups","setSessionId","resetSessionId"]
;function v(e){function t(t){e[t]=function(){
e._q.push([t].concat(Array.prototype.slice.call(arguments,0)))}}
for(var n=0;n<d.length;n++){t(d[n])}}v(n);n.getInstance=function(e){
e=(!e||e.length===0?"$default_instance":e).toLowerCase()
;if(!n._iq.hasOwnProperty(e)){n._iq[e]={_q:[]};v(n._iq[e])}return n._iq[e]}
;e.amplitude=n})(window,document);
amplitude.getInstance().init("df11525b6880a3c5e2af14f9b6238408", null,{
includeUtm: true,
includeGclid: true,
includeReferrer: true,
deviceIdFromUrlParam: true
}, function (instance) {
window.amplitudeLoaded = true;
});
</script><link rel="stylesheet" href="https://assets.htmlacademy.org/css/core.v284.css"><link rel="stylesheet" href="https://assets.htmlacademy.org/css/text.v104.css"><link rel="stylesheet" href="https://assets.htmlacademy.org/css/profile.v236.css"><link rel="stylesheet" href="/css/custom.css"><style>
.page-content__inner {
max-width: 800px;
}
.post-list__meta {
margin-top: 15px;
font-size: 0.8em;
}
.post-list__meta .post-author {
margin-left: 10px;
color: #999;
}
.text-container {
max-width: 680px;
}
.text-container h1,
.text-container h2,
.text-container h3 {
border-bottom: none;
padding-bottom: 0;
}
.post-intro {
margin: 40px 0;
padding-bottom: 40px;
border-bottom: 2px solid #eee;
}
.post-intro h1 {
font-size: 44px;
line-height: 1.3;
margin-bottom: 10px;
}
.post-intro h1 {
font-size: 44px;
line-height: 1.3;
margin-bottom: 10px;
}
.post-intro .meta {
margin-top: 0;
}
.post-intro .post-author {
margin-left: 20px;
color: #999;
}
.post-intro .lead {
margin-bottom: 0;
font-size: 20px;
}
</style><link rel="stylesheet" href="/css/cookies.css"><link rel="preload" as="script" href="https://assets.htmlacademy.org/js/general.v274.js"><title>Building a complex progress bar in 2026 — Blog — HTML Academy</title><meta name="description" content="Back in the day, building a circular progress bar meant suffering with SVG. Even now, opening DevTools on some of those old implementations still hurts. Today, things have become dramatically simpler."><meta property="og:type" content="website"><meta property="og:site_name" content="HTML Academy"><meta name="twitter:url" property="og:url" content="https://htmlacademy.org/blog/progressbar-2026"><meta name="twitter:title" property="og:title" content="Building a complex progress bar in 2026"><meta name="twitter:description" property="og:description" content="Back in the day, building a circular progress bar meant suffering with SVG. Even now, opening DevTools on some of those old implementations still hurts. Today, things have become dramatically simpler."><meta name="theme-color" content="#2f358f"></head><body><header class="page-header"><div class="page-header__inner"><div class="page-header__top"><a class="page-header__logo" href="/"><img src="https://assets.htmlacademy.org/img/logo.v2.svg" width="104" height="36" alt="HTML Academy"></a><nav class="main-menu" aria-label="Main navigation" itemscope itemtype="http://schema.org/SiteNavigationElement"><ul class="main-menu__list main-menu__list--main main-menu__list--adaptive"><li class="main-menu__item main-menu__item--logo"><a class="main-menu__link" href="/" title="HTML Academy main page"><img src="https://assets.htmlacademy.org/img/logo.v2.svg" width="104" height="36" alt="HTML Academy"></a></li><li class="main-menu__item"><a class="main-menu__link" href="/courses" title="Courses"><span class="main-menu__icon"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#course"></use></svg></span>Courses</a></li><li class="main-menu__item"><a class="main-menu__link" href="/tutorials" title="Tutorials"><span class="main-menu__icon"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#intensive"></use></svg></span>Tutorials</a></li><li class="main-menu__item"><a class="main-menu__link" href="/blog" title="Blog"><span class="main-menu__icon"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#hat"></use></svg></span>Blog</a></li></ul><button class="main-menu__trigger" type="button" title="Main menu"><span></span></button><div class="main-menu__dropdown" id="main-menu"><div class="main-menu__dropdown-inner"><ul class="main-menu__list main-menu__list--main"><li class="main-menu__item" itemprop="name"><a class="main-menu__link" href="/courses" itemprop="url"><span class="main-menu__icon" aria-hidden="true"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#course"></use></svg></span>Courses</a></li><li class="main-menu__item" itemprop="name"><a class="main-menu__link" href="/tutorials" itemprop="url"><span class="main-menu__icon" aria-hidden="true"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#intensive"></use></svg></span>Tutorials</a></li><li class="main-menu__item" itemprop="name"><a class="main-menu__link" href="/blog" itemprop="url"><span class="main-menu__icon" aria-hidden="true"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#hat"></use></svg></span>Blog</a></li></ul><ul class="main-menu__list main-menu__list--user main-menu__list--user-guest"><li class="main-menu__item" itemprop="name"><a class="main-menu__link" href="/signup?redirect_url=%2Fblog%2Fprogressbar-2026" title="Sign up" data-modal="open" data-value="register" itemprop="url"><span class="main-menu__icon" aria-hidden="true"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#user"></use></svg></span>Sign up</a></li><li class="main-menu__item main-menu__item--login" itemprop="name"><a class="main-menu__link" href="/login?redirect_url=%2Fblog%2Fprogressbar-2026" title="Log in" data-modal="open" data-value="login" itemprop="url"><span class="main-menu__icon" aria-hidden="true"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#login"></use></svg></span>Log in</a></li></ul></div></div></nav></div></div></header><div class="page-content page-content--static"><div class="page-content__inner"><nav class="breadcrumbs" itemscope itemtype="http://schema.org/SiteNavigationElement"><ul class="breadcrumbs__list"><li class="breadcrumbs__item" itemprop="name"><a href="/" itemprop="url">Home</a></li><li class="breadcrumbs__item" itemprop="name"><a href="/blog" itemprop="url">Blog</a></li></ul></nav><section class="text-container breadcrumbs-offset"><header class="post-intro"><h1>Building a complex progress bar in 2026</h1><p class="meta"><time>Jan 12, 2026</time><span class="post-author">Alexander Pershin</span></p><p class="lead">Back in the day, building a circular progress bar meant suffering with SVG. Even now, opening DevTools on some of those old implementations still hurts. Today, things have become dramatically simpler.</p><p class="lead">Modern CSS lets us build a complex, flexible, and visually pleasing circular progress bar using literally a single <code>div</code> and a single CSS property. And all of that comes with excellent browser support.</p><p class="lead">In this article, I’ll walk through this exact technique. We’ll start with the core idea, then move on to customization options. After that, we’ll add a bit of visual “polish”, convenient control knobs, and some experimental CSS logic. Yes — at the very end, we’ll even do a bit of programming in CSS.</p></header><article><h2>The core idea and a basic implementation</h2><p>Let’s start with the most important part. The entire implementation revolves around a single element:</p><pre><code><div class="progress"></div></code></pre><p>And a single property — <code>background-image</code> with multiple background layers. The core idea is simple:</p><ul><li><p>the top layer is a <strong>radial gradient</strong> that defines the shape of the scale;</p></li><li><p>the bottom layer is a <strong>conic gradient</strong> that controls the fill.</p></li></ul><p>Here’s the basic CSS:</p><pre><code class="css">.progress {
width: 150px;
height: 150px;
background-image:
radial-gradient(
circle,
#222 0% 27%,
transparent 28% 50%,
#222 51%
),
conic-gradient(
#D64E42 0% 60%,
transparent 60%
);
}</code></pre><p>The radial gradient on top creates the “donut” — a scale with a transparent cut-out center. The conic gradient underneath fills a sector of the circle, effectively controlling the progress.</p><p>It’s worth noting that this approach relies on old — one might even say “ancient” — CSS features: multiple backgrounds, radial and conic gradients, and hard color transitions.</p><figure class="full-width"><img
src="/img/blog/progressbar_2026/state-1.jpg"
alt="Basic circular progress bar implementation"
title="Basic circular progress bar implementation"
width="1742"
height="800"
loading="lazy"><div><figcaption>Basic circular progress bar implementation</figcaption></div></figure><p>This is the key technique that forms the foundation of the progress bar. Everything that follows is just customization and layering on top of it.</p><h2>Customization: scale thickness and transparency</h2><p>One of the nicest things about this approach is how easy it is to customize.</p><p><strong>Scale thickness</strong> is controlled by the parameters of the top, radial gradient. We simply tweak the color stop positions:</p><pre><code class="css">radial-gradient(
circle,
#222 0% 30%,
transparent 31% 54%,
#222 55%
)</code></pre><p><strong>Color and transparency of both the scale and the fill</strong> are controlled by the bottom, conic gradient. Change the first color stop to a semi-transparent color — and the fill becomes translucent. Change the second color stop — and the empty part of the scale changes.</p><pre><code class="css">conic-gradient(
rgba(214, 78, 66, 0.6) 0% 60%,
transparent 60%
)</code></pre><p>No extra elements, no masks, no calculations. Just gradient parameters.</p><figure class="full-width"><img
src="/img/blog/progressbar_2026/state-2.jpg"
alt="Adjusting scale thickness and fill transparency"
title="Adjusting scale thickness and fill transparency"
width="1742"
height="800"
loading="lazy"><div><figcaption>Adjusting scale thickness and fill transparency</figcaption></div></figure><h2>Making it look good: texture, borders, and shadows</h2><p>The basic version works, but it looks a bit rough. Let’s add some visual “expensiveness”.</p><p>First, we add a third background layer — a repeating conic gradient that creates subtle radial sections:</p><pre><code class="css">repeating-conic-gradient(
rgba(0, 0, 0, 0.3),
rgba(0, 0, 0, 0.2) 4.5%,
transparent 5%
)</code></pre><p>Second, we make the top radial gradient more complex by adding intermediate colors to create thin borders:</p><pre><code class="css">radial-gradient(
circle,
#222 0% 27%,
#333,
transparent 28% 50%,
#333,
#222 51%
)</code></pre><p>And finally, we slightly round the progress bar itself and add shadows:</p><pre><code class="css">.progress {
border-radius: 10px;
box-shadow: inset 0 0 1px #666, 0 0 30px black;
}</code></pre><p>None of this affects the logic of the component — it’s purely visual.</p><figure class="full-width"><img
src="/img/blog/progressbar_2026/state-4.jpg"
alt="Final styling"
title="Final styling"
width="1742"
height="800"
loading="lazy"><div><figcaption>Final styling</figcaption></div></figure><h2>Control knobs: CSS variables</h2><p>Now let’s make the progress bar practical for real interfaces. To do that, we introduce a CSS variable called <code>--progress</code>.</p><pre><code class="css">.progress {
--progress: 45;
--corner: calc(1% * var(--progress, 0));
background-image:
radial-gradient(
circle,
#222 0% 27%,
#333,
transparent 28% 50%,
#333,
#222 51%
),
conic-gradient(
#D64E42 0% var(--corner),
transparent var(--corner)
);
}</code></pre><p>Now progress is expressed as a clear number from 0 to 100, and CSS automatically converts it into the required angle.</p><p>It’s easy to create multiple instances of the component:</p><pre><code class="xml"><div class="progress" style="--progress: 15"></div>
<div class="progress" style="--progress: 50"></div>
<div class="progress" style="--progress: 90"></div></code></pre><figure class="full-width"><img
src="/img/blog/progressbar_2026/state-5.jpg"
alt="Controlling progress with a CSS variable"
title="Controlling progress with a CSS variable"
width="1742"
height="800"
loading="lazy"><div><figcaption>Controlling progress with a CSS variable</figcaption></div></figure><h2>Experimental CSS features: conditional logic</h2><p>Now let’s take a small peek into the future of CSS. In modern versions of Chrome, you can already use conditional logic via <code>if()</code>.</p><p>For example, you can change the scale color depending on the progress value:</p><pre><code class="css">.progress {
--color: if(
style(--progress <= 33): #D64E42;
style(--progress <= 66): #F5B848;
style(--progress <= 99): #58B473;
else: white;
);
}</code></pre><p>And then use that color in the gradient:</p><pre><code class="css">conic-gradient(
var(--color) 0% var(--corner),
transparent var(--corner)
)</code></pre><p>You can also add a label in the center of the progress bar that changes depending on the progress value. We add a pseudo-element and use <code>if()</code> in the <code>content</code> property to bind the label text to progress ranges. For the label color, we reuse the parent’s <code>--color</code> variable.</p><pre><code class="css">.progress {
display: flex;
justify-content: center;
align-items: center;
}
.progress::before {
content: if(
style(--progress <= 33): "low";
style(--progress <= 66): "med";
style(--progress <= 99): "high";
else: "go!";
);
color: var(--color);
}</code></pre><p>Important: these are experimental features. If you need solid browser support, use JavaScript together with modifier classes instead.</p><figure class="full-width"><img
src="/img/blog/progressbar_2026/state-6.jpg"
alt="Conditional styling based on progress"
title="Conditional styling based on progress"
width="1742"
height="800"
loading="lazy"><div><figcaption>Conditional styling based on progress</figcaption></div></figure><h2>Wow factor: native animation</h2><p>And finally — the fun part. This progress bar works beautifully with native CSS animations.</p><p>First, we register the <code>--progress</code> variable:</p><pre><code class="css">@property --progress {
inherits: true;
initial-value: 0;
syntax: "<number>";
}</code></pre><p>And then animate it:</p><pre><code class="css">.progress {
animation: progress 10s infinite alternate;
}
@keyframes progress {
to {
--progress: 100;
}
}</code></pre><p>During the animation, the following update automatically:</p><ul><li><p>the fill size,</p></li><li><p>the scale color,</p></li><li><p>the center label.</p></li></ul><p>In other words, all styles tied to <code>--progress</code> are recalculated on the fly as the native animation updates the variable.</p><figure class="full-width"><img
src="/img/blog/progressbar_2026/progress-animation.gif"
alt="Progress bar animation"
title="Progress bar animation"
width="836"
height="384"
loading="lazy"><div><figcaption>Progress bar animation</figcaption></div></figure><h2>Conclusion</h2><p>The key technique throughout this article is using multiple backgrounds with radial and conic gradients. It’s simple, well-supported, and extremely flexible.</p><p>Everything else — customization, visual effects, conditional logic, animation — is just an optional layer on top.</p><p>If you need a reliable production-ready component, stick to the basic technique. If you’re in an experimental mood and browser support allows it, try the newer features — they’re already available in recent versions of Chrome.</p><p>The complete code lives in an <a href="https://htmlacademy.org/tutorials/24">interactive, step-by-step demo</a> — you can go through the implementation at your own pace and play with the parameters along the way.</p><p>Hopefully, building progress bars in 2026 will feel a lot more enjoyable.</p></article></section></div></div><footer class="page-footer page-footer--tiny"><div class="page-footer__inner"><p><a href="/docs/cookies">Cookies</a> ∙
<a href="/docs/privacy">Privacy</a> ∙
<a href="/docs/agreement">License Agreement</a> ∙
<a href="/docs/about">About</a> ∙
<a href="/contacts">Contacts</a> ∙
© HTML Academy OÜ, 2019−2026
</p><div class="page-footer__financial"><img src="https://assets.htmlacademy.org/img/visa-white.svg?cs=96e54ec8c587db9d4b1d8d328ffd87c2ebfd9555" alt="VISA" title="VISA" width="35" height="35"><img src="https://assets.htmlacademy.org/img/mastercard-horizontal.v2.svg" alt="Mastercard" title="Mastercard" width="35" height="35"></div></div></footer><div class="modal"><div class="modal__inner"><div class="modal__wrapper js-login hidden"><button class="modal__close icon-close" type="button" title="Close" data-modal="close"></button><h4 class="modal__header">Log in</h4><ul class="modal__social"><li class="modal__social-link modal__social-link--fb"><a href="/login/fb?redirect_url=%2Fblog%2Fprogressbar-2026" rel="nofollow" title="Log in via Facebook"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#facebook"></use></svg></a></li><li class="modal__social-link modal__social-link--google"><a href="/login/google?redirect_url=%2Fblog%2Fprogressbar-2026" rel="nofollow" title="Log in via Google"><svg height="30" width="30" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M457.732 216.625c2.628 14.041 4.063 28.743 4.063 44.098C461.796 380.688 381.481 466 260.204 466c-116.023 0-210-93.977-210-210s93.977-210 210-210c56.704 0 104.077 20.867 140.44 54.73l-59.204 59.197v-.135c-22.046-21.002-50-31.762-81.236-31.762-69.297 0-125.604 58.537-125.604 127.841 0 69.29 56.306 127.968 125.604 127.968 62.87 0 105.653-35.965 114.46-85.312h-114.46v-81.902h197.528z"/></svg></a></li></ul><div class="modal__or"><span>or</span></div><form class="modal__form form" action="/login?redirect_url=%2Fblog%2Fprogressbar-2026" autocomplete="off" method="post" data-submit="o"><input type="hidden" name="csrf_name" value="csrf69aed5740d0d2"><input type="hidden" name="csrf_value" value="d077a9f5071b9ae355091127c6b3c6e7"><div class="form__group"><label class="sr-only" for="login-email">Email</label><input class="field field--text field--full-width" type="email" name="email" placeholder="Email" value="" id="login-email"></div><div class="form__group"><label class="sr-only" for="login-password">Password</label><input class="field field--text field--full-width ym-disable-keys" type="password" name="password" placeholder="Password" id="login-password"></div><input class="button button--full-width" type="submit" data-submit-text="Logging in…" value="Log in"></form><p class="modal__forgot-password"><a href="/recover" data-modal="open" data-value="recover">Forgot your password?</a></p><a class="modal__bottom-link" href="/signup" data-modal="open" data-value="register">Sign up</a></div><div class="modal__wrapper js-register hidden"><button class="modal__close icon-close" type="button" title="Close" data-modal="close"></button><h4 class="modal__header">Sign up</h4><ul class="modal__social"><li class="modal__social-link modal__social-link--fb"><a href="/login/fb?redirect_url=%2Fblog%2Fprogressbar-2026" rel="nofollow" title="Log in via Facebook"><svg aria-hidden="true"><use xlink:href="/img/sprites/general.svg#facebook"></use></svg></a></li><li class="modal__social-link modal__social-link--google"><a href="/login/google?redirect_url=%2Fblog%2Fprogressbar-2026" rel="nofollow" title="Log in via Google"><svg height="30" width="30" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M457.732 216.625c2.628 14.041 4.063 28.743 4.063 44.098C461.796 380.688 381.481 466 260.204 466c-116.023 0-210-93.977-210-210s93.977-210 210-210c56.704 0 104.077 20.867 140.44 54.73l-59.204 59.197v-.135c-22.046-21.002-50-31.762-81.236-31.762-69.297 0-125.604 58.537-125.604 127.841 0 69.29 56.306 127.968 125.604 127.968 62.87 0 105.653-35.965 114.46-85.312h-114.46v-81.902h197.528z"/></svg></a></li></ul><div class="modal__or"><span>or</span></div><form class="modal__form form" action="/signup?redirect_url=%2Fblog%2Fprogressbar-2026" autocomplete="off" method="post"><input type="hidden" name="csrf_name" value="csrf69aed5740d0d2"><input type="hidden" name="csrf_value" value="d077a9f5071b9ae355091127c6b3c6e7"><div class="form__group"><label class="sr-only" for="email">
Email
<span class="required"><span class="sr-only">Required field</span><span class="required__star">*</span></span></label><div class="form__group-fields"><input class="field field--text field--full-width" type="email" name="email" value="" id="email" required placeholder="Email"></div></div><div class="form__group"><label class="sr-only" for="password">
Password
<span class="required"><span class="sr-only">Required field</span><span class="required__star">*</span></span></label><div class="form__group-fields"><input class="field field--text field--full-width" type="password" name="password" value="" id="password" required placeholder="Password"></div></div><div class="form__group"><label class="checkbox"><input class="checkbox__input" type="checkbox" name="agreement" value="1" required><span class="checkbox__text"><span>By signing up, you agree to our <a href="/docs/agreement" target="_blank">License Agreement</a> and <a href="/docs/privacy" target="_blank">Privacy Policy</a>.</span></span></label></div><input class="button button--full-width" type="submit" data-submit-text="Signing up…" value="Sign up"></form><a class="modal__bottom-link" href="/login?redirect_url=%2Fblog%2Fprogressbar-2026" data-modal="open" data-value="login">Log in</a></div><div class="modal__wrapper modal__wrapper--no-btn-bottom js-recover hidden"><button class="modal__close icon-close" type="button" title="Close" data-modal="close"></button><h4 class="modal__header">Restore access</h4><p class="modal__text-accent">Have you forgotten your password or lost access to your profile? Enter your email connected to your profile and we will send you a link to restore access.</p><form class="modal__form form" action="/recover" autocomplete="off" method="post" data-submit="o"><input type="hidden" name="csrf_name" value="csrf69aed5740d0d2"><input type="hidden" name="csrf_value" value="d077a9f5071b9ae355091127c6b3c6e7"><div class="form__group"><label class="sr-only" for="recovery-email">Email</label><input class="field field--text field--full-width" type="email" name="email" placeholder="Email" value="" id="recovery-email"></div><script src='https://www.google.com/recaptcha/api.js'></script><div class="form__group"><div class="g-recaptcha" data-sitekey="6LetCTEqAAAAANROWtPzfC7Rfg9iIRiRt2k2FPn7"></div></div><input class="button button--full-width" type="submit" data-submit-text="Sending…" value="Send"></form><p class="modal__text">Forgot to connect your email to the profile? Email us and we’ll help.</p></div></div></div><div class="banner-bottom" id="cookies_disclaimer_container"><div class="banner-bottom__inner"><p>We are using cookies to gather information which will help you use our website most effectively. You can read about this <a href="/docs/cookies">here</a> or disable this feature if you want. By continuing to browse the site, you agree to our use of cookies.</p><button class="button button--green" type="button" id="cookies_disclaimer_button">Agree</button></div></div><script type="text/javascript">
(function (n) {
var c = document.getElementById('cookies_disclaimer_container');
var b = document.getElementById('cookies_disclaimer_button');
b.onclick = function() {
c.remove();
var d = new Date();
d.setTime(d.getTime() + 60 * 60* 24 * 365 * 1000);
document.cookie = n + "=1; path=/; expires=" + d.toUTCString();
};
})('hidden_cookies_disclaimer');
</script><script async src="https://assets.htmlacademy.org/js/general.v274.js" data-assets="https://assets.htmlacademy.org" data-require="modal,form,nav"></script></body></html>