CSS3 Styled Progress Bar
The quiz results on GoToQuiz are, more or less, progress bars. They visually depict your quiz result as it falls between 0% and 100%, inclusive. How would one go about creating an attractive progress bar entirely in CSS3? I’ll quickly show how I did it.
First, this is what the old bars look like:
It’s a <div> inside a <div> with some simple styling. The inner <div> is set to a reddish background and given a width as a percentage–80%, in the example above. This is a simple bar that communicates what it needs to, whether as a quiz result, poll result, or progress bar, but it’s not visually appealing. In contrast, this is what the new bar looks like:
This is done without any images, which would require additional requests to the server and are best-avoided when CSS is up to the job. And it works in all modern browsers (although IE < 10 will not stripe the unfilled portion of the bar).
First, here is the HTML for the progress bar:
<div class="barOuter"> <div class="barInner" style="width: 80%;"></div> <div class="barLabel">80%</div> </div>
To produce the gray stripes on the barOuter <div> I used linear-layout CSS3 property (original idea from here):
background-color: #ddd; background-size: 20px 20px; background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent); background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent); background-image: -ms-linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent);
As of 2012, it’s still necessary to repeat gradients with these various browser-specific prefixes. The background is set to a solid light gray, #ddd. Then an angled gradient is added that lightens stripes in a tiled 20×20 pixel area. IE < 9 does not support background-size
, so there is no use trying to make these stripes work in those versions. It’s possible to use CSS3Pie to enable linear gradients in IE 9, which does support background-size
, however I have not done so in this example. IE will fall back to a solid light gray background.
For the barInner <div> I use another linear gradient with a fallback to deep red:
background: #d02; background-image: linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); background-image: -moz-linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); background-image: -webkit-linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); background-image: -ms-linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); -pie-background: linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); behavior: url(/css/PIE.htc);
The linear gradient produces a shiny red progress bar. This time, I use CSS3Pie to make the gradient work in older versions of IE. The end of the red bar needs some sort of cap on it, so I added a 1px border and rounded the corners slightly:
border-right: 1px solid #c01; border-radius: 0 3px 3px 0;
This requires also setting a max-width
to be one pixel less than the width of barOuter, to handle the 100% case where the barInner’s border-right
will extend outside it’s container.
Finally, for the barLabel <div> holding percent indicator to the right of the bar, I set barOuter’s position
to “relative” and styled barLabel:
position: absolute; top: 0; right: -32px; color: #888; font-size: 12px;
So to wrap this up, here is the full CSS I’m using to create this no-image progress bar:
.barOuter { width: 220px; height: 15px; border: 1px solid #000; position: relative; background-color: #ddd; background-size: 20px 20px; background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent); background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent); background-image: -ms-linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, .3) 75%, transparent 75%, transparent); } .barInner { width: 50%; max-width: 219px; height:15px; background:#d02; background-image: linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); background-image: -moz-linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); background-image: -webkit-linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); background-image: -ms-linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); -pie-background: linear-gradient(bottom, rgb(221,0,33) 40%, rgb(255,60,86) 74%, rgb(221,0,33) 100%); border-right: 1px solid #c01; border-radius: 0 3px 3px 0; behavior: url(/css/PIE.htc); } .barLabel { position: absolute; top: 0; right: -32px; color: #888; font-size: 12px; }
Feel free to use this if you like it! To create your own gradients, try this CSS3 gradient generator or the ColorZilla generator. In order to set the amount of progress on the bar, just do what I’ve done and add an inline style to set the width as a percentage. You could do this dynamically using javascript as well as server-side.