Due to a server outage, images are currently not working.
Have you made your backups lately?

Dynamically Generated CSS Images in LESS

In solving some of the problems needed to create my pure CSS progress bars with rounded corners, I ended up using a combination of two backgrounds: a background-color and a background-image. Unfortunately, images are rather static, inflexible things. They require you to make a new image every time you want to use a slightly different colour… or do they?

While playing with different colours in my design (I like to prototype in code), the inability to change the colour of the image on the fly didn’t sit well with me. After all, it’s just a bunch of bytes being parsed by the browser before being rendered on the screen. If we can provide that data in CSS as a data-uri, as I already showed in my previous article, then surely we can have some level of control over what that data represents. I got a bit obsessed about this and over the weekend I managed to get this insanity to work. By dynamically generating a data-uri, we can have a 1-pixel image of any colour we want.

The result is available on Github. Check out the demo to see it in action.

Dynamic CSS

The one thing this solution requires is some level of dynamic control over the styles that define the image. For all I care, this can be SASS, a perl script that generates static CSS on the server or even PHP. I used LESS for this, because I was already using it anyway and it allows me to write JavaScript in my stylesheets. You can easily stick with with whatever you are already using and use LESS on the side, but the ideas in this technique are not tied to LESS in any way; it shouldn’t be hard to port to other tools.

A Dynamic Image

For a solid, single-colour background, all you need is a single pixel image. In the previous article I used this one:

It’s the smallest possible (43 bytes) 1-pixel image that is valid and visible on the web. This one happens to be red, but as I will show it can be any colour. I chose GIF because it was smaller than PNG for my purposes, but it’s probably possible to generate a PNG as well. GIF is also a very old and well understood file format, and before you ask: it’s no longer trapped in intellectual property limbo.

The goal here is to take a colour (say, red) and generate a 1 pixel gif from that. To be able to do that, we need to understand the GIF file format a little bit. Fortunately Wikipedia does a pretty good job a that, so I am not going in too much detail. What is important is that in GIF, the image is split into two parts: the palette is stored as a global colour table, separate from the image data. This means, that in order to change the colour of a one pixel image, all we need to do is change that colour in the palette; there’s no need to touch anything else.

The simplest possible GIF for this has only 43 bytes: it has just one pixel and a 1-bit palette (two colours, of which only one is used).
If we want to have a 1-pixel GIF of another colour, all we need to do is find colour #0 in the palette. Let’s do this for red_pixel.gif:

00: 4749 4638 3961  GIF89a
06: 0100 0100 f000  ......
0c: 00ff 0000 ffff  ......
12: ff21 f904 0000  .!....
18: 0000 002c 0000  ...,..
1e: 0000 0100 0100  ......
24: 0002 0244 0100  ...D..
2a: 3b              ;

As expected, the first colour in the palette has a hexadecimal value of #FF0000, or 255,0,0 RGB. Changing this to #00FF00 will make it green and #0000FF blue. Just load up the file in a HEX editor of choice (Hex Fiend is nice) and try it.

Now, being able to change an image colour by changing some values in a HEX editor is nice, but it’s hardly flexible. To make this useful for anything, we need to be able to change the GIF from CSS. Yay for data URIs!

Data URIs allow content to be embedded in CSS, where it can be used for backgrounds etc. As we are generating CSS using LESS, all we need is a way to generate a data URI for the desired image!

The data URI for red_pixel.gif looks like this:

data:image/gif;base64,R0lGODlhAQABAPAAAP8AAP///yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==

The 43 bytes have been turned into 61 ASCII characters using Base64 encoding, plus some stuff describing this is a data URI with an encoded GIF. If we want to change the GIF, all we need to do is change the data URI and we’re golden.

Now, it would be possible to just generate a whole GIF from an RGB bitmap and Base64 encode that, but that would be a lot of work. We really only need to change the 3 bytes representing the primary colour in the palette. The rest of the image is left untouched, so just swapping those three bytes out in the data URI is enough to get a 1-pixel GIF in a different colour.

