How to create a CSS3 tag cloud like on this blog

As part of my CSS3 try-out (also read my post on why I started using CSS3 on this site) I created a tag cloud that’s designed with CSS3 features. You can find the tag cloud under each article on my blog and also on the right on every page. In this article I’ll explain how you can create this CSS3 powered tag cloud yourself?

You can see rotations and shadows on all tags. Then they all differ a little in rotation and colors. Move over the tags with your mouse to see the :hover in action. Only on webkit browsers like Google Chrome and Safari you’ll also see an animation when hovering over the tags.

A small introduction to CSS3

Just before I continue I’ll explain a little about CSS3 assuming you already know how to use CSS. CSS3 is not yet a fixed standard. Many CSS3 functions are available already as browser builders started to add them. Since the standard isn’t fixed, browsers could be implementing the different features just a little different from each other. To make sure these differences will look great on browser A but won’t break on browser B, they are using prefixes.

So when for example we want to use a CSS3 function called css3-example Firefox could use -moz-css3-example (moz stands for Mozilla), Chrome and Safari could use -webkit-css3-example (both use the Webkit engine to render HTML and CSS) and Opera could use -o-css3-example. Notice that I say ‘could use’ in the previous sentence. You should check the browser specific API’s or just try it to make sure a CSS3 function exists for a specific browser.

We also want our site to work in the future too when browsers will have implemented the final standard and removed or deprecated the prefix versions. So you can add a non prefix version as well; css3-example. Or perhaps some other (bad) browser builder may have decided to implement the non prefix version. Of course the standard may change a little but we narrow down the possibility that our CSS3 functions don’t work.

-webkit-css3-example
-moz-css3-example
-o-css3-example
css3-example

For the rest of this tutorial I presume you know how to Google for specific rule implementations and are able to find (browser specific) CSS3 API’s. I won’t go and explain every detail. It is by the way quite some fun to figure this out yourself and it may even… inspire you 😉

Shadows and Rotation

Here’s the CSS3 code that gives the tags (with class=”tag”) shadows and a standard rotation:

.tag {
	/* Shadow under text */
	-webkit-text-shadow: 1px 1px 3px rgb(0,0,0);
	-moz-text-shadow: 1px 1px 3px rgb(0,0,0);
	-o-text-shadow: 1px 1px 3px rgb(0,0,0);
	text-shadow: 1px 1px 3px rgb(0,0,0);

	/* Shadow under tag */
	-webkit-box-shadow: 0 0 10px rgb(0,0,0);
	-moz-box-shadow: 0 0 10px rgb(0,0,0);
	-o-box-shadow: 0 0 10px rgb(0,0,0);
	box-shadow: 0 0 10px rgb(0,0,0);

	/* Rotation transformation */
	-webkit-transform: rotate(-2deg);
	-moz-transform: rotate(-2deg);
	-o-transform: rotate(-2deg);
	transform: rotate(-2deg);
}

For the text and box shadow I used <offset-x> <offset-y> <blur-radius> <color>. The rotation transform is, I think, quite self explanatory. All .tags will be tilted just a little but all the same way. Further on I’ll add scaling to the transformation.

Randomizing trick with Selectors

Now I liked to add some random feel to the tags, like they were added there in a hurry on this virtual pasteboard ;). I also liked all tags to differ a little by discoloring some of them, just like some would have had some more sunshine to endure. This randomized feel can be achieved with the :nth-child selector.

.tag:nth-child(2n) {
	background-color:#8ab9e4;

	-webkit-transform: rotate(2deg);
	-moz-transform: rotate(2deg);
	-o-transform: rotate(2deg);
	transform: rotate(2deg);
}

.tag:nth-child(4n) {
	background-color:#9ab9e4;

	-webkit-transform: rotate(-8deg);
	-moz-transform: rotate(-8deg);
	-o-transform: rotate(-8deg);
	transform: rotate(-8deg);
}

.tag:nth-child(5n) {
	background-color:#9ab9d4;

	-webkit-transform: rotate(-3deg);
	-moz-transform: rotate(-3deg);
	-o-transform: rotate(-3deg);
	transform: rotate(-3deg);
}

We started with the standard .tag css rules which every tag will get. This is a nice starting point for all tags. Now I can pseudo randomize all tags using the :nth-child selector. You can use it like you might know from the :hover pseudo class. Now the rules stated in .tag:nth-child(2n) will apply to every second tag overruling the normal .tag rules, the rules of .tag:nth-child(4n) will apply to fourth tag overruling the normal .tag and the .tag:nth-child(2n) rules and so on. I gave all different :nth-child selector rules a slightly different colour and rotation.

Adding interactivity

Lets add some interactivity with good old :hover.

.tag:nth-child(2n):hover {
	-webkit-transform: rotate(-3deg);
	-moz-transform: rotate(-3deg);
	-o-transform: rotate(-3deg);
	transform: rotate(-3deg);
}

.tag:nth-child(4n):hover {
	-webkit-transform: rotate(3deg);
	-moz-transform: rotate(3deg);
	-o-transform: rotate(3deg);
	transform: rotate(3deg);
}

.tag:nth-child(5n):hover {
	-webkit-transform: rotate(2deg);
	-moz-transform: rotate(2deg);
	-o-transform: rotate(2deg);
	transform: rotate(2deg);
}

