CSS Icon Backgrounds

Adding backgrounds programmatically to icons is easy with CSS...

Screenshot of a hue wheel demonstrating the colours used in my post.

When composing this post, I decided that each of the accompanying icons would work well against coloured discs, gradually rotating in hue as they progressed down the page. The result was something a bit like this:

Screenshot of icons with programmatically-generated CSS backgrounds.

I opted for 12 different colours, so each icon’s hue would change by 30 (hue being measured on a scale of 0-360 degrees). After some thought, I decided to create the discs programmatically using CSS. This has the following benefits over including them as part of the icon image:

  • If I ever decide to add, remove, or edit page content, I wouldn’t need to re-render any of the icons as a result of the hue pattern breaking.
  • If I ever embark on a website redesign and the icon backgrounds no longer work, I could just edit the CSS file for a completely new look (you never know, excessive gradients might just make a comeback).
  • I could re-use the icon images elsewhere on my website without concern for their background colour.

The Means To The End


	<li class="list-item-outer">
		<div class="list-item-inner">
			<h3>Say goodbye to your social life</h3>
			<img class="image-icon disc-background" src="/images/say-goodbye-to-your-social-life.svgz">
			<p>Are you happy to work long and unsociable hours? I mean <em>really</em> long and unsociable hours? If so, congratulations! Your life now belongs to the recording studio. Expect to work most weekday evenings (including Friday night), and all day Saturday and Sunday too. If you prefer to work a more regular nine-to-five, get a job at Tesco.</p>
	<li class="list-item-outer">
		<div class="list-item-inner">
			<h3>Say goodbye to your bed</h3>
			<img class="image-icon disc-background" src="/images/say-goodbye-to-your-bed.svgz">
			<p>You may find yourself working throughout the night on a project, only to realise that you've also got a session booked for the following day. If that’s the case, two hours’ sleep and a bucketload of coffee should be more than sufficient. And yes, this really does happen.</p>
	<li class="list-item-outer">
		<div class="list-item-inner">
			<h3>Take the rough with the smooth</h3>
			<img class="image-icon disc-background" src="/images/take-the-rough-with-the-smooth.svgz">
			<p>Don’t like country and western? Tough luck! Only like one genre of music? Then you’ve got no chance! The likelihood is that at some point, you'll find yourself working on project that really isn't your cup of tea. The long and short of it is: no one cares! Being a professional, you'll take on every session with the same level of interest and enthusiasm as the next, with head-nodding and foot-tapping aplenty. As far as the client is concerned, you're totally into whatever genre you happen to be working on, and listen to it all the time. If they suspect otherwise, things could quickly get awkward.</p>

The CSS (using LESS as my CSS pre-processor of choice):

    @icon-bg-base: #80A6D4;
.image-icon.disc-background {
	background: @icon-bg-base;
	border-radius: 50%;
.list-item-outer:nth-child(12n+2) .image-icon.disc-background {
	background: spin(@icon-bg-base, 30);
.list-item-outer:nth-child(12n+3) .image-icon.disc-background {
	background: spin(@icon-bg-base, 60);
.list-item-outer:nth-child(12n+4) .image-icon.disc-background {
	background: spin(@icon-bg-base, 90);
.list-item-outer:nth-child(12n+5) .image-icon.disc-background {
	background: spin(@icon-bg-base, 120);
.list-item-outer:nth-child(12n+6) .image-icon.disc-background {
	background: spin(@icon-bg-base, 150);
.list-item-outer:nth-child(12n+7) .image-icon.disc-background {
	background: spin(@icon-bg-base, 180);
.list-item-outer:nth-child(12n+8) .image-icon.disc-background {
	background: spin(@icon-bg-base, 210);
.list-item-outer:nth-child(12n+9) .image-icon.disc-background {
	background: spin(@icon-bg-base, 240);
.list-item-outer:nth-child(12n+10) .image-icon.disc-background {
	background: spin(@icon-bg-base, 270);
.list-item-outer:nth-child(12n+11) .image-icon.disc-background {
	background: spin(@icon-bg-base, 300);
.list-item-outer:nth-child(12n+12) .image-icon.disc-background {
	background: spin(@icon-bg-base, 330);

A Few Things To Note:

  • The list-item-inner div may seem unnecessary, but it plays an important role in the subtle animations used on the page.
  • This was all possible down to the CSS3 nth-child selector. (12n+x) essentially means “every 12th child, offset by x“.
  • I couldn’t use nth-child directly on the image icons, as the images are not all on the same DOM node (each one is situated within a list-item-inner div). This is why list-item-outer receives the nth-child treatment.
  • I use compressed SVGs (.svgz files) for all of my graphics site-wide (apart from photos), as in this age of high DPI screens it just makes sense. For IE <9 however I use Modernizr to revert back to a PNG alternative.

The Disadvantages:

  • IE <9 doesn’t support border-radius or nth-child, so I have to rely on the fallback (where each icon background is square and the same colour.

The Alternative

I could have used plain ol’ vanilla SVG and programmatically edit the colour of a disc (already embedded in the image) via CSS. I’m a real fan of SVGZ though (due to the excellent compression levels achieved), which unfortunately doesn’t present individual elements to the DOM, and so therefore isn’t editable.

Leave a Reply

Comments will be approved pending moderation.