Today I’m going to show you how to create a flat, long-shadow icon with the CSS3 text-shadow property. If you’re unfamiliar with the text-shadow property, it takes 4 values:

Value 1 = The X-coordinate Value 2 = The Y-coordinate Value 3 = The blur radius Value 4 = The color of the shadow in hex or rgba

Before we get into the long shadow, let’s create our container, icon box, and icon text. The container doesn’t actually require any styling for this effect to work, but we’ll add a little to it for demo purposes.

CSS

.container { padding: 50px; background: rgb(34,45,58); }

HTML

<div class="container"></div>

The CSS Explained

I’ve set the background color of the container to a dark grey (#222D3A) .

. I also added some padding so our icon isn’t right against the edge of the browser window.

Setting Up the Icon

The next thing I’ll do is show you how to setup an icon box that is going to hold the text. I’ll call this class .icon.

CSS

.icon { font-family: "Helvetica Neue", helvetica, arial, sans-serif; font-weight: bold; color: #fff; background-color: rgb(22, 160, 133); /* teal */ height: 150px; width: 150px; font-size: 75px; line-height: 150px; text-align: center; display: block; overflow: hidden; }

HTML

<div class="container"> <div class="icon">YO</div> </div>

The CSS Explained

I’ve set the font-family as Helvetica Neue as I find this effect works best with a sans-serif font.

as I find this effect works best with a sans-serif font. I also set the font-weight to bold as it helps with the effect.

to as it helps with the effect. The type color, within the icon, is set to white (#fff) .

. The background color is set to Teal rgb(22, 160, 133) with the rgba color value.

with the color value. I’ve set the height and width to 150px . This size works well for the effect, but feel free to tweak this.

and to . This size works well for the effect, but feel free to tweak this. I’ve set the font-size to half of the size of the box. This is important so that the text can be centered horizontally and vertically to appear like an icon.

to half of the size of the box. This is important so that the text can be centered horizontally and vertically to appear like an icon. Setting the line-height equal to the height of the box will center it vertically.

equal to the height of the box will center it vertically. Setting the overflow property to hidden is a critical step in creating the icon. This will crop the long shadow so it doesn’t exceed the edges of your box.

Once you’ve completed all these steps, you’re icon should look like this:

Adding the Long Shadow

The last step is to add the long shadow to the text within our box using the text-shadow property. The trick to achieving this effect is to create a large number of text-shadow steps. Each step is offset vertically and horizontally by 1 pixel until it is outside the radius of the box. For the purposes of this demo, we are going to use 100 steps. That will run the shadow far enough outside of the box so that when it’s cropped it will appear to be running into the inside edge of the icon. 100 steps might sound like a lot, however, you can copy and paste my code, then use find and replace to update the color value.

CSS

.icon { font-family: "Helvetica Neue", helvetica, arial, sans-serif; font-weight: bold; color: #fff; background-color: rgb(22, 160, 133); /* teal */ height: 150px; width: 150px; font-size: 75px; line-height: 150px; text-align: center; display: block; overflow: hidden; text-shadow: rgb(18, 128, 106) 1px 1px, rgb(18, 128, 106) 2px 2px, rgb(18, 128, 106) 3px 3px, rgb(18, 128, 106) 4px 4px, rgb(18, 128, 106) 5px 5px, rgb(18, 128, 106) 6px 6px, rgb(18, 128, 106) 7px 7px, rgb(18, 128, 106) 8px 8px, rgb(18, 128, 106) 9px 9px, rgb(18, 128, 106) 10px 10px, rgb(18, 128, 106) 11px 11px, rgb(18, 128, 106) 12px 12px, rgb(18, 128, 106) 13px 13px, rgb(18, 128, 106) 14px 14px, rgb(18, 128, 106) 15px 15px, rgb(18, 128, 106) 16px 16px, rgb(18, 128, 106) 17px 17px, rgb(18, 128, 106) 18px 18px, rgb(18, 128, 106) 19px 19px, rgb(18, 128, 106) 20px 20px, rgb(18, 128, 106) 21px 21px, rgb(18, 128, 106) 22px 22px, rgb(18, 128, 106) 23px 23px, rgb(18, 128, 106) 24px 24px, rgb(18, 128, 106) 25px 25px, rgb(18, 128, 106) 26px 26px, rgb(18, 128, 106) 27px 27px, rgb(18, 128, 106) 28px 28px, rgb(18, 128, 106) 29px 29px, rgb(18, 128, 106) 30px 30px, rgb(18, 128, 106) 31px 31px, rgb(18, 128, 106) 32px 32px, rgb(18, 128, 106) 33px 33px, rgb(18, 128, 106) 34px 34px, rgb(18, 128, 106) 35px 35px, rgb(18, 128, 106) 36px 36px, rgb(18, 128, 106) 37px 37px, rgb(18, 128, 106) 38px 38px, rgb(18, 128, 106) 39px 39px, rgb(18, 128, 106) 40px 40px, rgb(18, 128, 106) 41px 41px, rgb(18, 128, 106) 42px 42px, rgb(18, 128, 106) 43px 43px, rgb(18, 128, 106) 44px 44px, rgb(18, 128, 106) 45px 45px, rgb(18, 128, 106) 46px 46px, rgb(18, 128, 106) 47px 47px, rgb(18, 128, 106) 48px 48px, rgb(18, 128, 106) 49px 49px, rgb(18, 128, 106) 50px 50px, rgb(18, 128, 106) 51px 51px, rgb(18, 128, 106) 52px 52px, rgb(18, 128, 106) 53px 53px, rgb(18, 128, 106) 54px 54px, rgb(18, 128, 106) 55px 55px, rgb(18, 128, 106) 56px 56px, rgb(18, 128, 106) 57px 57px, rgb(18, 128, 106) 58px 58px, rgb(18, 128, 106) 59px 59px, rgb(18, 128, 106) 60px 60px, rgb(18, 128, 106) 61px 61px, rgb(18, 128, 106) 62px 62px, rgb(18, 128, 106) 63px 63px, rgb(18, 128, 106) 64px 64px, rgb(18, 128, 106) 65px 65px, rgb(18, 128, 106) 66px 66px, rgb(18, 128, 106) 67px 67px, rgb(18, 128, 106) 68px 68px, rgb(18, 128, 106) 69px 69px, rgb(18, 128, 106) 70px 70px, rgb(18, 128, 106) 71px 71px, rgb(18, 128, 106) 72px 72px, rgb(18, 128, 106) 73px 73px, rgb(18, 128, 106) 74px 74px, rgb(18, 128, 106) 75px 75px, rgb(18, 128, 106) 76px 76px, rgb(18, 128, 106) 77px 77px, rgb(18, 128, 106) 78px 78px, rgb(18, 128, 106) 79px 79px, rgb(18, 128, 106) 80px 80px, rgb(18, 128, 106) 81px 81px, rgb(18, 128, 106) 82px 82px, rgb(18, 128, 106) 83px 83px, rgb(18, 128, 106) 84px 84px, rgb(18, 128, 106) 85px 85px, rgb(18, 128, 106) 86px 86px, rgb(18, 128, 106) 87px 87px, rgb(18, 128, 106) 88px 88px, rgb(18, 128, 106) 89px 89px, rgb(18, 128, 106) 90px 90px, rgb(18, 128, 106) 91px 91px, rgb(18, 128, 106) 92px 92px, rgb(18, 128, 106) 93px 93px, rgb(18, 128, 106) 94px 94px, rgb(18, 128, 106) 95px 95px, rgb(18, 128, 106) 96px 96px, rgb(18, 128, 106) 97px 97px, rgb(18, 128, 106) 98px 98px, rgb(18, 128, 106) 99px 99px, rgb(18, 128, 106) 100px 100px; }

HTML

<div class="container"> <div class="icon">YO</div> </div>

The CSS Explained

At the top of our long list of values, I’ve inserted the the text-shadow property.

property. I’ve set the color to a darker version of the teal background so it looks like a shadow.

Notice that the color stays the same on each step, it’s only the X and Y coordinates that are changing.

Make sure you insert a comma after each value declaration.

Once you’ve added the text-shadow code into the .icon class, you’re icon is complete. Here’s what it should look like.

Further Customization

The reason the color values stay the same is because I wanted to create a flat icon. If you wanted to create a gradient shadow, you could enter different color values that cross a spectrum, creating a gradient. You could also add opacity to the shadow with rgba() if you want the shadow to be transparent. If you were to decrease the size of the icon box, less steps would be required. Play around with some of the sizing properties to see what I mean.

Reversing the Shadow

By default, the shadow will flow from left to right. If you’d like to reverse the direction of the shadow, you can use negative pixel values for the X and Y coordinates. This will run the shadow from right to left.

CSS

.icon { ... text-shadow: rgb(18, 128, 106) -1px -1px, rgb(18, 128, 106) -2px -2px, rgb(18, 128, 106) -3px -3px, ... }

Live Demo

There is a live demo of this effect available over at jsfiddle.

If you’re interested in learning more about CSS3, check out my eBook the CSS3 Handbook.