Drawing Things with Box-Shadow

Drawing Things with Box-Shadow

Demo

This post will take 3 minutes to read.

This is a neat little trick that I stumbled upon when playing around with a CSS experiment a few months ago. Basically, by using multiple box-shadows, you can draw complex images with only a single element. As you may know, I’m a big fan of semantic markup, and I really don’t like using extra elements just for styling, so I was very happy with this discovery!

I played around with a few experiments that showcased the potential of this trick. These ranged from favicons, to logos and typefaces. It wasn’t long after posting these experiments on CodePen that I began to see other people using the technique to create awesome things of their own.

It isn’t something that you would normally think to do with box-shadow, and as others are starting to use the technique, I thought I had better share how I do it.

Okay, here’s the trick

Firstly, let’s create a basic element that we will use for this explanation:

<div class="box-shadow-trick"></div>

.box-shadow-trick {
    background: #000;
    height: 10px;
    width: 10px;
}

Alright, now let’s create a basic 4 × 4 checkerboard pattern using that element and the box-shadow property. We will need 15 shadows; a 4 × 4 checkerboard has 16 squares, but one of them will be the element itself. We aren’t going to use blur radius at all, only using the offset values. Here is the relevant code:

box-shadow: 10px 0    0 #f00,
            20px 0    0 #000,
            30px 0    0 #f00,
            0    10px 0 #f00,
            10px 10px 0 #000,
            20px 10px 0 #f00,
            30px 10px 0 #000,
            0    20px 0 #000,
            10px 20px 0 #f00,
            20px 20px 0 #000,
            30px 20px 0 #f00,
            0    30px 0 #f00,
            10px 30px 0 #000,
            20px 30px 0 #f00,
            30px 30px 0 #000;

So you can see that it isn’t too difficult to make copies of an element, and to position them wherever you would like. It can get even more interesting when you begin to use box-shadow’s optional spread value. The obvious downside to this technique is that it is a fair bit of code, but that shouldn’t be an issue for experiments.

We can also use gradients to draw things

The demo linked to at the top of this article showcases an experiment that uses both gradients and box-shadows to create a MacBook Pro using only a single element. You can use gradients on their own to create icons or slightly more advanced logos. The principle is the same: use multiple backgrounds (i.e. linear and radial gradients), and then use the other background properties such as repeat, position and size to get the effect you want.

Another nifty trick

Box-shadows, when used with transparent backgrounds, can produce some cool effects. Here is an example of what I’m talking about.

Word of warning

The techniques outlined in this article are a lot of fun, but they really shouldn’t be used in production. They are a nifty way to produce semantic CSS experiments, but they don’t have full browser support. Also, the box-shadow property can be one of the slowest to render, especially if you are chaining together tens, or even hundreds, of shadows!

Your turn

Now that you know my little secret, it’s your turn to get out there and experiment. I want to see what you guys can come up with! Leave your links for me in the comments. If I get enough, I’ll add them to the post.

Updates

Emad Elsaid has cleverly developed an image to box-shadow converter, so now you can make things like this! Keep in mind that it pumps out an incredible amount of shadows, so don’t use large images!

Also, Hugo Giraudel has hand drawn this incredible piece.

Thanks to a request from Paul Irish, I have also created this little piece of internet history.

If you are interest in seeing me tweak one of these experiments, you can check out this screencast.

Tweet this

9 Comments

  1. Benjamin Knight

    This is neat to look at (kudos and all) but the code to produce this is totally opaque and not what CSS is really meant for.

  2. Josh

    Benjamin, you are absolutely right, and that is why I made sure to write a paragraph explaining that the technique shouldn’t be used in production.

    François, I usually do use ems instead of px, but sometimes using ems can cause funny things to happen when resizing, especially when using multiple gradients.

  3. Thomas

    Hi Josh!
    The technique is funny :)
    But i am wondering the difference with the data-uri.
    We can already do that with data-uri and it is probably more compatible and faster.
    See you,
    Thomas.

  4. Josh

    Great question, Thomas.

    The technique I have described in this post is one that uses CSS to create images whereas a data URI embeds actual image data as though it were loading an external source. Simply including a data URI in CSS does not make it CSS.

    With that being said, the technique mentioned in this article is experimental, and not appropriate for production (as explained in the article), you would be better off using actual images, or data URIs.