This is extreme CSS. An experiment to recreate an image file using nothing but CSS. And then manipulate the image. Madness? Certainly. Practical? Doubtful. Amazing? I hope so. I leave you to make up your own mind. I've made CSS do things it's not meant to, like a lone scientist, going into largely uncharted territory, pushing the boundaries, leaving behind common sense and practicality in the name of novelty, progress, excitement, aiming to inspire and educate others to use CSS in ways they never thought possible.

So what gives? There's an image on screen! But no image file is used. Instead each pixel is built with CSS. But it would be crazy to do an image pixel by pixel. Instead I've made use of borders. These give me three pixels at a time. One pixel comes from the left border of a div, the second pixel from the background colour, while a third pixel comes from the right border. This means less data, but still a lot of code!

How much data? Well there are 1,452 divs used in this demo. I've used a PHP loop just to spit them out. The divs are then styled by a PHP-generated stylesheet. But that's not all. There are several other stylesheets used too, which enable the image to be filtered as if you were using Photoshop!

Originally I did the whole demo with PHP, because the filtering was done live. I had a file of the raw image data which was then looped through to output the CSS directly. This enabled me to edit the colour values to produce any effect I wanted. To do this I defined the CSS colours with the 'rgb' format (eg: 'rgb(197,120,76)'), rather than the usual hash one (eg: '#FFE6D3'). This enabled me to get the values for the Red, Green and Blue colour channels. From there I could use PHP to change these values, simply by applying maths to them, or swapping them round, so the colours were reversed. All very easy.

Alas the routine was quite slow. Several seconds were needed for each image change to appear. I then thought the solution lied in using JavaScript. Modern browsers give you what's called a Document Object Model, or DOM for short. This is basically a map of the current web page elements (such as tags and styles) that you can look at with JavaScript to get information about anything on the page. The beauty is you can also edit the DOM, and the changes appear instantly. So for example, you can add extra tags, such as a new table column, or remove existing ones to hide parts of the page when the user clicks on a button. Immensely useful because there's no delay while the page is redrawn.

After much tearing my hair out I managed to get a working script. Using inline styles I was able to read the colours for each div, change them, then write them back to the page. But that proved as slow as my original PHP version. The reason was the sheer amount of data to sift through each time. A pity as this version had the best advantage - filter effects could be mixed together. The PHP version was static because each filter could only be applied once. After that it returned to the original image data before changing it.

Then I struck on the idea of using alternate stylesheets. These proved ideal. The image could be changed almost instantly, just by clicking on a link. Sadly I found no way to combine filters this way, so again only one can be applied at once.

Browser Support

Each version of the demo had different browsers choking on the code. Opera 7.5 showed the DOM version changing the page directly as the loop in my code progressed, while other browsers waited until the loop was complete before displaying the changes. The result is that Opera was slow here. IE6 failed to even work at all on this version, which I think is down to some incompatible JavaScript I was using. To make it compatible would have meant a longer script, which would have been slower. Only Mozilla and Firefox liked the DOM version.

Full Browser Support:
Windows (XP):

Version 1.1 (PHP):
IE5, 5.5, 6, 7 - superb
Mozilla 1.5, 1.6 - superb
Firefox 1.0.5 - superb
Opera 7.20 - superb, but gives you a blank screen between changes
Opera 7.54 - superb
Opera 8.02 - superb

Version 2.1 (JavaScript):
IE5, 5.5, 6, 7 - the filters don't work
Mozilla 1.5 - superb, though it sometimes jumps to another window
Mozilla 1.6 - broken - superb
Firefox 1.0.5 - superb
Firefox 4.0 - red or dark filters appear striped
Opera 7.20 - half works - some filters corrupted. Updates the image in real-time! (But very slowly.)
Opera 7.54 - nothing happens due to a change in the way browsers now read attributes. (RGB is converted to hex!)
Opera 8.02 - as above

Version 2.2 (JavaScript) - Opera 7.5 or 8 only:
Opera 7.54 - superb if slow
Opera 7.60 Preview 2 - nothing happens
Opera 8.02 - superb (and fast!)

