Pure CSS Shapes: Triangles, Delicious Logo, and Hearts

After reading through Smashing Magazine’s latest article, 50 New CSS Techniques For Your Next Web Design, I came across an article glossing over a technique for creating a triangle using pure CSS. A triangle using just CSS? That blew my mind! How is that even possible?

After playing around with the sample CSS I started to get it. Using an empty HTML element and the border properties, you can make all kinds of shapes. Here is how it works.

Note: As expected, Internet Explorer acts a bit wonky especially IE6. These experiments were done in Firefox 3.5 but you can see what they should look like in a screenshot I took.

Per the box model, the border outlines the perimeter of an element. When an element has a width and height of 0px the border-width’s make up the dimensions of the element.The corners of borders meet at a 45° angle which is apparent with larger border widths and what makes pure CSS shapes possible. The final CSS to make a 200 pixel tall red triangle pointing up looks like this:

But let’s see how we got to this conclusion step by step starting with a basic square and borders. Each border will be given a different color so we can tell them apart.

.triangle {
border-color: yellow blue red green;
border-style: solid;
border-width: 200px 200px 200px 200px;
height: 0px;
width: 0px;

We won’t need the top border so we can set its width to 0px. This makes our triangle easy to measure without any extra space on top; a border-bottom value of 200px will result in a triangle that is 200px tall.

.triangle {
border-color: yellow blue red green;
border-style: solid;
border-width: 0px 200px 200px 200px;
height: 0px;
width: 0px;

To hide the two side triangles we set the border-color to transparent. If we set the border-left and border-right widths to 0px then the whole shape would collapse, leaving us with nothing. Since the top-border has been effectively deleted, we can set the border-top-color to transparent as well.

 .triangle {
border-color: transparent transparent red transparent;
border-style: solid;
border-width: 0px 200px 200px 200px;
height: 0px;
width: 0px;

There you have it; a triangle using only a single, empty HTML element and some CSS. The same technique can be applied to the other three sides for different orientations. Where might this come in handy? A JavaScript toggle to indicate a container is visible comes to mind. And using a pure CSS triangle is a lot more convenient than coming up with new images for each variation.

Try playing around with different widths to create different kinds of triangles. You can also get some funky effects by changing the border-style; dotted produces a neat effect on our regular bordered square.

.funkyShape {
border-color: yellow blue red green;
border-style: dotted;
border-width: 200px 200px 200px 200px;
height: 0px;
width: 0px;

I even managed to come up with the del.icio.us logo.

.delicious {
border-color:#FFFFFF #3274D0 #D3D2D2 #000000;

And a heart shape.

.heart {
border-width:0 150px 150px 0;

I wasn’t the first one to explore CSS shapes, it turns out Tantek Çelik was playing around with these ideas way back in 2001.

IE Gets A CSS Rule Right

Web developers like to rag on Microsoft’s Internet Explorer every chance they get due it’s sub-par support for HTML/CSS standards. But one thing Microsoft did get right was support for background-position-x and background-position-y. The background-position property lets you control the placement of the background image of an element. Background-position-x and background-position-y let you control the placement independently.

What are some practical uses of controlling the background position independently? Take a card game, for example. Instead of assigning a separate background image for each card you could make a single image that has all the cards in a grid (see below). To show every card you would only need 18 classes: 1 for the common card styles, 4 for the background position of each suit, and 13 for the background position of each value (Ace, two, three etc.)

The CSS for the image above would look like this…

.card {
/* Suites */
.clubs { background-position-y:0%; }
.diamonds { background-position-y:25%; }
.hearts { background-position-y:50%; }
.spades { background-position-y:75%; }
/* Values */
.ace { background-position-x:0%; }
.two { background-position-x:7.5%; }
.three { background-position-x:7.5%; }
.four { background-position-x:7.5%; }
.five { background-position-x:7.5%; }
/* etc. */

The HTML would be simple, elegant, and look like this:

<a class="card hearts five">Five of Hearts</a>
<a class="card spade jack">Jack of Spades</a>

Alas if only life were that simple. Currently only IE 5.0+ and Safari 1.2+ support background-position-x and background-position-y. Every other browser ignores the properties, defaulting to the upper left position.

Instead this is how the CSS code would look if you were writing it for support with all browsers…

/* clubs */ 
.ace-clubs { background-position:0% 0%; }
.two-clubs { background-position:7.5% 0%; }
.three-clubs { background-position:15% 0%; }
.four-clubs { background-position:22.5% 0%; }
.five-clubs { background-position:30% 0%; }
.six-clubs { background-position:37.5% 0%; }
.seven-clubs { background-position:45% 0%; }
.eight-clubs { background-position:52.5% 0%; }
.nine-clubs { background-position:60% 0%; }
.ten-clubs { background-position:67.5% 0%; }
.jack-clubs { background-position:75% 0%; }
.queen-clubs { background-position:82.5% 0%; }
.king-clubs { background-position:90% 0%; }
/* spades */ 
.ace-spades { background-position:0% 25%; }
.two-spades { background-position:7.5% 25%; }
.three-spades { background-position:15% 25%; }
.four-spades { background-position:22.5% 25%; }
.five-spades { background-position:30% 25%; }
.six-spades { background-position:37.5% 25%; }
.seven-spades { background-position:45% 25%; }
.eight-spades { background-position:52.5% 25%; }
.nine-spades { background-position:60% 25%; }
.ten-spades { background-position:67.5% 25%; }
.jack-spades { background-position:75% 25%; }
.queen-spades { background-position:82.5% 25%; }
.king-spades { background-position:90% 25%; }
/* hearts */ 
.ace-hearts { background-position:0% 50%; }
.two-hearts { background-position:7.5% 50%; }
.three-hearts { background-position:15% 50%; }
.four-hearts { background-position:22.5% 50%; }
.five-hearts { background-position:30% 50%; }
.six-hearts { background-position:37.5% 50%; }
.seven-hearts { background-position:45% 50%; }
.eight-hearts { background-position:52.5% 50%; }
.nine-hearts { background-position:60% 50%; }
.ten-hearts { background-position:67.5% 50%; }
.jack-hearts { background-position:75% 50%; }
.queen-hearts { background-position:82.5% 50%; }
.king-hearts { background-position:90% 50%; }
/* diamonds */ 
.ace-diamonds { background-position:0% 75%; }
.two-diamonds { background-position:7.5% 75%; }
.three-diamonds { background-position:15% 75%; }
.four-diamonds { background-position:22.5% 75%; }
.five-diamonds { background-position:30% 75%; }
.six-diamonds { background-position:37.5% 75%; }
.seven-diamonds { background-position:45% 75%; }
.eight-diamonds { background-position:52.5% 75%; }
.nine-diamonds { background-position:60% 75%; }
.ten-diamonds { background-position:67.5% 75%; }
.jack-diamonds { background-position:75% 75%; }
.queen-diamonds { background-position:82.5% 75%; }
.king-diamonds { background-position:90% 75%; }

That’s a class for each card or 52 for those following along at home. Bloat city.

So kudos to Microsoft for letting developers be flexible in at least one area. Now if all the other CSS properties were as flawless as this we would be in business.

Walkthrough: Setup Multiple IE Virtual Machines On A Mac

One of the most dreaded tasks every web developer faces is testing their pages in the multitude of browsers to make sure everything is working as it should. Until recently, that required having multiple systems lying around. Microsoft only let you install one version of Internet Explorer (IE) at a time due to the fact that it is built deep into the system kernel. Apple used to keep Safari to itself on the Mac operating system leaving the only option of buying Apple hardware to get at the browser.

While there have been several stand-alone versions of IE cobbled together, I just don’t trust them like a fresh native install. And it’s good to see how a site renders with the text rendering engine of the Mac versus the Windows rendering system. Now with virtualization tools like VMWare Fusion, we can have it all.

After installing VMWare and an instance of Windows you may be tempted to set-up another virtual machine specifically for another version of IE. But this is foolish because each XP virtual machine can take up a good chunk of harddrive space. Fortunately there is another way to accomplish this while saving a heap of space.

Below are the steps I took to download the free Virtual Disk images that Microsoft provides with a bare minimum installation of XP or Vista and IE6, IE7, or IE8 Beta. All that we need to do is convert them to a format that VMWare can use and we’ll be in business. The basis of this walkthrough came from Running IE6, IE7 and IE8 on your Mac by Jeremy Gillick. So let’s dive in…

  1. Go and download the version(s) of IE that you want from Microsoft. This can be anywhere from 330MB – 3GB
  2. Download Qemu-0.9.1-windows.zip. We’ll use this to convert the Virtual PC disk images to a VMWare compatible virtual disk.
  3. Start up your virtual XP machine and drag the two files onto the XP desktop.
  4. Un-zip Qemu-0.9.1-windows.zip to your C:/ drive so it will be easier to find later.
  5. Speaking of making things easier, it would help to rename the folder Qemu-0.9.1-windows to qmenu. This will come in handy later when we are typing up a storm on the command line.

    The file structure of qmenu.

  6. Double click IE7-XPSP2_VPC.EXE to extract the image. Save it to C:\qmenu. You should now see a .vhd file in your qmenu folder. Size wise it should be a little over a gig.
  7. Again, to make things easier to type later we shall rename XP SP2 with IE7.vhd to XPSP2IE7.vhd

    Renaming the VHD file for simplicity.

  8. Now it’s time to do the conversion via the command line. Fire it up by going to Start -> Run and typing cmd. Then press enter to launch the command line.
  9. Navigate to the qmenu directory by typing cd c:\qmenu
  10. Now type this line to run the actual conversion process: bin\qemu-img.exe convert -f vpc C:\qmenu\XPSP2IE7.vhd -O vmdk XPIE7.vmdk

    This is what you should type into the command line to convert your image.

  11. You will know it is working because all you will see is a blinking cursor on a new line. The amount of time it takes to finish converting can be anywhere between 10 minutes and an hour depending on your CPU.
  12. When you get back the C:\qmenu> with the blinking cursor you will know the process has finished. There will also be a new file called XPIE7.vmdk in your qmenu folder.
  13. Copy XPIE7.vmdk back to OS X by simply dragging it out of the VMWare window and onto your Mac’s desktop.
    Copy the VMDK to OS X
  14. Open VMWare Fusion and create a new virtual machine by going to File -> New.
  15. Go through the wizard and once you get to the Virtual Hard Disk page, expand Advanced disk options and check Use an existing virtual disk. Use the drop down to select Other… and go find the .vmdk file you just copied over.

    Setting up the VMWare image.

  16. Finish the wizard and boot it up. If prompted to upgrade the virtual harddrive, click Yes.
  17. Install the VMWare tools by going to Virtual Machine -> Install VMWare Tools as soon as Windows boots up. Now you’re done!

    Install VMWare Tools for better performance.

You should have a dedicated IE machine that you can test your web pages in. Mine weighs in at a mere 1.06GB compared to the typical multi-gigabyte requirement of a full install.

Final IE7 Install

Before you go rushing off in a state of web development nirvana, it should be noted that you will have to do this every three months as the Virtual PC images that Microsoft gives out expire. This is done to deter free loaders from using the OS for real work. But since you should only use it for testing purposes, it won’t be a big deal to delete the image and start this process anew every couple of months.

Happy testing!