Pixelastic

You can cut our wings but we will always remember what it was like to fly.

Posts tagged with "IE6"

Alternative way for multiple classes in IE6

In a pure OOCSS style of writing CSS, let's imagine you created a css class of .button that visually turns a simple link into a button.


<a href="#" class="button">I'm a button</a>

Now, if you want to define a custom version of your button, let's say a button that will trigger a very dangerous action, you might want to style it differently, so our user will think twice before hitting it.

You got two ways of achieving this, depending if you still support IE6 or not.

Simple way for non-IE6

If you don't care about IE6 (and hell, it's 2012, you shouldn't), you just have to add a second class to your button/link :


<a href="#" class="button dangerous">I'm a dangerous button</a>

And in your CSS file, just define some special styles (like a red background) to your dangerous button.


.button.dangerous { ... }

Actually, that's the path followed by Bootstrap (among others). But it will not correctly work in IE6, because it does not understand multiple classes rules. Instead, IE6 will read .button.dangerous {} the same as .dangerous {}.

This will cause problems as soon as you'll use the .important class on something else than a .button : IE will apply the .button.dangerous rules to anything with the .dangerous class.

Other way, for IE6

The solution I personnaly use to fix IE6 is to use more explicit classes instead of using multiple ones. For example, instead of .button.dangerous {} I'll use .buttonDangerous {} and write my html like this :


<a href="#" class="button buttonDangerous">I'm a dangerous button, even on IE6</a>

That way, the link will have both the styles of .button and .buttonDangerous. This will assure cross compatibility with IE6, at the expense of a (arguably) less readable markup.

As of today, I hope that I'll never have to code for IE6 websites again, but if you ever need to, that's a little trick that can really help.

SWF caching issues accross browsers

Here are some quick notes on various browser caching behavior. I was fiddling with Wireshark to optimise my caching strategy and found some quirks one should be aware of.

First, let's define some reload vocabulary.

  • initial load is the first time the page is loaded, when the cache is empty.
  • hard reload is the classical reload. Clicking the Reload icon, or pressing Ctrl+R / F5.
  • link reload is when the page is loaded again after you click on a link to it
  • soft reload will be loading the page again by pressing enter in the address bar
  • navigational reload is the reloading of a page that occurs while using the previous/next buttons.

For the rest of this blog post, we will assume an HTML page loading the same .jpg file multiple times and the same swf file multiple times too (we will use both IE specific and general swf markup).

The html itself is not cached.

Also, all those static assets will have a Cache-Control:max-age=29030400 header.

All the network tests have been made using Wireshark.

Chrome

Initial load : Download of jpg and swf once each. Perfect.

Link reload & navigational reload: Nor jpg nor swf is loaded again. Perfect.

Soft reload & hard reload : The jpg is downloaded again but not the swf. Chrome sends a Cache-Control:max-age=0 header to the jpg request, to force loading it again.

Reloading images is a standard behavior on images, but I wouldn't have expected it on soft reloads.

Safari 5 Win

Safari behaves much like Chrome, with one important difference. It does not cache swf files at all.

Initial load : The jpg gets downloaded perfectly, but the swf gets downloaded multiple times, one per instance.

Link reload & navigational reload : The jpg is correctly fetched from cache, but the swf are all downloaded again. No swf is ever cached.

Soft reload & hard reload : Much as Chrome, Safari forces the reload of the jpg here. As you might guess, it also reload all the swf too, multiple times.

It means that Safari 5 does not cache any swf file at all. That's pretty impressive.

This same caching bug is talked about on this other blog. I've also tried including flash files from within another flash file (much like the Satay method). The results are the same : no swf flash is ever cached, even in the same html request.

