HTC Desire in CSS3 – Part 2

January 20, 2011

(Back to Part 1)

Gradients and Box Shadows

Step 6

Where were we? Code dump, this is how far we've got:

<div class="phone"> <div class="inner"> <div class="screen-surround"> <div class="screen"></div> </div> </div> </div>
.phone { width: 174px; /* 3 x 58 */ height: 348px; /* 3 x 116 */ border-radius: 45px / 24px; /* horiz 3x15 / vert 3x8 */ -moz-border-radius: 45px / 24px; /* horiz 3x15 / vert 3x8 */ background-color: #85969F; }
.inner { height: 306px; /* 3 x 102 */ border-top-right-radius: 45px 24px; /* horiz 3x15 vert 3x8 */ border-top-left-radius: 45px 24px; /* horiz 3x15 vert 3x8 */ border-bottom-left-radius: 36px 12px; /* horiz 3x12 / vert 3x4 */ border-bottom-right-radius: 36px 12px; /* horiz 3x12 / vert 3x4 */ -moz-border-radius-topright: 45px 24px; /* horiz 3x15 vert 3x8 */ -moz-border-radius-topleft: 45px 24px; /* horiz 3x15 vert 3x8 */ -moz-border-radius-bottomleft: 36px 12px; /* horiz 3x12 / vert 3x4 */ -moz-border-radius-bottomright: 36px 12px; /* horiz 3x12 / vert 3x4 */ background-color: #B3B4BA; }
.screen-surround { position: relative; top: 18px; /* 3 x 6 */ margin: auto; /* centered */ border-radius: 9px; /* 3 x 3 */ -moz-border-radius: 9px; /* 3 x 3 */ border-top-left-radius: 33% 15px; /* 3 x 5 */ border-top-right-radius: 33% 15px; -moz-border-radius-topleft: 33% 15px; /* 3 x 5 */ -moz-border-radius-topright: 33% 15px; width: 165px; /* 3 x 55 */ height: 276px; /* 3 x 92 */ background-color: #151515; }
.screen { position: relative; top: 21px; /* 3 x 7 */ margin: auto; /* centered */ width: 144px; /* 3 x 48 */ height: 240px; /* 3 x 80 */ background-color: #333; }

Step 7

In CSS3 we can use a gradient instead of an image. Remember you can write url(myimg.jpg)? Anywhere you could do that, like background-image.

It's easiest to use a helper like the Ultimate CSS Gradient Generator to create your gradients. Then just copy the generated code. It does take some playing around to get the effect you're after.

.phone { background: #969696; /* old browsers */ background: -moz-linear-gradient(top, #969696 0%, #6E6E6E 88%, #AAAAAA 97%, #4B4B4B 98%, #4B4B4B 100%); /* firefox */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#969696), color-stop(88%,#6E6E6E), color-stop(97%,#AAAAAA), color-stop(98%,#4B4B4B), color-stop(100%,#4B4B4B)); /* webkit */ }

This is the gradient:

Opera and IE9 don't support CSS3 gradients yet (they're quite experimental as you can see by the varying syntax).

Step 8

Another gradient to get the shading and 3d effect around the 'inner' light grey area.

.inner { background: #9B9093; /* old browsers */ background: -moz-linear-gradient(top, #9B9093 0%, #E6DFE5 3%, #E6DFE5 4%, #BEB4BA 9%, #BEB4BA 100%); /* firefox */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#9B9093), color-stop(3%,#E6DFE5), color-stop(4%,#E6DFE5), color-stop(9%,#BEB4BA), color-stop(100%,#BEB4BA)); /* webkit */ }

A good tip: to get sharp contrasts/edges and blocks of colour, you can set the same colour at multiple points, and multiple colours at the same point. E.g. black 0%, black 60%, white 60%, white 61%, black 61%, black 100% will give you a simple white line on a black background.

With a linear gradient the effect is not quite as nifty as it could be if it followed the shape of the border.

Step 9

But... actually, we can colour along the curved borders.

One way is, unsurprisingly, using a border-top or border-bottom.

Another is a more exciting new property: box-shadow, which, naturally, appears outside/behind the box. This has the added advantage that it doesn't add to the element size (which border does).

.inner { border-bottom: 2px solid #343638; /* shadow below */ box-shadow: 0 1px 1px #ccc, /* highlight below, matching .phone colour */ 0 2px 3px #333; /* highlight further below, shading .phone */ -webkit-box-shadow: 0 1px 1px #ccc, /* highlight below, matching .phone colour */ 0 2px 3px #333; /* highlight further below, shading .phone */ -moz-box-shadow: 0 1px 1px #ccc, /* highlight below, matching .phone colour */ 0 2px 3px #333; /* highlight further below, shading .phone */ }
.screen-surround { border-top: 1px solid #333; /* darkest top */ box-shadow: 0 -5px 5px #E8E1E7, /* highlight above, */ inset 0 1px 1px #777, /* top inside highlight */ 0 2px 2px #F2EAF1, /* highlight below, */ -1px 0 2px #D3CDD2, /* to left and right, */ 1px 0 2px #E8E1E7; /* matching .inner colour */ -webkit-box-shadow: 0 -5px 5px #E8E1E7, /* highlight above, */ inset 0 1px 1px #777, /* top inside highlight */ 0 2px 2px #F2EAF1, /* highlight below, */ -1px 0 2px #D3CDD2, /* to left and right, */ 1px 0 2px #E8E1E7; /* matching .inner colour */ -moz-box-shadow: 0 -5px 5px #E8E1E7, /* highlight above, */ inset 0 1px 1px #777, /* top inside highlight */ 0 2px 2px #F2EAF1, /* highlight below, */ -1px 0 2px #D3CDD2, /* to left and right, */ 1px 0 2px #E8E1E7; /* matching .inner colour */ }

Using these we can put some highlights and lowlights in the appropriate places.

As you can see, you can define more than one box shadow on the same box. The first two parameters are the shadow offset, the third is the fuzziness, and then the colour (and if you use rgba you can have transparent box shadows). For even more features see: CSS3.info, W3C CSS3.

Chrome - inset box shadows are very buggy, but the fix should be going out soon (it's ok in the dev channel build).
Webkit and Firefox 3.6 also have problems with curved borders - they're meant to transition smoothly between borders of different sizes, but that's not there yet and you get a sharp cutoff. Normal box-shadow is nicely supported by both though, which can give a similar effect.

Step 10

More shininess:

.phone{ border-top: 2px solid #444; /* dark shadow top */ box-shadow: 0 -5px 5px #BFBDBF, /* light shadow above (match .inner), */ inset 0 300px 10px #555, /* top inside shadow shifted below surround */ inset 0 -5px 10px #333, /* below inside shadow, */ 0 1px 2px #777, /* below highlight, */ 2px 5px 2px #111, /* below darkest, */ 5px 10px 10px #999; /* below faint grey */ -webkit-box-shadow: 0 -5px 5px #BFBDBF, /* light shadow above (match .inner), */ inset 0 300px 10px #555, /* top inside shadow shifted below surround */ inset 0 -5px 10px #333, /* below inside shadow, */ 0 1px 2px #777, /* below highlight, */ 2px 5px 2px #111, /* below darkest, */ 5px 10px 10px #999; /* below faint grey */ -moz-box-shadow: 0 -5px 5px #BFBDBF, /* light shadow above (match .inner), */ inset 0 300px 10px #555, /* top inside shadow shifted below surround */ inset 0 -5px 10px #333, /* below inside shadow, */ 0 1px 2px #777, /* below highlight, */ 2px 5px 2px #111, /* below darkest, */ 5px 10px 10px #999; /* below faint grey */ }

Making good use of inset here for some extra shading inside the lower grey area.

Hover over the style rules to see where they're applied: the inset shadow shifted downwards was entirely accidental at first, but looked nifty.

Step 11

Just getting the shading at the top of the phone right.

.inner { box-shadow: 0 1px 1px #ccc, /* highlight below, matching .phone colour */ 0 2px 3px #333, /* highlight further below, shading .phone */ inset -1px 2px 1px #ccc, /* top and right inside highlight */ inset -7px 3px 10px #333, /* top and right dark inside shadow */ inset 0px 7px 5px #6D6B6D; /* top inside shadow, matching .inner */ -webkit-box-shadow: 0 1px 1px #ccc, /* highlight below, matching .phone colour */ 0 2px 3px #333, /* highlight further below, shading .phone */ inset -1px 2px 1px #ccc, /* top and right inside highlight */ inset -7px 3px 10px #333, /* top and right dark inside shadow */ inset 0px 7px 5px #6D6B6D; /* top inside shadow, matching .inner */ -moz-box-shadow: 0 1px 1px #ccc, /* highlight below, matching .phone colour */ 0 2px 3px #333, /* highlight further below, shading .phone */ inset -1px 2px 1px #ccc, /* top and right inside highlight */ inset -7px 3px 10px #333, /* top and right dark inside shadow */ inset 0px 7px 5px #6D6B6D; /* top inside shadow, matching .inner */ }

Summary

Here's the latest phone on a separate page.

We still haven't used any images. Just saying.

But here are some - so you can see how that last one renders in various browsers.

  • Firefox 4 betaLooks best - I used it while developing.
  • Firefox 3.6.13 Border smoothing is missing.
  • Opera 11Gradients missing.
  • IE9Gradients missing.
  • Safari 5.0.3 (Win)Border smoothing and percentages in border-radius are missing.
  • AndroidBorder smoothing and percentages in border-radius are missing.
  • Chrome Dev (10.0.648.11)Border smoothing is missing.
  • Chrome Stable (8.0.552.237)Border smoothing missing. Inset box shadows are broken.
  • IE8Because I know you were curious.

To continue...

But we aren't done yet! On to Part 3.

Leave Your Comment

Your email will not be published or shared. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>