Drawing Things with Box-Shadow

Drawing Things with Box-Shadow

Demo

This is a neat little trick that I stumbled upon when play­ing around with a CSS exper­i­ment a few months ago. Basically, by using mul­tiple box-shadows, you can draw com­plex images with only a single ele­ment. As you may know, I’m a big fan of semantic markup, and I really don’t like using extra ele­ments just for styl­ing, so I was very happy with this discovery!

I played around with a few exper­i­ments that show­cased the poten­tial of this trick. These ranged from favicons, to logos and typefaces. It wasn’t long after post­ing these exper­i­ments on CodePen that I began to see other people using the tech­nique to cre­ate awe­some things of their own.

It isn’t some­thing that you would nor­mally think to do with box-shadow, and as oth­ers are start­ing to use the tech­nique, I thought I had bet­ter share how I do it.

Okay, here’s the trick

Firstly, let’s cre­ate a basic ele­ment 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 cre­ate a basic 4 × 4 check­er­board pat­tern using that ele­ment and the box-shadow prop­erty. We will need 15 shad­ows; a 4 × 4 check­er­board has 16 squares, but one of them will be the ele­ment itself. We aren’t going to use blur radius at all, only using the off­set val­ues. Here is the rel­ev­ant 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 dif­fi­cult to make cop­ies of an ele­ment, and to pos­i­tion them wherever you would like. It can get even more inter­est­ing when you begin to use box-shadow’s optional spread value. The obvi­ous down­side to this tech­nique is that it is a fair bit of code, but that shouldn’t be an issue for experiments.

We can also use gradi­ents to draw things

The demo linked to at the top of this art­icle show­cases an exper­i­ment that uses both gradi­ents and box-shadows to cre­ate a MacBook Pro using only a single ele­ment. You can use gradi­ents on their own to cre­ate icons or slightly more advanced logos. The prin­ciple is the same: use mul­tiple back­grounds (i.e. lin­ear and radial gradi­ents), and then use the other back­ground prop­er­ties such as repeat, pos­i­tion and size to get the effect you want.

Another nifty trick

Box-shadows, when used with trans­par­ent back­grounds, can pro­duce some cool effects. Here is an example of what I’m talk­ing about.

Word of warning

The tech­niques out­lined in this art­icle are a lot of fun, but they really shouldn’t be used in pro­duc­tion. They are a nifty way to pro­duce semantic CSS exper­i­ments, but they don’t have full browser sup­port. Also, the box-shadow prop­erty can be one of the slow­est to render, espe­cially if you are chain­ing together tens, or even hun­dreds, of shadows!

Your turn

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

Updates

Emad Elsaid has clev­erly developed an image to box-shadow con­verter, so now you can make things like this! Keep in mind that it pumps out an incred­ible amount of shad­ows, so don’t use large images!

Also, Hugo Giraudel has hand drawn this incred­ible piece.

Thanks to a request from Paul Irish, I have also cre­ated this little piece of inter­net his­tory.

If you are interest in see­ing me tweak one of these exper­i­ments, you can check out this screen­cast.

Tweet this

Comments

  1. Benjamin Knight

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

  2. Josh

    Benjamin, you are abso­lutely right, and that is why I made sure to write a para­graph explain­ing that the tech­nique shouldn’t be used in production.

    François, I usu­ally do use ems instead of px, but some­times using ems can cause funny things to hap­pen when res­iz­ing, espe­cially when using mul­tiple gradients.

  3. Thomas

    Hi Josh!
    The tech­nique is funny :)
    But i am won­der­ing the dif­fer­ence with the data-uri.
    We can already do that with data-uri and it is prob­ably more com­pat­ible and faster.
    See you,
    Thomas.

  4. Josh

    Great ques­tion, Thomas.

    The tech­nique I have described in this post is one that uses CSS to cre­ate images whereas a data URI embeds actual image data as though it were load­ing an external source. Simply includ­ing a data URI in CSS does not make it CSS.

    With that being said, the tech­nique men­tioned in this art­icle is exper­i­mental, and not appro­pri­ate for pro­duc­tion (as explained in the art­icle), you would be bet­ter off using actual images, or data URIs.