I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my other blogs

Massive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

A Sass color keyword system for designers. Replaces CSS defaults with improved hues and more memorable, relevant color names.

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.


css / shadows

Estimated reading time: 2 minutes, 56 seconds

In the spirit of past CSS art creations, including the Opera logo and Homer Simpson, I decided to make a simple little something of my own: EVE from the Pixar movie WALL*E.

The markup is fairly straightforward: I’ve used a single relatively positioned div to contain several absolutely positioned div elements that represent EVE (which, following display rules, will be positioned relative to their containing parent div). Every absolutely positioned div, with one exception, is an element in EVE’s body. I’ve also nested the elements, so that moving the eve-body element also moves EVE’s arms, and adjusting the position of her head will shift the faceplate and eyes in concert.

<div id="eve-container">
<div id="eve-body">
<div id="eve-neck"></div>
<div id="eve-leftarm" class="arm"></div>
<div id="eve-rightarm" class="arm"></div>
<div id="eve-head">
<div id="eve-faceplate">
<div class="eye" id="eve-lefteye"></div>
<div class="eye" id="eve-righteye"></div>
<div id="eve-shadow"></div>

I’ve placed EVE’s head “beneath” her body in the markup simply because the browser will visually stack elements in the order they appear in the code, rendering EVE’s head as if it is floating “above” her body. If I wanted slightly more semantic markup, I could position the elements in the more traditional head-neck-body order and change their stacking using z-index.

The one element inside the eve-container div that is not an actual part of EVE is eve-shadow. When we get to the CSS, you’ll see that we don’t actually see the eve-shadow div, but do see its shadow, rendered out via box-shadow. The reason I’ve done this is simple: the gradient effects that I’ve used to shade EVE’s body and neck do not yet feature Gaussian blur, which is necessary to portray a realistic shadow. box-shadow, on the other hand, does.

For the sake of brevity I’ll show just the standard CSS, without vendor prefixes:

div#eve-container { position: relative; width: 200px; height: 600px; margin: 0 auto; }
div#eve-container div { position: absolute; }
div#eve-head { height: 145px; width: 180px;
border-top-left-radius: 90px 85px;
border-top-right-radius: 90px 85px;
border-bottom-left-radius: 90px 60px;
border-bottom-right-radius: 90px 60px;
background-color: #fff; border: 1px solid #999;
div#eve-faceplate { background-color: #000;
width: 150px; height: 95px; bottom: 8px; margin: 0 15px;
border-top-left-radius: 75px 60px;
border-top-right-radius: 75px 60px;
  border-bottom-left-radius: 75px 35px;
border-bottom-right-radius: 75px 35px; }
div.eye { width: 45px; height: 25px;
background-color: #00a; bottom: 25px;
border-top-left-radius: 22px 12px;
border-top-right-radius: 22px 12px;
border-bottom-left-radius: 22px 13px;
border-bottom-right-radius: 22px 13px; 
background: radial-gradient(#5798ce 0%, #000 100%);
div#eve-lefteye { margin-left: 15px; transform: rotate(10deg); } 
div#eve-righteye { margin-left: 85px; transform: rotate(-10deg); }
div#eve-body { width: 180px; height: 220px; top: 152px;
border-bottom-left-radius: 90px 220px;
border-bottom-right-radius: 90px 220px;
border: 1px solid #999; border-top: none;
background: radial-gradient(40px 0, #fff, #fff 70%, #000);
div#eve-neck { width: 180px; height: 60px;
background-color: #fff; top: -30px;
border-radius: 50%; border: 1px solid #999;
background: radial-gradient(90px 65px, #fff, #fff 55%, #888);
div.arm { width: 40px; height: 180px;
background: #fff; border: 1px solid #999; }
div#eve-leftarm { left: -45px;
border-top-left-radius: 30px 50px;
border-top-right-radius: 10px 40px;
border-bottom-left-radius: 30px 130px;
border-bottom-right-radius: 10px 140px;
transform: rotate(10deg);
div#eve-rightarm { left: 180px;
border-top-right-radius: 30px 50px;
border-top-left-radius: 10px 40px;
border-bottom-right-radius: 30px 130px;
border-bottom-left-radius: 10px 140px;
transform: rotate(-10deg); }
div#eve-shadow { width: 180px; height: 60px; top: 300px;
border-radius: 50%;
box-shadow: 0px 100px 30px rgba(0, 0, 0, 0.3); }

What makes CSS-EVE possible is the little-known fact that the border-radius property can take two values: one for the vertical extent of the curve, the other for the horizontal. For an even, semi-circular radius, border-radius takes a single value.

Finally, EVE’s arms and eyes are given a little axial tilt with CSS3 rotate transforms. All of this work is, of course, patently ridiculous: if I truly wanted to create a drawing of EVE on the web that was resolution independent (one of the features of CSS – do try zooming the browser up and down to test it), I’d probably use . I merely wanted to use CSS just to show that it could be done.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.