La Coctelera

foo-bar

Un blog sobre esto y lo otro

20 Noviembre 2006

Colour palettes for web development

One of the best features of CSS is implied in its own name: cascading. It means that, if you change a style definition, all elements of a page that have that style applied will change at the same time in a "cascade".

As recomended by the W3C, designers must not rely on color alone to convey information. That's a reasonable recomendation that we designers must always follow.

As you designers probably know, we use to work with colour palettes. Usually a document has a previously decided range of colors, often limited to just a few, that we use throughout the document. In DTP applications we define this colour palette and use it to apply colour to the different styles in use. In that way, if we want to change the colour scheme, we just have to redefine the colour palete and the change is applied to all the elements that use that colours in the document, giving the document a different feeling. In the same way, we can use the same style but different colours for different document sections. But in CSS, if you want to do that you have to create a whole new style sheet, doing a "find & replace" all over the CSS to change the colour definitions.

That’s why I’d like to see CSS Colour Palettes implemented in CSS3.[...]

This quote from electriblog shows in all it's a glory a little but insistent pain that shows up every time we go into cascade style sheets. It seems that my head retained the whole article and, a couple of days ago, my brain got working (tm), remembering an article from PPK which could hold the solution in it: it turns out that, some CSS rules, can have as a possible value the url() command, for example:

background-image: url('mi_imagen.gif');
 

And how is this useful? how does it help in creating colour palettes? The key, very little known, is that the standard specifies that the url() command admits a little bit of javascript (example here). It's a very limited javascript but, after all, you can put it there. Let's say, imagine you have a javascript variable called path_to_gif, then it would be valid to do something like this:

background-image: url('javascript:document.write(path_to_gif);');
 

Knowing this, inmediatly everybody thinks about defining a colour palette in a javascript file, and make some kind of ugly hack in the CSS (as shown in previous example, a document.write) which would take this variables to the specified colour attributes. Before anyone starts to code this as fast as hell, let me say it: this won't work, as the javascript is executed in a very limited scope. It seems that the standard's main intention was to provide of some flexibility to this parameter to make it a little more dynamic.

So, as we seen, this first attempt was not valid. But a useful pair of ideas have already popped up: defining the colour palette in a separate javascript file and, somehow, push some javascript code inside the style sheet.

First part is quite easy to achieve but second one... ugh! We've already seen that we can -barely- put some javascript inside a style sheet. But we've also heard zillions of times that mixing javascript with HTML or styles with HTML isn't a good practice, so imagine of mixing javascript inside CSS...

In the other hand, what it is very common is using javascript to change a web's appearance, and it's this way where we are going to reach a satisfactory conclusion. However, we are not allowing any sahbby, grotty code. The idea is to obtain a solution which will be sufficiently transparent and generic, which translated to web developer jargon is called unobtrusive. I won't make a big speech of this point, instead, I will refer to another article from PPK. In fast, it comes to say that an unobtrusive script should achieve these characteristics (if you want to read more about unobtrusive scripting, this article is a good place to begin with):

  1. Usable: A script should be unobtrusive to the user. No flashy stuff or sliding layers, just a small usability benefit that helps users make sense of a site instead of hindering them.
  2. Accessible: A script should be unobtrusive when it doesn’t work. The site shouldn't depend on the script.
  3. Easy to implement: A script should be unobtrusive to Web developers. Typically, a Web developer should only have to include a script and to add a class or id to one or more XHTML elements, which the script interprets as: "Deploy the behaviour here".

At this point we are at disposal of introducing the last piece of the puzzle: Behaviour, a quite impressive javascript library developed by Ben Nolan, which allows us to specify CSS selectors to apply them javascript functions in an unobtrusive way. Technically, is the best javascript code I've ever approached. So little code, so elegant, which allows so many things going so unnoticed.

Making a very quick summary, with this library we can define an array of CSS selectors and associate them with the javascript event that we want:

var myrules = {
  '#example li' : function(el) {
    el.onclick = function() {
      my_js_function_a(this);
    }
  },
  '#example2 li' : function(el) {
    el.onclick = function() {
      my_js_function_b(this);
    }
  }
};

Behaviour.register(myrules);

From now on, we are going to fit all the pieces together. Let's have another look to them:

  1. HTML Document (better if xHTML), with page content.
  2. One or several style sheets, where any of them is going to have any colour attribute (neither front colour, nor background, nor border). Made this exception, the rest of the page presentation will be defined in the CSS.
  3. Behaviour javascript library, used to split behaviour from content.
  4. Another javascript library, developed by myself, which seamlessly integrates with Behaviour, and allows us to use in an unobtrusive way a colour palette to define an style. On an unkown originality show off, I've decided to name it css_init_palette.
  5. A javascript file, where we will define our colour palette and our CSS selector's array, so we can associate both the javascript events and the colour palette to the page elements.

My custom library adds the on_css_init event, so we can apply the colour palette in a similar way we apply events to CSS selectors with Behaviour. It's not a very big thing (~2KB) but, quoting Woody Allen, "hapiness is all about having little things: a little mansion, a little yatch, a little fortune...".

I've also added a convenience method called set_css_color_palette(el, bg, fg, bd), which receives four parameters: the HTML element in which we apply the colour palette, background colour, foreground colour and border colour. An example of use could be the following one:

