Download Demo

3D Text in Just CSS?

This is a little effect I’ve been working on for a few hours, I thought it was pretty neat! So we’re going to make 3D text with just CSS3. We’ll be looking at the CSS pseudo class :before.

So first what we need to do is pick the font we’re going to use! I’m using Istok which is available from Google Web Fonts. You can include it in the head like this:

<link href='http://fonts.googleapis.com/css?family=Istok+Web:700' rel='stylesheet' type='text/css'>

Next we’ll add some simple HTML to get things working

	<div class="text">
		
		<span>Text you want here</span>
		
	</div>

Currently the mask effect only works in Webkit browsers like Chrome and Safari, but the rest of these effects work in Firefox as well!

CSS

Now the :before pseudo element doesn’t actually create a physical element, but places whatever you want before the element you apply it to. We want it to act like a shadow, so we want it to appear below the original text layer. First off, lets apply some styles to the .text element.

.text {
	font-size: 120px;
	font-weight: bold;
	font-family: 'Istok Web', Helvetica, sans-serif;
	position: relative;
	color: #fff;
}

We apply an absolute position to the span, and change its z-index (that’s basically what layer its on) to 2, so it’ll be above everything else.


.text span {
	position: absolute;
	z-index: 2;
	-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, 
	color-stop(0.29, rgba(0,0,0,0)), color-stop(0.65, rgba(225,225,225,1))
	);
}

Notice we’re applying mask-image, which is only supported by webkit. It’ll let us get the effect we’re looking for, in Safari and Chrome anyway. All other browsers will just ignore that line.

Finally we’re just going apply some styles to the :before psuedo class. Now you may have noticed that the top of the text is now transparent. To fix that we’re going to use the :after pseudo class to place another bit of text directly below the original.

.text:before {
	content: "Quickly! Hurry!";
	position: absolute;
	top: 4px;
	color: #aaa;
	text-shadow: 0px 5px 10px rgba(0,0,0,0.5);
}

.text:after {
	content: "Quickly! Hurry!";
	color: #e0e0e0;
	position: absolute;	
}

The content is whatever we want to appear before. We’ve positioned them absolutely, so it’ll stay on top of the original text. Then we just move it down by 4px, change the colour and add a text shadow. You can alter the colour and everything, to make it look nicer! Check out the Preview below to see!

<!DOCTYPE html>
<head>

	<title>CSS Text</title>
	<link href='http://fonts.googleapis.com/css?family=Istok+Web:700' rel='stylesheet' type='text/css'>
	
	<style type="text/css"> 
		
		body {
			background: url('noise.png');
			margin: 100px;	
		}
		
		/* Heights to correct for multiple texts
		   You might not need this */
		
		.text, .text_2 { height: 200px; }
		
		/* END */ 		
		
		.text {
			font-size: 120px;
			font-weight: bold;
			font-family: 'Istok Web', Helvetica, sans-serif;
			position: relative;
			color: #fff;
		}
		
		.text span {
			position: absolute;
			z-index: 2;
			-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, 
			color-stop(0.29, rgba(0,0,0,0)), color-stop(0.65, rgba(225,225,225,1))
			);
		}
		.text:before {
			content: "Quickly! Hurry!";
			position: absolute;
			top: 4px;
			color: #aaa;
			text-shadow: 0px 5px 10px rgba(0,0,0,0.5);
		}
		.text:after {
			content: "Quickly! Hurry!";
			color: #e0e0e0;
			position: absolute;
		}
		
		
		/* --------------------- */
		/* For different colours */
		/* --------------------- */
		
		.text_2 {
			font-size: 120px;
			font-weight: bold;
			font-family: 'Istok Web', Helvetica, sans-serif;
			position: relative;
		}
		
		.text_2 span {
			position: absolute;
			z-index: 2;
			color: #409dcd;
			-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, 
			color-stop(0.29, rgba(0,0,0,0)), color-stop(0.65, rgba(225,225,225,1))
			);
		}
		.text_2:before {
			content: "You're Pretty";
			position: absolute;
			top: 4px;
			color: #2d426a;
			text-shadow: 0px 5px 10px rgba(0,0,0,0.5);
		}
		
		.text_2:after {
			content: "You're Pretty";
			color: #66b5de;
			position: absolute;
		}
		
				
	</style>
	
</head>
<body>
	
	<div class="text">
		
		<span>Quickly! Hurry!</span>
		
	</div>
	
	<div class="text_2">
		
		<span>You're Pretty</span>
		
	</div>
	
</body>
</html>