Version 3.1 (Stylesheets):
IE5/5.5 - good but slow to update
IE6, 7 - superb (fast)
Mozilla 1.5 - superb (but wait until all stylesheets are loaded)
Mozilla 1.6 - broken - superb
Firefox 1.0.5 - superb (fast)
Firefox 4.0 - superb
Opera 7.2 - too slow
Opera 7.54 - slow but works
Opera 8.02 - superb, if slow

Mac (OS X):

Versions 1.0, 2.0 & 3.0:
Safari 1.1 - superb
Firebird 0.7 - no image shown
Netscape 7.02 - no image shown
IE 5.2.3 - no image shown
Opera 6.03 - the filters don't work
Opera 7.50 Preview 3 - superb (speedy JavaScript!)

Linux (Yellow Dog):

Versions 1.0 & 3.0:
Mozilla 1.6 - superb

Thanks to Stefan Kremer and others for invaluable help in testing on a Mac.


I can't vouch that this demo will work for you. Slower machines may run out of steam. Your browser might keel over. View it at your own risk.

The stylesheets in Version 3 take up an awful lot of memory. I've tried to compact them as much as possible, while still leaving them readable. Thus the whole demo comes in at something like 1.4Mb! If you don't have broadband, I've made a 168Kb zip version of the demo you can download. This gives you the main demo file in plain HTML (no PHP needed) and a folder called "css" that contains the stylesheets. Put the main file and the folder in the same directory on your computer. Then you can run the demo from there.

CSS Pencils Demo Versions

Comments (48)

