How to Create a CSS3 3D Text Plugin for jQuery

Contributing Editor

In my previous post, we created 3D text in CSS3 using multiple text-shadows. It may have been effective, but generating the effect was a tedious trial-and-error exercise.

We’re going to make life a little easier with a jQuery plugin. It will do the hard work and generate long-winded CSS3 code such as:


text-shadow:
	-1px 1px 0 #ddd,
	-2px 2px 0 #c8c8c8,
	-3px 3px 0 #ccc,
	-4px 4px 0 #b8b8b8,
	-4px 4px 0 #bbb,
	0px 1px 1px rgba(0,0,0,.4),
	0px 2px 2px rgba(0,0,0,.3),
	-1px 3px 3px rgba(0,0,0,.2),
	-1px 5px 5px rgba(0,0,0,.1),
	-2px 8px 8px rgba(0,0,0,.1),
	-2px 13px 13px rgba(0,0,0,.1)
	;
note: Is this wise?

Our jQuery plugin uses JavaScript to apply a CSS3 style. You’d normally avoid doing that since it’s be slower and, without JavaScript, the user won’t see the effect.

However, the 3D is unlikely to be essential and the plugin will save a significant number of development hours. If you still feel dirty, copy the generated text-shadow property from Firebug into your static CSS file.

Head over to the plugin demonstration page to view examples and download the code.

How to Use the Plugin

jQuery and the plugin should be included on your page — ideally just before the closing </body> tag, e.g.


<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="jquery.text3d.js"></script>

To apply a default 3D effect, set a class of “text3d” to any HTML element, e.g.


<p class="text3d">3D Text</p>

Alternatively, you can specify custom 3D effects for any number of elements in JavaScript, e.g.


<script>
$("#custom").text3d({
	depth: 6,
	angle: 135,
	color: "#aaa",
	lighten: -0.1,
	shadowDepth: 30,
	shadowAngle: 45,
	shadowOpacity: 0.2
});
</script>

Where:

  • depth is the number of pixels for the 3D extrusion
  • angle is the 3D extrude angle, i.e. 90 is vertically downward
  • color is the 3D extrusion color
  • lighten is the difference in color between the top and bottom of the extrusion, e.g. -0.1 means the color will darken by 10%
  • shadowDepth is the approximate number of pixels the shadow extends from the text
  • shadowAngle is the angle at which the shadow falls
  • shadowOpacity is the initial opacity between 0 (no shadow) and 1 (dark black). Note that multiple shadows overlay one another so you’ll rarely need a number greater than 0.4.

The jQuery Plugin Code

Our JavaScript template will be familiar to anyone who has written or used a jQuery plugin:


(function($) {

	// jQuery plugin definition
	$.fn.text3d = function(opts) {
	
		// default configuration
		var config = $.extend({}, {
			depth: 5,
			angle: 100,
			color: "#ddd",
			lighten: -0.15,
			shadowDepth: 10,
			shadowAngle: 80,
			shadowOpacity: 0.3
		}, opts);
		
		// to radians
		config.angle = config.angle * Math.PI / 180;
		config.shadowAngle = config.shadowAngle * Math.PI / 180;
		
		// ... main code ...
		
		// initialization
		this.each(function() {
			TextShadow(this);
		});

		return this;
	};

})(jQuery);

The config object is defined with a set of default properties which can be overridden. angle and shadowAngle assume degrees so these are converted to radians. Each HTML element within the jQuery selector is passed to a TextShadow() function…


// create text shadow
function TextShadow(e) {

	var s = "", i, f, x, y, c;
	
	// 3D effect
	for (i = 1; i <= config.depth; i++) {
		x = Math.round(Math.cos(config.angle) * i);
		y = Math.round(Math.sin(config.angle) * i);
		c = ColorLuminance(config.color, (i-1)/(config.depth-1)*config.lighten);
		s += x+"px "+y+"px 0 "+c+",";
	}
	
	// shadow
	for (f = 1, i = 1; f <= config.shadowDepth; i++) {
		f = f+i;
		x = Math.round(Math.cos(config.shadowAngle) * f);
		y = Math.round(Math.sin(config.shadowAngle) * f);
		c = config.shadowOpacity - ((config.shadowOpacity - 0.1) * i/config.shadowDepth);
		s += x+"px "+y+"px "+f+"px rgba(0,0,0,"+c+"),";
	}
	
	e.style.textShadow = s.substr(0, s.length-1);		
}

The function builds a text-shadow string using the defined parameters and applies it to the current element. Note that the 3D extrusion colors are generated using a ColorLuminance() function — refer to How to Calculate Lighter or Darker Hex Colors in JavaScript for more information.

Finally, the following code is included at the end of our plugin file to apply the default 3D effect to all elements with the “text3d” class.


jQuery(function() {
	jQuery(".text3d").text3d();
});

I hope you find it useful. As the demonstration page illustrates, CSS3 transitions can also be adopted to create 3D animations.

If you create any interesting examples, please post your URLs in the comments section below.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Mike Staples

    Did you mention that it doesn’t work in any version IE?

    • http://www.optimalworks.net/ Craig Buckler

      That’s not quite true – IE10 is fine!

      But seriously, it was mentioned in the last post. IE9 and below don’t support CSS3 text-shadow so the 3D effect won’t be applied.