Displaying percentages

David Stone | The Design, The Development, Amigo | Tuesday, August 15th, 2006

In Amigo we’ve got percentage bars! This was the image that Jason came up with:

In turning this part of the design into something flexible on the website I saw two options; clever CSS, or ‘Lots of Images’. I decided that ‘Lots of Images’ was a bad idea:

  • If they were generated in PHP you’ve got that extra overhead
  • For each percentage bar you’d need to download another image - extra bandwidth & slower for the user
  • Could get difficult for a designer to update (and, it’s an image after all)

… so clever CSS it is.

The Code

Okay, it’s not really that clever, it’s CSS not rocket science. It does however mean that no matter how many percentage bar’s will be displayed on the page the user will only need to wait for two images to be downloaded. I think it’s a nice solution that you might be interested in. Here’s the XHTML & CSS:

<img src="/images/percentImage.png" alt="9.5%" class="percentImage" style="background-position: -110.315px 0pt;" />

img.percentImage {
 background: white url(/images/percentImage_back.png) top left no-repeat;
 padding: 0;
 margin: 5px 0 0 0;
 background-position: 1px 0;
}

If you understand XHTML/CSS, you’ll see there’s two images involved. The first image is the border for the widget, inside of the border it’s transparent:

percentImage.png

The second image is the bar’s color, split into two halves. The first 50% is the "full" color, the remaining 50% being the "empty" color:

percentImage_back.png

What’s it doing

Notice, the alt attribute of the img tag (I’m with you Roger) is the percentage that the image represents for screen readers etc. - this is important information and we want to make sure it’s accessible!

The width of the img tag will always be the same regardless of the width of the background image we set in the CSS, knowing this we can position the background to the top left (as default) and set it not to repeat. The background-position is set to 1px so that the image fits within the border in the first image, however, we could make the image a little large if we wanted to.

The inline style handles what pecentage we want to display in the box by changing the position of the background-image. In our case a PHP script handles all the math for us (which is why it’s a little too exact, however I believe browsers will round that to the nearest pixel).

I’ll throw a few other thoughts out there for anyone interested in using this method:

  • When inline styles become redundant in the XHTML standard
  • Page Zoom (IE7) - how would that change the display of this widget