Comments are locked on this topic. Thanks to everyone who posted a comment.

  1. dodo:
    wow that's insane.. it did take quite some time to load on my IE6 even that i'm on T1 connection

    Posted on 5 January 2004 at 10:10 pm
  2. Karina:
    Amazing! ;=) That's all I got to say.

    Posted on 6 January 2004 at 3:08 am
  3. amber:
    It's insane, but it's also just gorgeous!

    Posted on 6 January 2004 at 1:51 pm
  4. liz:
    I can't believe you've only gotten three comments on this thus far... but that's the most crazy insane piece of CSS I've ever seen! Madness, sheer madness! Congratulations!

    Posted on 6 January 2004 at 8:21 pm
  5. flump:
    thats pretty f****** amazing

    Posted on 7 January 2004 at 6:52 pm
  6. flump:
    just out of curiositiy, did you use
    or something similar to create the html (you can using something like html tidy to conver the html which that page creates to xhtml)

    so it wouldnt need much more changing to create the page you made.

    just a thought.

    Posted on 7 January 2004 at 6:57 pm
  7. Sushubh:
    You are insane. Go to Bill Gates and demand for a job in the IE development (if it exist somehow) department. If he refuses. God help his soul.

    Posted on 7 January 2004 at 7:09 pm
  8. Big John:
    Apparently Chris hand coded this monster. If he wasn't mad before he is now. Woohoo! :-D

    Posted on 7 January 2004 at 8:05 pm
  9. Chris Hester:
    "just out of curiositiy, did you use or something similar to create the html"

    No, never seen that site before. The first version of the demo used PHP to read in all the image data line by line, from a text file. It then converted it into CSS. If I tell you how I got the image into RGB values you'd probably laugh, or call for the men in white coats. :-)

    Once I had the data, PHP was used to change it, initially on the fly, into the filters you see. I had a lot more filters before, such as 10 levels of zoom, and a weird water effect that came about by accident.

    For the final demo I went back to this version to generate the CSS, which was then saved out as separate stylesheets.

    Ideally you could have a routine that takes any image and converts it to CSS. But that's beyond me at the moment. :-D

    Posted on 7 January 2004 at 8:07 pm
  10. giselle:
    that's amazing! it take a while to load on my computer..but the result was incredible! GREAT JOB! :-D

    Posted on 7 January 2004 at 11:19 pm
  11. Stu Nicholls:
    You must have the patience of a saint to create such a picture.
    I have been playing around with pure css art on my web site but nothing as adventurous as this.
    You could almost have done this down to a pixel level. A css masterpiece!

    Posted on 7 January 2004 at 11:31 pm
  12. Phil:
    You are the god of CSS, all our CSS are belong to you.

    When I first put up my blog and realized the power of CSS I was inspired. It fascinated me that I could control things right down to the pixel. But your demo has inspired me to a new level.

    Thank you!

    Posted on 8 January 2004 at 2:40 am
  13. csant:
    amazing work! simply wonderful...


    Posted on 8 January 2004 at 8:20 am
  14. Beni:
    yeah... i can't belive it...

    Posted on 9 January 2004 at 9:30 pm
  15. Anna:
    *is utterly speechless*

    Posted on 10 January 2004 at 11:29 am
  16. Chris Hester:
    Related post on Dodo's Message Board:

    Posted on 11 January 2004 at 11:04 pm
  17. runningtings:
    Makes me think that someone somewhere could set up some program to output the divs.
    Excellent work, makes people think.

    Posted on 12 January 2004 at 4:19 pm
  18. Chris Hester:
    Shit. I am owned.

    Thanks to Eric Meyer for mentioning the site and Tantek Çelik for forwarding me the link.

    Posted on 13 January 2004 at 8:39 pm
  19. Nicholas Liu:
    I know nothing about CSS, but I know that that's fucking amazing. Wow.

    Posted on 16 January 2004 at 11:04 am
  20. patricia:
    that's amazing. i can't begin to wrap my mind around what it would take to code that. :-O

    Posted on 16 January 2004 at 8:38 pm
  21. Ray:
    Hmm. I see nothing with Moz 1.6 but it looks awsome with IE6.

    Posted on 17 January 2004 at 2:26 am
  22. Will:
    By the way, the css version loaded quickly on a fast DSL line and displayed flawlessly in Firebird 0.6.1 in Win2KPro-SP4 on a 300Mhz Celeron laptop with 288MB RAM and a 97% full hard drive! This is absolutely f***ing amazing! I am throughly stunned! Nice work!

    Posted on 17 January 2004 at 4:32 am
  23. Ruth:
    You are a both a lunatic and an inspiration. Awesome, man, completely awesome.

    Posted on 17 January 2004 at 9:34 pm
  24. Chris Hester:
    I find the demo is now broken in Mozilla 1.6 final. Anyone know what is happening? The height of each 'pixel' is extended, leading to the image carrying on at the bottom.

    Posted on 17 January 2004 at 10:20 pm
  25. Cameron Adams:
    Chris, I hope you didn't go through Photoshop and manually record the RGB values using the eye dropper :o]

    You could probably have got a converter that outputs the image as a text-based RGB format.

    Posted on 19 January 2004 at 2:36 am
  26. Chris Ruzin:
    I noticed that in Mozilla 1.6 on the Mac, the v2 image doesn't show up at all. But in Mozilla 1.6 on Yellow Dog Linux, it does. Has anyone else noticed this?

    The v3 image works amazingly on Mozilla 1.6 on YDL as well. The filters are lightning fast. And this is on an old Powerbook Pismo with only 192MB RAM.

    The v1 image works too, but is much slower at redrawing with the filters, as mentioned by the author.

    Posted on 20 January 2004 at 12:47 am
  27. Amit Karmakar:
    Awesome Chris! WOW! Pretty impressive.

    Posted on 20 January 2004 at 12:28 pm
  28. Sharon:
    Gives a whole new meaning to the phrase "mad genius"!! to put it to practical use...? Gotta have one of those auto-div-generators :-D

    But it doesn't need to be practical when it's this astonishing.

    Posted on 20 January 2004 at 2:56 pm
  29. Chris Hester:
    Fixed the problem with Mozilla 1.6/Win.

    Posted on 20 January 2004 at 8:53 pm
  30. Ryan Saghir:
    Wow.. that's simply incredible. You're one sick person! :-) Great work.

    Posted on 21 January 2004 at 3:57 am
  31. tommi:
    this is just *great*, i wish a div generator existed - overcaffeinated psycho php coding, anyone?

    Posted on 22 January 2004 at 4:43 pm
  32. Jamie:
    If you have the GD image manipulation library installed on your web server (I don't, so you'll have to copy it somewhere else to use it), should generate divs for you.

    Instructions (of a kind) are included in the source.

    Posted on 25 January 2004 at 9:50 pm
  33. Lindy:
    Ooooohmigod... this is Brain Breaking! STUNNING!
    Only took a few seconds on a Win XP with IE6.0

    Posted on 27 January 2004 at 7:22 pm
  34. Alex:
    This is sick, disturbing, and brilliant... I can hardly wait for the "CSS Output" option on my favorite paint program ;-)

    Posted on 28 January 2004 at 4:11 pm
  35. Gerry:
    Amazing! Could this technique be used to dynamically generate correctly-sized rounded box corners with PHP? That would be awesome if it could do that.


    Posted on 29 January 2004 at 5:29 am
  36. Chris Hester:
    Yes that would be a good idea. The code would be small too. You could also add transparency taking into account the background colour to give the same effect as PNGs, only it would work in all main browsers!

    Posted on 29 January 2004 at 10:42 am
  37. ECarlson:
    Very cool (all 3 versions) in Mozilla 1.7a/Win2K.

    For grins I tried Netscape Navigator 4.08, and version 1.1 worked, except it was slow, the bottom 1/4 of the image was stretched, and the effects mostly worked, but it wasn't too pretty about it. Version 2.1 displayed the pencils, again with the bottom 1/4 stretched, but none of the effects worked, and version 3.1 displayed a blank page.

    Posted on 16 March 2004 at 4:17 am
  38. tod:
    Hey, checked the site in the brand new Opera 7.5b1 for Mac... everything works great. The javascript version is downright speedy!

    Posted on 17 March 2004 at 3:28 pm
  39. Andrew Wooldridge:
    That's simply amazing. Imagine combining this technique with the 5k wolfenstein demo:
    You could have a tiny screen/video game

    Also, in case folks are interested, there is another way to draw images to the browser without resorting to external image files:

    you can create images that have a data: url instead of http and url encode the whole thing into the page itself. see here for more information

    Posted on 19 March 2004 at 4:47 pm
  40. Richard Thompson:
    that is AMAZING :-D

    Posted on 16 April 2004 at 2:57 pm
  41. mnemonic:
    very impressive. it'd be interesting to do filesize comparisons between the CSS implementation and the original image. and more thoroughly investigate the implications of your achievement............

    Posted on 3 May 2004 at 9:56 pm
  42. DuContra:
    I think someone is in desperate need of sex.

    Posted on 4 May 2004 at 6:12 pm
  43. Missy:
    WOW. That is awesome!!!!

    Posted on 13 May 2004 at 11:51 pm
  44. Kokoliso:
    1) The bad news: You're insane.
    2) The good news: You're onto something big. The W3C intelligensia might not like this. :)
    Well seriously, I think it's pretty cool and it is possibly the future, maybe, maybe not. One excellent application I can recommend to you is to use your technique to create rounded corners for divs and tables. I am so tired of having to use little graphics for corners.
    Definitely you could get a job at like PARC or MS or something advanced like that, where you can get to play all you want with divs.

    Posted on 17 May 2004 at 8:21 pm
  45. Ansonet bros:
    lright on mate.
    we were looking how to embed imgs in CSS and bumped into u :)

    We salute you in honour of your creation, and the commitment of hard crimes against any image-related sanity!

    Posted on 25 May 2004 at 12:19 pm
  46. Anonymous:
    that's simply bigger than a gif

    Posted on 16 June 2004 at 6:21 pm
  47. Jessica Deprez:
    This is outstanding! It must've taken you so long to create this. It may be a while before this is regularly implemented (because we all know an image will work on the web.. you never know when a certain 'exploding' browser will not :\ ), but it's another big step in the CSS creating community :) Many kudos!

    Posted on 14 July 2004 at 5:40 pm
  48. rich:
    Are you telling me you made 1492 css "id"s to create a picture of some pencil heads ? Try a jpg next time, much easier :-)

    Posted on 20 July 2004 at 1:15 am