var pl_bg_col1 = "#ffff88";
var pl_fg_col1 = "#ff7400";
var pl_bg_col2 = "#cdeb8b";
var pl_fg_col2 = "#73880a";
var pl_bg_col3 = "#c3d9ff";
var pl_fg_col3 = "#3f4c6b";

var css_palette = {
  'div.div1' : function (element) {
    element.on_css_init = function() {
      set_css_color_palette(this, pl_bg_col1, pl_fg_col1, pl_fg_col1);
    }
  },
  'div.div2' : function (element) {
    element.on_css_init = function() {
      set_css_color_palette(this, pl_bg_col2, pl_fg_col2, pl_fg_col2);
      document.getElementById('id2').style.borderWidth = "2px;";
    }
  },
  'div.div3' : function (element) {
    element.onclick = function() {
      set_css_color_palette(this, pl_bg_col3, pl_fg_col3, pl_fg_col3);
      document.getElementById('id2').style.borderWidth = "1px;";
      document.getElementById('id3').style.borderWidth = "1px;";
    }
  }

};

Behaviour.register(css_palette);
css_init_apply();

This example has several things which should be noted:

  1. On the method definition executed in on_css_init is possible to call more javascript functions ('div.div2' case), but I definitely don't recommend this approach: mixing behaviour with presentation it's not a good practice so, if we've done it a little, we've better don't do it anymore.
  2. The set_css_color_palette method and the on_css_init event are independent one from another, as it can be seen in 'div.div3' case.
  3. The colour palette initialization, css_init_apply();, must always go next to Behaviour initialization (Behaviour.register(css_palette); or Behaviour.apply(); if we've been toying around with DOM).

In relation to the first consideration, it would be very nice if the future standard CSS 3.0 would add support for colour palettes. The easiest way I can think of would be implementing a new command, palette(), which could parse javascript, pretty much the same way as it's done in url() command. I haven't found any other way to achieve a colour palette for web development, so until then we'll have to ignore the use of colour palettes or use a custom solution like the one described above.

As I said before, css_init_palette is heavily based on Behaviour, so it will run in the same browsers as it. I've tested it against Firefox 1.5 & 2.0, and against Internet Explorer 6.0. It should run in any nowadays browser, but it would be nice to hear about other people who have successfully tested it against other browsers and platforms.

I've uploaded a complete example of use for everyone who wants to have a look to the whole picture. As this is all too web 2.0, I've chosen the colour palette from the most appropiate site I could think of. Oh, by the way! before we end, this tiny library is BSD licensed, just like Behaviour.

And that's all folks, hope someone finds this useful, at least as an intellectual exercise.

If you are from Google, you've liked the post and you've managed to read this, then you can try to hire me :o)

(Disclaimer - english readers: this is not my mother tongue so, if you see any misspellings it's not my fault, it's a beta version :o) and furthermore it's 3.00am at the time of writing this! post a comment and I'll fix it as soon as I can).

Update 21/11/2006: Whoaa! Been hitted by Ben Nolan himself! Thousand thanks for the post!

servido por foobar 3 comentarios compártelo

3 comentarios · Escribe aquí tu comentario

Ethan

Ethan dijo

Why not use a server-parsed stylesheet? Seems hella simpler.

3 Diciembre 2006 | 04:34 PM

foo-bar

foo-bar dijo

Hi Ethan,

My main goal was to provide a CSS colour palette, sticking as much as I could to the stylesheet, so web designers could use it easily.

I'd prefer to do it on the client side because I think it has many advantages, the most important of all, easiness for the web developer. Using this approach, they only have to set up their palette and declare the rule's array, which is pretty similar of how is done when using Behaviour. Also, you don't mix client-side code with server-side code so, if you want to toy around, you don't have to redeploy the whole app to see the changes, you refresh your page and your done.

Using Behaviour is the key element here. It allows to do the server-side parsing on the client, in an unobtrusive way, so the rest of the client code (css, js, html) isn't affected. We are mixing here javascript with css, which is not ideal but I think it's the least worst option of being able to use a colour palette. In fact, I don't think it's a bad solution anyway, beside the fact you must support javascript.

CSS lacks of support colour palettes so, if you want to use them, you must accept this javascript constraint (at least using css_init_palette). Done this assumption, I think css_init_palette is a very elegant solution: simple, generic, small and unobtrusive.

Regards,
JP

3 Diciembre 2006 | 09:27 PM

foo-bar

foo-bar referenció

css_init_palette v0.2

...Los lectores hispanos por favor sírvanse a leer el artículo en español dos párrafos más arriba :O)) It is almost 6 months back when my brain got working and developed css_init_palette, an unobtrusive script which allows the use of colour palettes in web development...

10 Mayo 2007 | 01:28 AM

Escribe tu comentario


Sobre mí

    Como se puede observar en esta foto, visto chistera, tengo monóculo, fumo puros y, probablemente, bebo cerveza.

    Para regalarme jamones, ofrecerme dinero o simplemente mandarme unas líneas, nada como usar el formulario de contacto.

Tag de sabiduría

Estadísticas


    Ver las estadísticas de foo-bar

    spam posion

Fotos

foobar todavía no ha subido ninguna foto.

¡Anímale a hacerlo!

Buscar

suscríbete

Selecciona el agregador que utilices para suscribirte a este blog (también puedes obtener la URL de los feeds):

¿Qué es esto?

Crea tu blog gratis en La Coctelera