HTC Desire in CSS3

January 20, 2011

  • The real phone.
  • CSS3-rendered phone, in Firefox 4 beta (screenshot).

But why would you do such a thing?

I was playing about with CSS3, which turned into a larger game when I wanted to see how far it could go.
Of course this whole thing is daft, you should use the right tool for the job and all that - but it was fun :)

Getting started

Let's start with the phone outline.

Step 1

Measuring, it is 11.6cm high and 5.8cm wide. The top and bottom corners have a horizontal curve that extends for 1.5cm and a smaller vertical curve of 0.8cm. The outermost shell is a dark grey: #85969F will do.

<div class="phone"></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; /* dark grey */ }

And we get this.

Notice the border-radius. Our ones here all have the same horizontal and vertical extents so we can use the shorthand; there are lots of ways to specify it and for clarity you can instead specify border-top-left-radius, border-bottom-right-radius etc if you like.

Firefox 3.6 needs -moz-border-radius. The other usual suspects are all quite happy with just border-radius

Step 2

Next let's add the silver/grey/purplish bit (#B3B4BA) that wraps the screen. For lack of inspiration, its class is 'inner'.
Trusty ruler: it is 10.2cm high and its lower border radius is about 12mm horizontally and 4mm vertically.

<div class="phone"><div class="inner"></div></div>
.inner { height: 306px; /* 3 x 102 */ border-bottom-left-radius: 36px 12px; /* horiz 3x12 / vert 3x4 */ border-bottom-right-radius: 36px 12px; /* horiz 3x12 / vert 3x4 */ -moz-border-radius-bottomleft: 36px 12px; /* horiz 3x12 / vert 3x4 */ -moz-border-radius-bottomright: 36px 12px; /* horiz 3x12 / vert 3x4 */ background-color: #B3B4BA; }

Er, wait up.
Those top corners aren't right.
Of course you see what's happened: that 'inner' div is inside the 'phone' div, and by default it has normal, square corners and these are now overlapping its nicely-rounded parent. You can see that if you make the 'inner' div transparent... go on, hover over the image (yep I cheated with an extra style rule for you, setting opacity:0.6 on :hover).

Step 3

Now here's a gotcha. I originally just set the .phone to overflow:hidden, which would simply crop/hide any child content that escaped beyond it. But it turned out that later this messed up with gradients and box-shadows in some browsers (although Firefox 4 beta was fine). I'm sure the others will fix their stuff at some point, but for now it's much easier to just explicitly repeat our top border radiuses:

.inner { border-top-right-radius: 45px 24px; /* horiz 3x15 vert 3x8 */ border-top-left-radius: 45px 24px; /* horiz 3x15 vert 3x8 */ -moz-border-radius-topright: 45px 24px; /* horiz 3x15 vert 3x8 */ -moz-border-radius-topleft: 45px 24px; /* horiz 3x15 vert 3x8 */ }

By the way, notice Firefox 3.6 also uses an older version of the top-right / topright thing.

Step 4

Next: the black screen surround, 5.5 x 9.2 cm, 6mm from the top of the phone. The top corners have a wide horizontal curve, going maybe a third of the way across, and 5mm down. The bottom corners are a balanced 3mm both ways.

<div class="phone"> <div class="inner"> <div class="screen-surround"></div> </div> </div>
.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; }

We use position: relative so we can define this element's offset (in top) from its default position. Normally of course the div would hug the top, just like .inner did before. (See Quirksmode or W3C CSS 2.1 for more).

Notice also that we can use percentages to define the border radius size. Er, apart from Safari/Win and Android it seems. Well in theory we can.

The algorithm for generating the top curve results in a harsher curve than the reality, which is more weighted towards the corners (if you look at the photo) - but never mind, it'll do.

Step 5

The last large structural piece is the screen itself: 4.8 x 8cm, with square corners, 7mm down from the top of the black surround. It can be grey (#333333) for now.

<div class="phone"> <div class="inner"> <div class="screen-surround"> <div class="screen"></div> </div> </div> </div>
.screen { position: relative; top: 21px; /* 3 x 7 */ margin: auto; /* centered */ width: 144px; /* 3 x 48 */ height: 240px; /* 3 x 80 */ background-color: #333; }

Notice that our offset from the top, 7mm (21px) is now measured from the top of the .screen-surround, not the .phone (or .inner). '.screen' is directly inside '.screen-surround', so its natural position would be at the top of .screen-surround... so this offset makes sense.

Also, did you spot that colour shorthand, #abc = #aabbcc? An old one but useful.

That's the basic outline done, and we've managed to avoid using any images.
It's starting to look like a phone, but we can go a lot further.

Next: adding some gradients.

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>