Actually nothing really new is going on here. The only thing that might look a little weird is that we now have a selector and just behind it the :hover pseudo class was added. This time I only changed the rotations a little.

Animations with transitions

Now when you check this in your CSS3 enabled browser, you can see the :hover interactivity when you move your mouse pointer over a tag. Wouldn’t it be nice if we could make the switch a little more smooth? Yes, we can… with CSS3 transitions!

(If you’re using Firefox or Opera, now it’s time to switch to Chrome or Safari since this feature isn’t implemented at time of writing this article. It is planned for Firefox 3.7. Opera 10.5 has the support but it renders just too slow to see any difference :(, so Opera has some work to do there).

.tag {
	... see the code above ...

	/* Transition between this and :hover state */
	-webkit-transition: -webkit-transform 0.1s ease-in;
	-moz-transition: -moz-transform 0.1s ease-in;
	-o-transition: -o-transform 0.1s ease-in;
	transition: transform 0.1s ease-in;
}

I added the transition rules to the .tag class rules I already had. You only have to put them in here and not in your :hover rules. When the state of a tag element changes, the transition kicks in and starts to animate between the current state and the new state instead of switching the state immediately. If you want to tweak this more yourself you can read about it on for example this article from Opera.

Embossed text with shadows

Just recently I added something extra. I found a nice embossing example on mozilla’s development centre and thought this could work great for my tag cloud. I updated…

.tag {
	/* Shadow under text */
	-webkit-text-shadow: 1px 1px 3px rgb(0,0,0);
	-moz-text-shadow: 1px 1px 3px rgb(0,0,0);
	-o-text-shadow: 1px 1px 3px rgb(0,0,0);
	text-shadow: 1px 1px 3px rgb(0,0,0);

	... rest of the .tag rules ...

to…

.tag {
	/* Shadow under text */
	-webkit-text-shadow: rgba(0,0,0,0.2) 2px 0,
		rgba(0,0,0,0.2) 0 2px,
		rgba(255,255,255,0.2) -2px 0,
		rgba(255,255,255,0.2) 0 -2px,
		rgba(0,0,0,0.2) 2px 2px,
		rgba(255,255,255,0.2) -2px -2px;
	-moz-text-shadow: rgba(0,0,0,0.2) 2px 0,
		rgba(0,0,0,0.2) 0 2px,
		rgba(255,255,255,0.2) -2px 0,
		rgba(255,255,255,0.2) 0 -2px,
		rgba(0,0,0,0.2) 2px 2px,
		rgba(255,255,255,0.2) -2px -2px;
	-o-text-shadow: rgba(0,0,0,0.2) 2px 0,
		rgba(0,0,0,0.2) 0 2px,
		rgba(255,255,255,0.2) -2px 0,
		rgba(255,255,255,0.2) 0 -2px,
		rgba(0,0,0,0.2) 2px 2px,
		rgba(255,255,255,0.2) -2px -2px;
	text-shadow: rgba(0,0,0,0.2) 2px 0,
		rgba(0,0,0,0.2) 0 2px,
		rgba(255,255,255,0.2) -2px 0,
		rgba(255,255,255,0.2) 0 -2px,
		rgba(0,0,0,0.2) 2px 2px,
		rgba(255,255,255,0.2) -2px -2px;

	... rest of the .tag rules ...

I use 6 shadows with the colors white (top left shadows) and black (bottom right shadows) with transparency. You can do this with the CSS3 rgba(<red>,<green>,<blue>,<alpha>) rule. The alpha channel lets you specify this transparency. The 6 shadows are all positioned differently as you can see behind the rgbarules.

It does look more realistic doesn’t it? Perhaps you’ve noticed that the use of now six shadows gives a little of a performance drop (probably depends on you CPU and/or GPU of course). You could tweak this by removing some shadows till what looks acceptable.

A little more show with Scaling

Now as a final addition I’d like the tags to pop up just a little for making the mouse over effect just a little more dramatic ;). We go back to the :hover rules and add scaling to the transform.

.tag:hover {
	/* Scaling transformation */
	-webkit-transform: scale(1.2);
	-moz-transform: scale(1.2);
	-o-transform: scale(1.2);
	transform: scale(1.2);
}

Conclusion

So there you have it, your very own CSS3 enabled tag cloud! When you experiment with it you can build great new things. You can use more of your imagination. Now just hope Microsoft will soon add some of the features used here in IE9.

If you decide to use this example on your site It would be great if you add a link on your site referring to this article (for the effort I put into the tags and this article ;)). Happy CSS3-ing.

8 gedachten aan “How to create a CSS3 tag cloud like on this blog”

  1. Very nice! Gotta love css3, there is just 1 remark I would like to make, though.
    Chrome somehow ignores the z-index on the hover element. Making it slide below whatever comes next. To fix this you can add a position:relative; to the .tag, I’m unsure on WHY this works, as far as I know, A tags are already positioned relative.. but meh, who cares, it works and doesn’t come with anoying side-effects.

    Keep up the good work!

  2. Nice article. How do you set the tags width? It is a block element, but the width is not 100% but fitted to the text. How do you manage this?

    1. Hi Janos, I guess what you want could be achieved by setting the display mode of the element to block and then explicitly setting width (and height):

      display:block;
      width:300px;
      height:200px;

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *