Put Your Print Stylesheet At The Bottom

I woke up this morning with a profound realization. “Why not put print stylesheets at the bottom of the page so they load last?”, I thought to myself. It makes perfect sense to any performance-conscious web developer who savors every last millisecond of performance gained. Your print styles aren’t needed until you print the page, so it is okay if it takes a little while longer to download.  Unfortunately the quirkiness of the browser makers trumps our otherwise sound logic.

According to tests done by Steve Souders, web performance guru extraordinaire, Internet Explorer blocks the rendering of content until all of the stylesheets have been downloaded regardless of their media type. And since Internet Explorer is the dominant browser by visitors to most mainstream sites, there is absolutely no benefit to including the print stylesheet at the bottom of the page.

A possible workaround would be to dynamically insert the print stylesheet (using JavaScript) into the web page after it has finished loading. This just feels icky to me as the poor sap who is most likely to print out the webpage I so meticulously coded is also the poor sap using Internet Explorer 5.5 with JavaScript turned off and BonziBUDDY turned on.

Developers: Stop Whining About IE6


I’m sick of the developer community whining and moaning about IE6. It’s amazing how many different campaigns have been created in an attempt to get people to upgrade. From the simple brochure sites like stopie6.com to the unethical IE6 update script which tricks a user into thinking an IE upgrade is a critical update. There was even a CNN story about the anti-IE campaign on the front page (which I think they ran mostly because they stood to benefit from people upgrading). And lets not forget the jovial tweets when news broke that YouTube would be dropping support for IE6.

The only major site that has a valid plan for leaving IE6 behind is Digg.com which was a business decision. According to their stats, IE6 accounts for 10% of visits and 5% of all pageviews. The biggest IE6 headaches for Digg is supporting the functionality to digg a story, bury a story, or leave a comment. IE6 only accounts for a mere 1% of these actions which Digg can’t justify the extra development time needed to support them for such a small group of users. They even conducted a survey to find out why people don’t upgrade their browsers with a majority of the respondents stating they aren’t allowed or they don’t have the proper rights to install new software on their computers.

Digg IE6 Survey chart

All of this hoopla so the lives of developers are easier. After all it is the job of developers to build a site and make sure it works across a variety of operating systems, browsers, and devices in order to serve its audience. Martin Ringlein put it best in his post Stop being a dick, support IE6, “We are in the business of creating usable, accessible and intuitive experiences for our users; we are not in the business of changing users, user agents and user behavior all in a pursuit for what we’ve deemed a ‘better’ web.”

I became a developer because I enjoyed solving problems. Internet Explorer is just another obstacle to get over when solving a problem. Rather than wasting energy on things I couldn’t control like trying to persuade the public to upgrade, I dove into learning how to get past the quirks of IE. Here are my 5 tips:

  1. Start with a reset stylesheet – This removes any default styles set by the browser so you can start styling on a consistent base. I prefer Eric Myer’s CSS Reset Reloaded , but there are many to choose from.
  2. Use a strict HTML doctypeDoctypes tell the browser how to interpret the HTML and transitional and loose doctypes introduce rendering quirks known as triggering “quirksmode“. Any XML doctype (including XHTML flavors) triggers quirks mode in IE as well.
  3. Don’t be afraid of CSS conditional hacks – Did you know you can send IE a different property by putting an underscore in front of it? It works like this:
    .style {
    margin-left:15px; //Caught by every browser
    _margin-left:10px; //Caught by IE 6 & 7
    .margin-left:8px; //Only caught by IE6

    You can also use conditional stylesheets to serve different stylesheets but that becomes difficult to maintain.

  4. Learn to love the AlphaImageLoader filter for transparent PNGs – There is no way around it.
  5. Learn to clear floats the simple way – Just set the “overflow” property of the container to auto or hidden and set the width or height to something other than auto. This applies to all browsers not just IE. I hate seeing the overly complicated clearfix solution.

Other tips for taming IE quirks:

So if studying up on these workarounds and techniques sound like too much work, then maybe you shouldn’t be a developer. Perhaps a professional lobbyist is right up your alley. They’re pretty good at ignoring the details of reality.

Here’s a list of some of the more prominent anti-IE6 sites:

And David DeSandro agrees with my attitude towards IE6.

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.

Browser Wars Graphic

This is certainly the most creative way to show the battle of the browsers in the Internet space.

Browser War Graphic

I stumbled upon this on fffound.com, my favorite source for random images that everyone is buzzing about. I have no idea where it came from but it is a little out of date with the lack of Google’s Chrome in the mix.

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!