I often think about ways to visualize data using pure css. A while ago I wrote an article about pure css bar graphs, but what puzzled me lately was a solution for doing line graphs using nothing but css.
Many will not see much sense in this technique, specially when we have so much JavaScript (or even Flash) based line graph scripts.
My intention was not only to enable data visualization to people that don't feel comfortable with using various scripting languages but also to demonstrate the power of css and present a way of using css a bit differently. If you are not a fan of line graphs and data visualization in general, you may still read this article and think of it as css experiment and perhaps learn a thing or two about css sprites and positioning.

Take a look at the demo | Download pure css line graph
So, the line graphs. What are they good for? I will mention just one reason, and leave other advantages or downsides for a debate: users scan your page, they don't read every word and number you write. Line graphs will deliver information much faster then a table filled with numbers.
How does this thing work?
This technique takes structured html, replace text with images and by using css sprites and absolute positioning it creates a simulation of a line graph. As in my pure css bar graph example, I am using definition list element (DL). DL element is styled to represents the coordinate system where we place items. For that reason, empty DL element must look something like this:

The dimensions used in the background graphic define the dimensions we're using for child elements in order for everything to fit well. In this case, each item will represent one day. For items we are using DD elements with nested spans. We are formatting and placing the DL's so they form linear bars across the chart.