It is supposed to have been fixed in Safari Mac (anyone can confirm this? I don't own a Mac) but the issue is still here on Safari Windows.

IE6, IE7 and IE8

IE6, IE7 and IE8 behaves the same here. They have a less severe version of the bug than Safari 5. At the time of writing I didn't have IE9 to test on it.

Initial load : Same bug as Safari here. The swf are downloaded multiple times, once for each instance. The jpg is only download once.

Link reload, navigational reload and soft reload : This time, everything is fetched from the cache. Actually, even the html is seems fetched from cache (I didn't investigate that much)

Hard reload : Html and jpg are fetched from the server, swf file stays in the cache.

It appears that (surprisingly) IE behaves quite well. Its caching behavior is more aggressive than the others (soft reload is really soft). However, it still have a nasty side effect of loading swf files multiple times on the same page. Shouldn't happen a lot in the real world, but still nice to know.

Firefox 4.0

Initial load : No issue arising. It does fetch each resource once.

Link reload, navigational reload and soft reload : Fetches everything from cache, nice.

Hard reload : Re-request jpg and swf files by adding a Cache-Control: max-age=0 request header. This feels like the expected behavior.

 


Testing IE6 and IE7 using VirtualBox on Windows

Testing various IE version as always been a chore. Back in the days, I managed to install both IE7 and use a standalone IE6 version.

Then, I discovered IETester that became a lifesaver (my IE6 standalone tends to crash a little too often). It would allow me to test various IE versions side by side.

Unfortunatly, the emulation wasn't perfect, some ajax calls were returning errors and the Flash support wasn't so good.

Additionnaly, there was not way to use the IEDebugBar nor the WebPageTest plugin.

Switching to VM

I finally decided to switch to a Virtual Machine. This would allow me to have an exact snapshot of a given OS/IE version.

VirtualBox is free, so this was my choice. Microsft used to provide free downloads of various flavors of Windows/IE, but it seems to be only working with their proprietary VirtualPC (which only works under Windows 7).

So I took the long road, and manually installed a Windows XP Pro through VirtualBox, using my Windows XP cd.

I used the same serial than my main windows XP. I'm not exactly sure if legally, I'm allowed to do that. How does a VM fits inside the legal statements ? Am I allowed to use one windows activation key inside itself ? Well, I don't really know and don't care that much.

Starting with some housekeeping

I ended up with a nice and clean WinXP install. I had to add an antivirus quick if I wanted to keep it clean. VirtualBox provides a Shared Folder feature to exchange files between the host and the guest.

Start by adding shared folders to your guest (Devices > Shared Folders).

Then install the "Guest Additions", just mount the VBoxGuestAdditions.iso found in your VirtualBox installation directory, using DaemonTools and run the installer.

Don't be as silly as I was. Do not install the Guest Additions on your host, but on your guest. Yeah, seems more logical that way. Just select the options in the Devices menu of your guest window. Reboot after the installation.

You should now be able to access your shared folders by opening the windows Explorer (Windows + E), and going to Network places > All network > VirtualBox Shared Folders

Accessing your websites

I then updated the C:\WINDOWS\system32\drivers\etc\hosts file to bind all requests made to my still-in-development websites to my host.

10.0.2.2        www.pixelastic
10.0.2.2        s1.pixelastic
10.0.2.2        s2.pixelastic
10.0.2.2        s3.pixelastic

You can find your host ip by doing a ipconfig /all in a command prompt.

You then just have to go to http://www.pixelastic/ in IE6 to display the correct website. You can even switch to the Seamless mode to display your IE6 inside your main host.

Some CSS hacks to target IE6 and IE7

After stopping using ugly IE hacks and moving to conditionnal comments to load a special IE stylesheet, I now use conditional comments to mark my body element with classes reflecting the current IE version.

<!--[if IE 6]><body class="ie ie6 ie-lt8 ie-lt9"><![endif]-->
<!--[if IE 7]><body class="ie ie7 ie-lt8 ie-lt9"><![endif]-->
<!--[if IE 8]><body class="ie ie8 ie-lt9"><![endif]-->
<!--[if IE 9]><body class="ie ie9"><![endif]-->
<!--[if !IE]><!--><body class="nie"><!--<![endif]-->

This saves me a lot of trouble : less files to manage and easier fixes to write. I quite happy with this solution and have tested it accross several projects for the past 3 months. It works really well.

I had to work on a legacy project last week, where this technique wasn't implemented but all the css code was still compressed using CSSTidy. And I ran into a couple of issues.

CSSTidy messes the star and underscore hacks

Using the brilliant _property and *property hacks to target IE6 and IE7 does not work in conjunction with CSSTidy.

For the _property hack, the property is kept as-is, with the underscore, but as they are alphabetically arranged, the _background gets added before the background, rendering it absolutly useless.

On the other hand, on the *property, the * gets removed, and the value is merged with the original value of the correct property. Useless too.

Other solutions that worked

To avoid digging into CSSTidy one more time, I tried to find other ways to achieve the same effect.

To target IE6 I used the !ie6 hack by writing .mySelector { property:value !ie6; }. IE6 is dumb enough to understand any !blahblah as !important.

I could have also used the fact that IE6 understands .class1.class2 as .class2, and could have written .ie6.mySelector { property:value; } (of course, you have absolutly no class="ie6" in your code)

To target IE7 I made a custom selector that its parsing engine is the only one to understand : *:first-child + html .mySelector { property:value; }