45 Comments »

  1. Pretty nifty css!

    Might be good to mention how you are using this widget. On a file upload? Is the browser doing an auto-refresh every X seconds? Is it updated with AJAX? i.e. Will this image flicker(if reloaded) as it is loaded on each reload.

    Is it to track the status of an order, or for graphing percentage of hits on an ad-click.

    It looks great, but what’s it for?

    :)

    Comment by Jeff Ward — August 15, 2006 @ 11:47 pm

  2. Such a great example for designers and developers new to CSS. Often times, the solution requires one to look at objects in a more dynamic way. For instance, we immediately think of the percentage bar expanding. But from a practical CSS standpoint, we have to look at it as this background image being repositioned.

    I did a pie chart for a client in much the same way. I created a large image with 5% incremental pie charts spanned evenly and horizontally. So, I had 20 charts to display 100 different percentage possibilities. If a value was something like 35%, the chart background-position would be adjusted to “-7 x chartWidth.” It worked out nicely.

    Comment by Colin — August 16, 2006 @ 12:24 am

  3. I don’t know about IE7’s Page Zoom, but the percentage bar zooms perfectly in Opera. This would be because Opera zooms both images and also the background-position value. (CSS px does not necessarily refer to absolute pixels on the screen, so it scales up and down okay.)

    Comment by Nathan Jones — August 16, 2006 @ 12:28 am

  4. Yes, it does zoom nicely in Opera.

    Here’s my pie chart example.

    http://petewilliamsagency.com/css/examples/pie/

    Comment by Colin — August 16, 2006 @ 12:30 am

  5. Excellent, elegant solution.

    Comment by Matthew Pennell — August 16, 2006 @ 8:05 am

  6. I love these methods of replacing arcane image heavy data visualisation methods with a few lines of clean, valid code.

    Those pies are nothing short of beautiful, Colin, as beautiful as pies can be.

    Excellent work guys!

    Comment by Ben — August 16, 2006 @ 8:25 am

  7. “Page Zoom (IE7) - how would that change the display of this widget”

    I’ve just checked it out, it won’t change at all in IE7 (besides getting bigger…)

    Comment by Gabriel — August 16, 2006 @ 8:27 am

  8. Oh um, forgot to mention: Of course I didn’t just load the above pic (as it is a static example), but used the code here in a local example…

    Comment by Gabriel — August 16, 2006 @ 8:30 am

  9. Great charting examples guys… both the bar and pie examples. Elegant and simple… very impressive.

    Comment by Paul Livingstone — August 16, 2006 @ 8:37 am

  10. Just curious - how will you make a 100% chart?

    When: “background-position: 1px 0pt;” there is small white space to the right of a bar,
    with: “background-position: 2px 0pt;” white space is visible on the left side

    You can clearly see it in Opera with huge page zoom (like 260%)

    Comment by Tomasz Tybulewicz — August 16, 2006 @ 10:22 am

  11. […] I’ve written another article over at Bare Naked App, this time about Displaying Percentages in XHTML/CSS, accessible and everything. […]

    Pingback by BuiltByDave.co.uk » Displaying percentages, by David Stone — August 16, 2006 @ 11:16 am

  12. Wow!

    Really good!

    Thanks for sharing!

    Comment by Ramon Bispo — August 16, 2006 @ 1:14 pm

  13. Not sure about the “lot’s of images” thing i.e “for each percentage bar you’d need to download another image..”.

    Surely, you’d create one image 1px wide and stretch it using css or html width attribute?

    Comment by Jeremy Jarvis — August 16, 2006 @ 1:39 pm

  14. Jeremy, if I understand correctly, your talking about another solution (one that I’ve used previously) however I was going for nice mark up this time. The way your talking about, you’d probably have two images and do something like:

    <img src=”bar_full.jpg” alt=”50%” width=”50px” /><img src=”bar_empty.jpg” alt=” ” width=”50px” />

    I personally think it’s neater and more semantic to have one image tag for the image.

    Another point is if we wanted to redesign the bar, changing the ‘fill’ we can easily, if we’re stretching images we’ve limited ourself to images that stretch well.

    Comment by David Stone — August 16, 2006 @ 2:03 pm

  15. Nice work Dave.
    Why don’t you round() to the nearest full px in php, then you don’t have to believe it will be displayed correctly, but you’ll know.

    Comment by Matthias — August 16, 2006 @ 4:00 pm

  16. Hi Matthias,

    I was going to printf() it as a integer, I just hadn’t got round to it yet - it’s not an important change as it won’t affect functionality. Mind you I’d be interested if being more exact affects Page Zoom.

    Comment by David Stone — August 16, 2006 @ 4:18 pm

  17. Hi Dave -
    I was more thinking that I’d use the border image you’ve made as the background to the div, which contains stretching image. Granted, this would only work with an image that repeats horizontally.

    Thanks for sharing,anyway :)

    Comment by Jeremy Jarvis — August 16, 2006 @ 4:45 pm

  18. Maybe stupid question, but why not just make the white of the background light blue so you only need a dark blue image half the size (I know it doesn’t really matters size-wise, I just wondered if you considered it).
    Benefit of your method is that changing colors is a bit easier.

    Comment by Tim vdc — August 16, 2006 @ 6:33 pm

  19. […]  A very nice example on how to build a percentage bar with two images and css! Comments » […]

    Pingback by JDev :: CSS Shreadsheet Style :: August :: 2006 — August 16, 2006 @ 8:12 pm

  20. You are forgetting the CSS-less users. They will see an empty bar and alt won’t help them.

    Comment by Hunox — August 16, 2006 @ 10:16 pm

  21. “You are forgetting the CSS-less users. They will see an empty bar and alt won’t help them.”

    Come on, now.. Of course there’s going to be a textual representation of the percentage bar. It’s not like they expect people to know an exact percentage just by looking at a bar.

    Comment by Colin — August 17, 2006 @ 12:52 am

  22. […] Bare Naked App » Blog Archive » Displaying percentages (tags: ajax css webdesign ui) […]

    Pingback by Breyten’s Dev Blog » Blog Archive » links for 2006-08-17 — August 17, 2006 @ 11:50 am

  23. Great. Add in a bit of javascript and we can have progress indicators! Anyone care to give it a go?

    Comment by Jon — August 17, 2006 @ 12:16 pm

  24. Jon,

    Sounds like your looking for this: http://php5.bluga.net/progressDemo/demo.php

    Dave

    Comment by David Stone — August 17, 2006 @ 12:30 pm

  25. I was thinking of something a bit simpler, like a timer.

    Comment by Jon — August 17, 2006 @ 12:40 pm

  26. Thanks, can’t wait to use it.

    Comment by Blake P — August 17, 2006 @ 5:58 pm

  27. […] Displaying percentages display a progress bar with css (tags: css code html) […]

    Pingback by nonimage » Blog Archive » links for 2006-08-17 — August 17, 2006 @ 10:31 pm

  28. What math are you using? care to post your formula?

    Comment by Matt — August 18, 2006 @ 1:59 am

  29. Percentages? That would be x/y*100, where x = amount had, and y = amount possible.

    Comment by Colin — August 18, 2006 @ 6:30 am

  30. not the percentage :). Im talking about the negative background-position. at 9.5%, it is -110px? I dont see the coorelation.

    Comment by Matt — August 18, 2006 @ 1:39 pm

  31. Matt,
    I was wondering the same thing - wondering the correlation between the two.

    This is a nice technique…

    Comment by Nate K — August 18, 2006 @ 6:51 pm

  32. […] Bare Naked App » Blog Archive » Displaying percentages (tags: CSS percent percentages webdesign bar design) […]

    Pingback by dEOS » links for 2006-08-18 — August 18, 2006 @ 11:20 pm

  33. For those needing help with the maths:

    If the image bar image is 250px wide and is half/half colored/blank then to represent 37%:

    (125/100)*(100-37) = 78.75

    In words; image width divided by 100 to give is width of one percent multiplied by 100 minus the percentage we want to represent.

    From that you should be able to figure out the details yourself.

    One suggestion I would make is adding a title attribute so that users can mouse over the bar to get the percentage as a number appearing in a tooltip; it’s all very well having the alt text there but being an able user I don’t want to have to look at source code to find out the exact percentage being represented.

    If you are using this alongside a text representation of the percentage then alt text is not required. A screen reader would read out the text representation the the alt text from the visual representation which could be confusing.

    Indeed on this page the bar given as an example lacks a title attribute and the alt attribute is blank which is quite bad considering the way the sentence above is worded in such a way as to make the image a required part of the content.

    Comment by Jon (Different to one above) — August 20, 2006 @ 3:50 pm

  34. you could use the technique in this article:

    http://www.jimroos.com/2006/08/playing-with-full-deck.html

    and just send down *ONE* image. just stack the two images and use the positioning the same way with offsets.

    just a thought. i love the idea of grouping the images.

    Comment by roy ashbrook — August 20, 2006 @ 11:39 pm

  35. […] Displaying percentages: comment créer une barre de progression en CSS […]

    Pingback by Weblogger.ch » Blog Archive » Liens — August 22, 2006 @ 7:24 am

  36. RE: Jon
    Thanks for posting this. I forgot to check back and had figured out the same solution to get the proper percentage in the bar.

    Comment by Nate K — August 24, 2006 @ 3:26 pm

  37. Nice script!

    One minor glitch though (don’t know if it’s a bug in the script), when the bar should be at 100 %, there’s like 1 px to the right left white. I tried fixing this by changing some values in the CSS style but nonetheless. Anybody care to give feedback on that?

    Thanks,
    FireSt0rm

    Comment by FireSt0rm — September 11, 2006 @ 5:59 pm

  38. Very nice job !

    Simple, clean, valid, usefull.

    Great job,

    Thank you

    Comment by francois — October 3, 2006 @ 7:04 am

  39. […] achja das «bare naked» in der tabbar führt dahin und das «latex magazine» erklärt sich aus den folgenden Tabs […]

    Pingback by nur Bahnhof » Firefox minimal — December 23, 2006 @ 11:02 am

  40. […] 37. Displaying Percentages with CSS […]

    Pingback by 53 CSS-Techniques You Couldn’t Live Without | Smashing Magazine — January 18, 2007 @ 11:12 pm

  41. Not to be nit picky, but isn’t 9.5% -111.315px?

    Comment by Sean — January 19, 2007 @ 12:33 pm

  42. Semantically incorrect. A blank image here is not a valid content image. Just take any page using this technique with CSS disabled and you’ll see why it’s wrong.

    Use the same technique but with something like 75% or whatever is appropriate, using background images only…and your favorite image replacement technique to remove the text.

    Comment by vicmackey — January 21, 2007 @ 8:16 pm

  43. tags got stripped in my previous page. <div><p>75%</p></div>

    Comment by vicmackey — January 21, 2007 @ 8:18 pm

  44. Very good css code !

    Comment by hosting grenoble — January 24, 2007 @ 10:38 pm

  45. Very cool tip! ;) thankyou very much, maybe useful!

    Comment by loige — January 26, 2007 @ 12:26 pm

RSS feed for comments on this post. TrackBack URI

Leave a comment

Powered by WordPress | Theme by Roy Tanck