The styling of nested spans are what makes this css line graph possible.
The Graph Principle
The concept may seem a bit advanced but if you look carefully into it you'll see that the logic is quite simple. In my example item's (DD's) dimensions are 33px in width and 330px in height. Each one of those items represent one "line movement" from one point to the other. We're using one image, css sprite, that has all possible options displayed graphically. As you can see on the image, there are lines that go up (rising values) and lines that go down (falling values). Setting the nested SPAN's background-position property to certain values we are choosing one of the "line" options.

But that is not all. We also have to set the "starting position" for each item as the lines always start at different values. That is done by setting top value for each SPAN

For this reason, each SPAN has 2 (actually some of them have 3 - read below) class names attached: one that defines the SPAN's "starting point" (SPAN's top value) and other that represent the rising or falling "line move" (SPAN's background position value).
Starting point is based on previous value. You have to continue with next item where the previous item "stopped".
Usage
If you look at the css file I created 4 groups of class names: 2 for setting starting position and 2 for defining the "move".
I divided starting position class name groups based on the situation where we are increasing values (using line-up, the upper part of the image) or decreasing values (lower part of the image).
I named those class names .pi1 or .pd1 ("p"osition "i"ncreasing 1) or ("p"osition "d"ecreasing 1) By looking at the css file you'll notice that .pi group has negative top values which shits sprite image up while .pd group has positive top values (shifts image down).
Actual line movements are defined with class names like .i1 or .d1 i.e. this class name .i24 increases the value by 24 points.
Choosing a proper position (".p" class) is fairly easy: you have to take a look at previous item which can be something like:
<dd><span class="pi1 i10"><em>33</em></span></dd>
We have pi1 and i10. It means that we have item starting at point 1 and is increased by 10 points. That makes point 11 our new starting point. If our next move is increase we are choosing .pi11 but if we're decreasing we choose .pd11!
If this sound to complex (or if I presented it poorly) just remember that when choosing both class name you have to be careful that you don't mix i's and d's
This is good:
<dd><span class="pi1 i10"><em>33</em></span></dd>
and this isn't
<dd><span class="pi1 d10"><em>33</em></span></dd>
Now, let me explain what's with the EM element. Items are placed next to each other without overlapping so the line connections are not smooth. I am using EMs to place dots over these connecting points to cover them. EMs are absolutely positioned to cover the PREVIOUS line connection area. There is one default css definition for EMs although the decreasing items need additional class name .d - that's why I mentioned that some of the SPANS has 3 class names. The decreasing item is marked up like this:
<dd><span class="pd10 d d1"><em>46</em></span></dd>
Please note that class names are written in "points" or "steps" not the actual values. In my case each "point" represents 3,3%
As mentioned, I am not trying to replace advanced JS or flash techniques with this. I am offering an alternative way to visualize data and perhaps different view of CSS usage. This method has it's limitations, but it's pure CSS!
Designer, developer and a passionate standardista. Long time web professional with huge experience in all types of front-end work. Founder of Css Globe and creator of
Bennobo on 11 Feb, 2009 wrote:
Cerebral on 11 Feb, 2009 wrote:
webdawson on 11 Feb, 2009 wrote:
w0w on 11 Feb, 2009 wrote:
vladocar on 11 Feb, 2009 wrote:
Dado on 11 Feb, 2009 wrote:
Ollie on 11 Feb, 2009 wrote:
Pliggs on 11 Feb, 2009 wrote:
Umut Muhaddisoglu on 11 Feb, 2009 wrote:
Aiya101 on 11 Feb, 2009 wrote:
Chris M on 11 Feb, 2009 wrote:
Jonathan Snook on 11 Feb, 2009 wrote:
Soh on 11 Feb, 2009 wrote:
James Howard on 11 Feb, 2009 wrote:
That'll teach them! :-)
WebmasterNeal on 11 Feb, 2009 wrote:
I'd also like to see something integrated into this that stylizes the x & y axis. and the zebra stripes.
cssProdigy on 11 Feb, 2009 wrote:
cssglobe on 11 Feb, 2009 wrote:
cssglobe on 11 Feb, 2009 wrote:
cssglobe on 11 Feb, 2009 wrote:
daniel on 11 Feb, 2009 wrote:
cssglobe on 11 Feb, 2009 wrote:
Dean on 11 Feb, 2009 wrote:
But wouldn't it be more semantically correct to have the underlying code as a table of data rows/columns than as a definition list? I wonder how much that would complicate things?
w0w on 12 Feb, 2009 wrote:
Unsure? Try it
inner thoughts on 12 Feb, 2009 wrote:
I think that tricks/hacks like this only show how terrible an HTML is and that even CSS cannot remedy the fundamental flaw of the whole HTML concept! Even (W3C) standards cannot fix it! I see people everywhere thinkering hacks, tricks and other clever ways to get something so obvious, like in this example - simple data visualisation, in HTML. If only all that energy and "brain power" is used to design and develop a completely new replacement for HTML (not based on HTML/XML and other similar crap!) - where all the mistakes in design from HTML would be gone!
Just my .02$
cssglobe on 12 Feb, 2009 wrote:
benburleson on 12 Feb, 2009 wrote:
@cssglobe - I admire thinking outside the box, especially when it comes to using css sprites. But I really think this is the wrong tool for the job. Creating the data HTML is far too complicated. You could use js to simplify the creation of the data HTML. But then if you're going to use js, why not use js to do the graphing?
Check out my css sprite project hosted at google code: http://code.google.com/p/sprhide/ I think it has some potential, and it would be nice to have some others with experience in the subject take a look at it. (And hopefully contribute!)
Timothy on 12 Feb, 2009 wrote:
Creamy CSS on 12 Feb, 2009 wrote:
Eli on 12 Feb, 2009 wrote:
Small correction:
"This method has it's limitations, but it's pure CSS!"
"It's" means "it is". It should be "This method has its limitations, but it's pure CSS!"
Márton Sári on 12 Feb, 2009 wrote:
I would say it's a pure misleading title. It's a half-css method.
CSS sprites have their own areas to be used in, this is definitely not in that.
cssglobe on 12 Feb, 2009 wrote:
In a broader sense, when saying that something is "Pure CSS" the fact that I'm trying to emphasize is that i haven't used any scripting languages. That was actually my main reason for calling this pure css solution.
Athos on 12 Feb, 2009 wrote:
http://stfw.hu/demos/css_line_graphs/
It works in most of the browsers.
(It's not a general solution to draw lines, and it seems to be impossible to draw multiple lines on the same graph with my code.)
Simon Sigurdhsson on 12 Feb, 2009 wrote:
Márton Sári on 13 Feb, 2009 wrote:
Actually it doesn't even have a real relevance of the images being in a sprite, it could be all in seperate files. The relevance of using CSS sprites here is just the same as in using sprites generally: performance. That's why it's misleading. The sprite idea doesn't add anything to the concept.
So the question is, that without sprites (separate image files) would you still call it a "pure CSS solution", and not rather a "pure HTML solution"?
Márton Sári on 13 Feb, 2009 wrote:
inner thoughts on 13 Feb, 2009 wrote:
Wow! Isn't using borders and overlapping elements to get thinner lines actually, what you call, "other trickery"? :)
At least cssglobe's solution is nice looking and usable. That can't be said for your "trickery"!
inner thoughts on 13 Feb, 2009 wrote:
@benburleson: Why? People should exchange thoughts and discuss them. There is nothing wrong wanting new and better things to happen. Also, you imply that I have no right to say that something is broken/wrong/bad unless I have a solution or alternative? Interesting. Have you ever said for anything (product, tv show, movie) "that is bad" and all that without an alternative?
I still stand at my view that HTML (with related stuff) is bad, very very broken and it should be abandoned and replaced! Today (X)HTML/CSS/JS/.. is totally FUBAR!
Márton Sári on 13 Feb, 2009 wrote:
It depends on what you wanna do, and what you mean by nice and usable.
The border-trick has its own technological beauty (which I expect from a title like "pure CSS solution"), you can scale the graph in both dimensions, you can scale the distance between two spots, you can make precise graphs, you can control the color, and probably you can make it better looking that it is now on Athos' site (e.g. you can put png dot images at the breaking points hiding that glitch). And is probably standard-proof.
Unfortunately it's not anti-aliased in IE and Opera.
Márton Sári on 13 Feb, 2009 wrote:
Exdizajn on 13 Feb, 2009 wrote:
inner thoughts on 13 Feb, 2009 wrote:
HTML could hardly be called an technology. Take SGML, cripple it, give it a new name and that's a technology? With all due respect to Mr. Berners-Lee, HTML was good way back then and it was fun, but now it's just pain in the ass. That's why we need something new and hopefully better with full and native support (among other things) for vector graphics (if somebody wants to mention SVG just don't! ;), audio, video, unified server and client side programming, real bidirectional persistent communication channels, real separation of content and presentation, better indexing and data knowledge and not to mention pixel perfect rendering. There is much more, but this is just place for comments so I'll stop.
My apology to cssglobe for all disturbance, won't do it anymore. :)
Athos on 13 Feb, 2009 wrote:
When I write trickery, I mean cheating (using other than CSS or HTML).
You say: "we need something new and hopefully better with full and native support (among other things) for vector graphics (if somebody wants to mention SVG just don't! ;), audio, video, unified server and client side programming, real bidirectional persistent communication channels, real separation of content and presentation, better indexing and data knowledge and not to mention pixel perfect rendering."
I don't think this will be reality in less than 10 years...
Márton Sári on 14 Feb, 2009 wrote:
So you have problems with only HTML? SGML is OK? XHTML is OK? What about HTML 5? You said: "HTML with related stuff". So you're blaming the whole technology. Then what's the point in questioning a term i'm using obviously to refer to that whatever technology you're speaking about, and naming it by it's probably strongest meme as an adjunct (HTML). Actually i'm getting lost what precisely do you have problems with. Maybe it's the whole world. Or just the internet. Maybe you should go cutting trees.
You still haven't given a piece of thought of alternatives. Why one shouldn't mention SVG??? Audio, video -- what's with that??? You can make it on any level (with version 5 even on HTML) with any tool you want. "unified server and client side programming" WTF???, you don't like free market and competition, do you? You're pushing the same bullshit as people who are crying for a 'one and only' browser engine, so they don't have to bother with compatibility issues. Poor guys, don't notice that behind your absurd ideas it's only the simple fact is hiding that you feel really uncomfortable with you job...
Why wouldn't you wish then a one and only OS, a one and only car brand, a one and only party... What a huge amount of compatibility issues and debates we could get rid of!
Martin S. on 17 Feb, 2009 wrote:
inner thoughts on 17 Feb, 2009 wrote:
And that is all fault of a bad HTML specification!
Saying that I want one OS, one brand or whatever just because I feel and know that current HTML is (too) broken is just insane!
FYI, when I say "unified server and client side programming" I mostly refer to ability for my code (compiled/uncompiled) to seamlessly "travel" between server and client side, not just data - like it is now. Like I said, I cannot be elaborate in this comment area, and for sure I don't think that I alone can make an alternative - this is multidisciplinary task where all interested sides should contribute - from designers, content writers, users, programmers, sysadmins, etc...
Once again, my apology to cssglobe for littering his site with something unrelated . This is final EOD from me on this subject!
Athos on 17 Feb, 2009 wrote:
IMHO that is all fault of a company doing it's "best" to win the browser-wars back in the '90s. And they are still doing the same - see what Microsoft is planning about standards-compliant mode in IE8. Again.
Fadel on 17 Feb, 2009 wrote:
Paul Armstrong on 18 Feb, 2009 wrote:
It would be much simpler, semantically correct, usable, and accessible to have used a straight HTML table, hidden it off screen with a negative absolute position, and replaced it with an image via CSS. After all, a line graph is tabular data and deserves to be treated as such.
Zachary Johnson on 18 Feb, 2009 wrote:
When it comes to actually using a line chart on a website, I am either going to want to download/hotlink a rendered image of the chart OR I am going to want a table of the data in the chart.
In this case my choices are taking a screen shot myself or grabbing the weird definition list.
Lorne Pike on 22 Feb, 2009 wrote:
Web Design Creatives on 24 Feb, 2009 wrote:
Thanks!
vishal on 24 Mar, 2009 wrote:
Sean Olson on 1 Apr, 2009 wrote:
It really does look very nice, and the thought that goes into your CSS projects is always noticeable. The one question I have is if this can plot data from MySQL... Would you just place your aliases/queries between the em tags like so? <em>'.$rows.'</em>
I'm developing a chart for tracking real-time statistics for our company's intranet site, and we have a gorgeous bar graph plotting data from MySQL... I've been up to this point completely unsuccessful getting the same functionality out of a line graph (which is what management wants).
Any insight you can offer is appreciated.
@inner thoughts:
Show me another language that can render graphical elements better than CSS using syntax that is JUST AS EASY and I'll be happy to try it. CSS is very powerful stuff, and is only becoming more so with time. You're entitled to your opinion that HTML and everything related to it sucks, but I have to agree with others here-- Yes, in this case the burden is on YOU to come up with a better alternative. All of our web standards are broken? Fix them or shut up and learn to deal with it like the rest of us.
PJ on 11 Apr, 2009 wrote:
cssrain on 13 Apr, 2009 wrote:
Hans Lee on 20 Apr, 2009 wrote:
http://www.pagecolumn.com/webparts/html_image.htm
Of course, the technique could be used in drawing pure css line graph. It's possible to draw multiple lines on the same graph.
Gerd on 18 Jun, 2009 wrote:
thuc pham minh on 18 Jun, 2009 wrote:
Lucy on 23 Jun, 2009 wrote:
jay on 26 Jun, 2009 wrote:
"top values which shits sprite image up".
Now if my top values actually did shit my sprite images up, id probably be quite amused. lol.
ok onward with the debates