Tuesday 26 June 2012

Optimising, not hiding

You may remember my posting a while ago about the importance of build scripts in an Interface Developer's workflow (see here).

Lately I've been knocking out some Ant scripts and realised there's a bit of my process that's worth sharing.

Goals of optimisation

The goal of most the scripts I write at the moment (at least the part related to CSS & JavaScript) is to compress the content as much as possible and into the least amount of files. The end result is less files get downloaded and those that do make the most efficient use of their bytes.

This also means the build forms a clear distinction between development code (designed for reading & sharing by humans) and production code (designed for downloading by devices & processing by their browsers).

What we're forgetting

All of this is very good and healthy but it misses one thing we used to take for granted. As explained above, production code is for devices & their browsers but the web is not just a delivery device for programs, it's also designed for reading & sharing by humans, just like our development code.

The source code of http://adactio.com/articles

This is important. One of the beautiful things about the web is that you can dig into sites or apps people have made and see how they tick. It's no coincidence that web development has a large amount of self-taught people working in it and I feel it would be a real shame to lose this just for lack of process.

So, a conundrum. How do we satisfy both sets of requirements?

Erm, quite simply actually

Turns out it's not that difficult. There's a few ways I could think of off the top of my head but they all involve one step: providing a link to the development code in the production. Here's how I do it:

  1. Concatenate my files.
  2. Create a directory (I call mine full) & copy them into it.
  3. Optimise the original scripts.
  4. Concatenate a standard comment onto the bottom of all files explaining how to access the full versions.

Here's a sample comment from a recent project:

/* A full version of this file is stored in a directory called 'full' at the js/ or css/ level. Add 'full/' into the file path, after 'js/' or 'css/' to access. For example, the full version of /assets/js/core-scripts.js is /assets/js/full/core-scripts.js */

The last step is the most important. Providing a URL, or a way to build one means your code is available in both forms and I don't personally think the extra characters will make enough difference to not do this.

If anyone else is doing something similar but differently I'd be interested to know as this is a first-pass at best.

Wednesday 11 April 2012

Colourful times: Introducing the CSS3 gradient image generator


I've been working on a project with quite a few CSS3 gradients recently. As usual I want the site to degrade nicely back down my browser matrix with contrast ratios holding up and the general look and feel being as close as possible. (Which doesn't have to be the same.)

Establishing a workflow

I'm using only linear gradients so the requirement is for an approach that can draw the gradient either vertically or horizontally.

I settled on a workflow shown in this article whereby a background image that repeats along one of the image axis is served to browsers that don't support gradients.

So a button's default background would be defined in CSS with a gradient, i.e.

linear-gradient(#490091, #8000FF 20%, #8000FF 50%, #B469FF 50%, #B469FF 80%, #7140A3)

The CSS above gives the button this background:

Button

The background would also be defined as an image that repeats along the x-axis, i.e.

background:#490091 url(/img/purple_repeater_1.png) 0 100% repeat-x;

The CSS above gives the button this background:

Button
Cross-browser differences

The most obvious difference is that a gradient is mathematically generated and so can scale to whatever dimension needed, whereas the raster image used in the second example is fixed.

Any changes to the element size (i.e. through text resizing) will mean the image no longer fills the space but adding a background colour matching one of the gradient stops can help this. It's not quite as pretty but it keeps the colour ratio and preserves some of the look and feel:

Summary

That leaves quite a lot of tasks to perform just to get a result:

  1. Make the linear gradient in CSS.
  2. Produce all the vendor variants (made a lot easier by Lea Verou's excellent cssgradientsplease tool).
  3. Take a screen-grab of it and cut a background image for older browsers.

The biggest task here seemed to be making the background image (screengrab the web page, open Photoshop, crop & save), so I made an online tool to provide a bit of automation: http://tombye.github.com/CSS3-Gradient-image-generator/.

Using the tool

The tool accepts the same syntax as Lea Verou's parser, which is the closest we'll get to a standard at the moment, so you don't have to change it when generating the image and the CSS variants.

It will always generate an image in the page HTML for you to grab but can also download it if needed. (Note: I can't figure out how to change the download's file name, let me know if you know how.)

There's a set of unit tests in the repo for checking the CSS parsing is correct. They cover all I can think needs testing but let me know if anything isn't working as expected so I can add tests for any missed requirements.