Unfortunately, the way Base64 works makes this a bit harder. Base64, as the name suggest, encodes data in 64 bit chunks. Every 6 bits are represented by 1 ASCII character. With our luck, the first four bits of the primary RGB pair get encoded in one such 6-bit chunk and the last two in a separate 6-bit chunk. This means replacing the 6 bits in the palette, requires re-encoding the 12 surrounding bits into 5 characters.

Caring not too much about efficiency, this can be done in a few lines of JavaScript (try in jsFiddle):

Generating a GIF with the desired primary colour now becomes a simple matter of inserting these 5 characters in the right place in the Data URI:

"data:image/gif;base64,R0lGODlhAQABAPAAA"
+ encodeRGB(0,0,255) + 
"///yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==)"

Doing this in LESS is a bit complicated, as Less is very picky about syntax, but it’s easy to just cram all of that ugly code into a mixin, so that when it is used, you can just forget about all of that:

This gives div.progress item a gif with the desired colour as a background. The trick only works in browsers that support data-URIs, so IE7 and below get no love.

As a bonus, I also liked to be able to specify the colour as a HEX value. Try that out in a jsFiddle here. The whole thing is available as a LESS module on Github. It really works, check the demo!

I would love to see someone do a PNG version of this hack. I didn’t need it myself, but a 24 bit PNG would allow specifing an Alpha (opacity) value as well!

14 Responses to “Dynamically Generated CSS Images in LESS”

  1. dmitry_f says:

    Hi. I’ve implemented PNG generator with LESS. Here is code and underlines demo.

  2. Pingback: Реализация стилей подчеркивания в LESS через генерацию png в data-URI - cSSSeo: интернет, SEO, WordPress, CSS, HTML5

  3. Everything is very open with a precise explanation of the issues.
    It was truly informative. Your website is very
    helpful. Many thanks for sharing!

  4. Fabulous, what a website it is! This weblog presents helpful information to us, keep it up.

  5. Eleanor says:

    Spot on with this write-up, I truly feel this site needs a great deal more attention.

    I’ll probably be returning to read through more,
    thanks for the info!

  6. I loved as much as you will receive carried out right here.
    The sketch is attractive, your authored subject matter
    stylish. nonetheless, you command get got an shakiness over that you
    wish be delivering the following. unwell unquestionably come more formerly again
    as exactly the same nearly a lot often inside case you shield this hike.

    Look into my site Minecraft Chomikuj Za Darmo – Rybnitsa-City.Info -

  7. I’m curious to find out what blog system you have
    been working with? I’m having some small security issues with my
    latest site and I’d like to find something more safe. Do you have any suggestions?

    My weblog :: Ludovico einaudi una mattina

  8. Hello! I realize this is sort of off-topic however
    I needed to ask. Does managing a well-established website like yours require a massive amount work?

    I am brand new to running a blog however I do write in my journal daily.

    I’d like to start a blog so I can easily share my experience and views online.

    Please let me know if you have any recommendations or
    tips for new aspiring bloggers. Thankyou!

  9. Exactly where did you learn to write as well as you do.
    I plan to create my very own website and get started making a living from this.

    my website; sell your automobile

  10. Are you currently interested PSN code generator sites. com
    require it and it find everything you need learn and learn to become successful at stock options trading and
    purchasing today’s stock game. a part of the wall that is painted intense colorless.

  11. So to give you not only my personal millionaire marketing machine talents just might be better
    to think you got it all right now. Well it’s a” Walk in the beginning you will need trust me!

  12. The use of a digital board in the classroom can be beneficial to the learners as
    they work well to make learners concentrate on the topics.
    Many people prefer the look of stainless steel appliances because it adds a clean, fresh, and modern appearance to the home.

    The ingredients that you usually find are based upon the kids of goals that Mary set for herself in the prior chapter.

  13. This Blackberry USB in Car Charger ensures that the battery of your Black – Berry mobile phone
    does not get damaged because of overcharging. For installation, you need certain basic tools such as screwdrivers, socket wrench, wire cutters, wire strippers,
    electrical tape and wire ties. This should then operate by way of the firewall of
    your vehicle, underneath the carpet, to the amplifier.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>