IE6 and CSS media types

When trying to reduce the number of HTTP requests on a web project I was working on, I tried to combine my screen and print stylesheets into a single file. Using the @media declaration, one should be able to specify media-specific styles. Other browsers were ok, but as usual IE6 was playing up. My @media print block was completely ignored.

The setup

First, I had only generic rules and a single print block, like so:

body { font-size: 12px }
@media print {
    body { font-size: 14pt }
}

Then, I included the stylesheet on my page with a media type:

<link rel="stylesheet" href="styles.css" media="screen, projection">

As I understood the specs all generic styles (outside the @media print block) should apply to the media specified in the link, while the print-specific styles should apply only to the print media type.

The solution

It seems the media type from the link overrides the @media print block in IE6, so removing that un-ignored those styles:

<link rel="stylesheet" href="styles.css">

Then, in order to keep my generic styles (which are actually screen-only styles) from influencing my print styles, I used another @media block:

@media screen {
    body { font-size: 12px }
}
@media print {
    body { font-size: 14pt }
}

All was well and both my screen and print styles were picked up nicely. Now I could use one single stylesheet and remove one additional HTTP request, speeding up the site loading time.

Internet Explorer, Javascript and base elements

Internet Explorer treats the base element a bit diffently from other browser. I ran into the issue when trying to change the current page’s hash through javascript:

window.location.hash = 'some_value';

Internet explorer took the entire base URL and prepended it to the hash, resulting in an URL like http://domain.tld/http://domain.tld/#some_value. That’s clearly not my intention.

The trick lies in the href attribute for links. This actually points to the faulty long url, while its actual attribute value is only the hash:

<a id="link" href="#some_value">...</a>
// IE: http://domain.tld/#some_value
// other browser: #some_value
$('#link').attr('href'); 

The trick is to replace anything before the pound when reading the href value, like so:

$('#link').attr('href').replace(/^.*(?=#)/, '');

And when trying to find links pointing at #some_value to not be too restrictive with your selector:

// finds 1 in other browsers, nothing in IE
$('a[href="#some_value"]')

// works like expected in all browsers; Note the *
$('a[href*="#some_value"]')

Tricky stuff!

Internet Explorer’s defects

Internet explorer has many faults, especially the versions 6 and below. As web developers we want to give our users the best possible experience, so we come up with ways to hide these faults. By doing this we are teaching internet users that Internet Explorer is a fine web browser, and that websites built with web standards that look odd are not properly built. This is turning things on their head, me thinks.

How can we turn a web culture that says: “this website looks odd, what a lazy developer,” into “this website looks odd, I really should get a better browser”? How to raise awareness about what a browser is, what browser people use and why they use it?