By Tim King · Updated
Progress Bar Generator
CSS Progress Bar Online, Linear, Striped, Animated and Circular
OneTask is free, with no sign-up, and built by one person.
If this tool saved you time, a coffee helps keep new ones coming.
How the Progress Bar Generator works
This progress bar generator builds linear and circular bars in CSS. Drag the value slider, pick a style and colours and the bar redraws as you go. Solid gives a plain fill, Striped adds the diagonal candy-stripe pattern, Striped animated makes the stripes crawl so the bar reads as busy, and Circular ring draws the same percentage as a conic-gradient ring with the number in the middle. The code box holds the HTML and the CSS together, with the percentage stored in a --value custom property so your script only has to change one number to move the bar.
Progress bar generator: linear and circular
A progress bar is two boxes: a track with overflow: hidden and a fill whose width is the percentage. Everything else is decoration. The generated CSS keeps the percentage in a custom property on the outer element, so updating it from JavaScript is bar.style.setProperty('--value', '80%') and the transition: width handles the movement. Setting aria-valuenow at the same time keeps screen readers in step; the markup already carries role="progressbar" and the min and max.
Stripes. The striped look is a repeating 45-degree linear-gradient of translucent white over the fill colour, sized to twice the bar's height so the stripes are square. Because it is a translucent overlay rather than a second colour, it works on any fill colour without picking a matching shade. The animation just slides the background position by one tile width per second, which is why it loops without a visible jump.
Circular ring. A conic-gradient fills the ring from twelve o'clock to the percentage and the rest in the track colour; a white pseudo-element covers the middle to turn the disc into a ring. Change the pseudo-element background to match your page. Because the gradient stops at a hard edge there is no anti-aliasing seam in current browsers, and the value can be animated by transitioning the --value property if it is registered with @property { syntax: '<number>' }.
When to use the native element. <progress value="65" max="100"> is accessible for free and needs no ARIA, but styling it consistently across browsers takes vendor pseudo-elements (::-webkit-progress-value, ::-moz-progress-bar) and stripes and rings are impractical. The div-based version here is the usual compromise: it styles anywhere and carries the same semantics through role="progressbar".
Indeterminate state. For a bar with no known percentage, leave the fill at about 30% width and animate its position from left to right, or use the animated stripes at 100% width. Remove aria-valuenow in that state so assistive tech announces it as indeterminate.
Thickness and label. A label inside the bar needs the bar to be at least about 16px tall to be legible; the generator scales the font to 60% of the thickness. For thin bars put the label above, where the meta row also gives you somewhere for a title.
FAQ
How do I change the progress bar value with JavaScript?
Set the custom property and the ARIA attribute together: el.style.setProperty('--value', pct + '%') and el.setAttribute('aria-valuenow', pct). The width transition in the CSS animates the change. For the ring, the property is a plain number rather than a percentage.
How do I make the stripes move?
Choose Striped, animated. The CSS adds a @keyframes rule that shifts the background-position by one stripe tile each second on a linear loop. Slow it down by increasing the 1s duration, or pause it with animation-play-state: paused when the task stalls.
Can I make a circular progress bar with only CSS?
Yes. The Circular ring style uses conic-gradient for the arc and a pseudo-element to hollow out the centre, with no SVG. It is supported in every current browser. If you need a rounded end cap on the arc or a gradient along the arc, an SVG circle with stroke-dasharray is the better tool.
Is the generated progress bar accessible?
The markup includes role="progressbar", aria-valuemin, aria-valuemax, aria-valuenow and an aria-label. Keep aria-valuenow updated as the value changes, and give the bar a more specific label such as "Upload progress" in your own code.
Should I use the HTML progress element instead?
If you only need a plain bar and can live with the browser's default look, yes; it is simpler and accessible by default. Use the generated version when the design calls for stripes, animation, a ring, or a look that has to match across browsers.
See also: all UI Components tools, Layout & Spacing, Shadows & Motion, Shapes & SVG, Forms & Inputs, Colour.
Related tools
Form Progress Bar
Step indicators and progress bars for multi-step forms and checkouts.
Keyframe Animator
Build and preview a CSS @keyframes animation from three stops.
Border Radius Generator
Per-corner border-radius with shorthand and longhand output.
Gradient Maker
Linear, radial and conic CSS gradients with live preview.
Range Slider Builder
Custom-styled range input with filled track and live value.