The Makeshift Gradient

Recently we helped our friends (and new "flatmates") at Makeshift to build the first iteration of their website. They wanted something quick, lean and simple to get a presence out there without burning a load of time they could put to better use on their hacks. No problem - we put together a simple flat HTML page managed through Github Pages so that anyone on the team could easily push a change and have it deployed.

The more complex bit was the site header, an eye-catching grid made up of the swatch of brand colours Makeshift had chosen. You might think "nah that's easy, its just an image", but in order to keep the site scalable and responsive I decided to use a CSS gradient instead.

When you imagine a gradient you probably immediately think of a smooth graduation from one colour to another. So using a gradient to make a grid of blocks might sound as sensible as making jam out of bacon. But that works as well, so bear with me!

The key is that the CSS gradient specification uses "colour stops" to define where on the gradient the shade should change. Typically you would specify 0% and 100% as your stops to give a smooth gradient from one side of the element to the other. But if you bring those figures together - say 25% and 75% - you get a smaller gradient with flat colours either side. And if you put two colour stops in the same place? You get an immediate change from one to the other.

Gradient Examples 1

Extending from that, you can specify multiple colour stops and so create several bands of colour along an element's background. You'll need a colour stop at the start and end of each colour, so for Makeshift's palette of 9 colours there will need to be 16 colour stops in your CSS rule. Why not 18? Because the initial stop at 0% and the final stop at 100% are implicit. Gradient Example 2

The rule for this is, as you might expect, rather long winded and there's still quite a tangle of vendor prefixes to implement a cross browser CSS gradient. So we're just going to give examples in the unprefixed linear-gradient syntax - however libraries such as Lea Verou's -prefix-free can help you create the alternatives.

background: linear-gradient(to right, #e15c1b 11%, #9a937a 11%, #9a937a 22%, #cb6e40 22%, #cb6e40 33%, #8c9159 33%, #8c9159 44%, #484a35 44%, #484a35 55%, #522321 55%, #522321 66%, #a52e28 66%, #a52e28 77%, #a2726a 77%, #a2726a 88%, #dfa454 88%);

Live demo

This is great for a strip of colours, but to get the full Makeshift grid we need to go in both directions. You can't do this with a single gradient, but you can put multiple background images on a single element and so overlap several gradients with the colour stops offset.

Gradient Example 3

Here we're setting a background property with two linear-gradient rules, the second has the colour stops offset by five (so colour 1 in the first row is colour 6 in the second). We also need to set the background repeat to repeat-x, give each background a size and set its position.

background: linear-gradient(to right, #a52e28 11%, #a2726a 11%, #a2726a 22%, #dfa454 22%, #dfa454 33%, #e15c1b 33%, #e15c1b 44%, #9a937a 44%, #9a937a 55%, #cb6e40 55%, #cb6e40 66%, #8c9159 66%, #8c9159 77%, #484a35 77%, #484a35 88%, #522321 88%), linear-gradient(to right, #9a937a 11%, #cb6e40 11%, #cb6e40 22%, #8c9159 22%, #8c9159 33%, #484a35 33%, #484a35 44%, #522321 44%, #522321 55%, #a52e28 55%, #a52e28 66%, #a2726a 66%, #a2726a 77%, #dfa454 77%, #dfa454 88%, #e15c1b 88%);
background-repeat: repeat-x;
background-position: center 0, center 100%;
background-size: 100% 50%;

Live demo

For the final gradient, there are five rows to the grid and therefore five background image gradients. We also set the colour stops with pixels rather than percentages to be able to control the size that the grid appeared a little better, to allow it to repeat regardless of the width of the viewport, and to align accurately with the logotype.

Screen Shot 2013-05-24 at 14.36.03

This results in (unprefixed) CSS which looks like:

background-color: #df5a19;
background: linear-gradient(to right, #a52e28 86px, #a2726a 86px, #a2726a 172px, #dfa454 172px, #dfa454 258px, #e15c1b 258px, #e15c1b 344px, #9a937a 344px, #9a937a 430px, #cb6e40 430px, #cb6e40 516px, #8c9159 516px, #8c9159 602px, #484a35 602px, #484a35 688px, #522321 688px), linear-gradient(to right, #9a937a 86px, #cb6e40 86px, #cb6e40 172px, #8c9159 172px, #8c9159 258px, #484a35 258px, #484a35 344px, #522321 344px, #522321 430px, #a52e28 430px, #a52e28 516px, #a2726a 516px, #a2726a 602px, #dfa454 602px, #dfa454 688px, #e15c1b 688px), linear-gradient(to right, #522321 86px, #a52e28 86px, #a52e28 172px, #a2726a 172px, #a2726a 258px, #dfa454 258px, #dfa454 344px, #e15c1b 344px, #e15c1b 430px, #9a937a 430px, #9a937a 516px, #cb6e40 516px, #cb6e40 602px, #8c9159 602px, #8c9159 688px, #484a35 688px), linear-gradient(to right, #e15c1b 86px, #9a937a 86px, #9a937a 172px, #cb6e40 172px, #cb6e40 258px, #8c9159 258px, #8c9159 344px, #484a35 344px, #484a35 430px, #522321 430px, #522321 516px, #a52e28 516px, #a52e28 602px, #a2726a 602px, #a2726a 688px, #dfa454 688px), linear-gradient(to right, #484a35 86px, #522321 86px, #522321 172px, #a52e28 172px, #a52e28 258px, #a2726a 258px, #a2726a 344px, #dfa454 344px, #dfa454 430px, #e15c1b 430px, #e15c1b 516px, #9a937a 516px, #9a937a 602px, #cb6e40 602px, #cb6e40 688px, #8c9159 688px);
background-repeat: repeat-x;
background-position: center 0, center 86px, center 172px, center 258px, center 344px;
background-size: 774px 86px;

Live demo

Once all the browser-specific prefixes are included it's a bit of a brain-melt to try and manage, but for the sake of our sanity we were at least generating it all through LESS with the colour values and grid size being variables in mixin rules. The most serious browser quirk we discovered was that Firefox (at the time we built the page) couldn't handle the full 16 colour stops, so the -moz-linear-gradient and -moz-background-size rules needed to be adjusted to only show 7 colours out of the 9. The version at the time of writing (21) appears to behave better.

This does all depend on viewing the site in a browser which supports CSS gradients, multiple backgrounds and background size - but in mid-2013 that effectively only excludes IE9 and below, which Makeshift as forward-thinking hackers are willing to live with.

There were a few more complexities once the basic grid was up and running, such as how the cell size scales down through the media queries, and how the colour strip "sticks" to the navigation as the user scrolls down, but feel free to dig through the final CSS on the Makeshift site to see how it all came together.

Stephen Fulljames
More from Stephen