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!
Bennobo 11 Feb, 2009
Cerebral 11 Feb, 2009
webdawson 11 Feb, 2009
w0w 11 Feb, 2009
vladocar 11 Feb, 2009
Dado 11 Feb, 2009
Ollie 11 Feb, 2009
Pliggs 11 Feb, 2009
Umut Muhaddisoglu 11 Feb, 2009
Aiya101 11 Feb, 2009
Chris M 11 Feb, 2009
Jonathan Snook 11 Feb, 2009
Soh 11 Feb, 2009
James Howard 11 Feb, 2009
That'll teach them! :-)
WebmasterNeal 11 Feb, 2009
I'd also like to see something integrated into this that stylizes the x & y axis. and the zebra stripes.
cssProdigy 11 Feb, 2009
cssglobe 11 Feb, 2009
cssglobe 11 Feb, 2009
cssglobe 11 Feb, 2009
daniel 11 Feb, 2009
cssglobe 11 Feb, 2009
Dean 11 Feb, 2009
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 12 Feb, 2009
Unsure? Try it
inner thoughts 12 Feb, 2009
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 12 Feb, 2009
benburleson 12 Feb, 2009
@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 12 Feb, 2009
Creamy CSS 12 Feb, 2009
Eli 12 Feb, 2009
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 12 Feb, 2009
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 12 Feb, 2009
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 12 Feb, 2009
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 12 Feb, 2009
Márton Sári 13 Feb, 2009
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 13 Feb, 2009
inner thoughts 13 Feb, 2009
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 13 Feb, 2009
@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 13 Feb, 2009
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 13 Feb, 2009
Exdizajn 13 Feb, 2009
inner thoughts 13 Feb, 2009
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 13 Feb, 2009
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 14 Feb, 2009
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. 17 Feb, 2009
inner thoughts 17 Feb, 2009
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 17 Feb, 2009
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 17 Feb, 2009
Paul Armstrong 18 Feb, 2009
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 18 Feb, 2009
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 22 Feb, 2009
Web Design Creatives 24 Feb, 2009
Thanks!
vishal 24 Mar, 2009
Sean Olson 1 Apr, 2009
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 11 Apr, 2009
cssrain 13 Apr, 2009
Hans Lee 20 Apr, 2009
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 18 Jun, 2009
thuc pham minh 18 Jun, 2009
Lucy 23 Jun, 2009
jay 26 Jun, 2009
"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