CSS sledgehammer… #2

…browser-hacking is dangerous business…

avoid - if you can…

Some see browser-hacking as an art. I see it as a necessary evil. A stable solution is what I'm after, and hacks are not reliable. Sometimes there are no way around them though.

We can probably find a weak spot or a back door into each and every web browser that's released out in the wild, but despite the fact that I know how to get to their inner cores, I'm reluctant to add hacks.

An upgrade, and a browser-bug is gone and/or another has appeared. All hacks that rely on such bugs may fail then, and I have to start all over again in my search for new ways to hack my way through the mess.
Important: see update-notes down this page.

solid state…

Yes, there are some "solid state" solutions. At least some "relatively" reliable ones... We may use those without too much of a risk.

IE5+/win is most troublesome at the moment, so most of our efforts have to be focused on that old browser—drawing a line after IE6.

There are other, more risky, methods available. I've included some for good measure, since we may need ways to relieve all browser of their bugs at times — separately. However, I won't recommend the use of these methods in any way, shape or form.

Here is the not so short list:
Last updated and expanded: [24.jun.2006].

mode switching…

All new browsers decide how to render our pages, based on what DTD = DocTypeDeclaration we provide in our page-source. This DTD is only meant to tell the W3C: Markup Validation Service what standard we use, but browsers sniff it out and use it for mode-switching — probably because there isn't a better way to figure out what we are trying to serve them.

What DTD we use isn't all that important — as long as it is a proper one and we serve it right. What is important is that if we put a DTD in our pages, then we better make sure we code in accordance to that DTD. Not much room for cheating here, if we want the validator, and most important; the browsers, to play along with our wishes.

Today there are 3 modes in most browsers. We can expect such mode-switching to take place in all new browsers when they are served text/html.
It can get pretty messy if we don't know how it works, so take note of the notes below.

  1. quirks mode: the old mode, used when web pages have an old or badly written DTD, or no DTD at all. This mode may also be used if browsers are unable to interpret our pages because we have done a bad job at writing them.

    - Note: Old Internet Explorer versions (pre IE6) will only know old "MSIE mode", and can't make use of our DTD.

    - Note: Old Netscape versions will only know old "Netscape mode", and can't make use of our DTD.

    - Note: IE6+ will use this old MSIE mode as quirks mode, and Opera will follow IE/win closely, while Gecko-based browsers will use old "Netscape mode" as quirks mode. Notion of these two versions of quirks mode should be at the back of our minds, if we choose to enter the world of quirks mode rendering.

  2. Almost standard mode: some, but not all, browsers have such a mode, with only some minor deviations from "standard mode", to use when the DTD is recognized as a form of Transitional. See it as a 'slightly more relaxed' standard mode.

    - Note: browsers without this "almost standard mode" will render our pages in "standard mode" under these conditions.

  3. Standard mode: HTML 4.01 Strict, xhtml 1.0 Strict (and xhtml 1.1 and higher, although these shouldn't really be served as text/html).

    - Note: Standard mode is supposed to give us rendering close to W3C-defined standards, but don't be surprised over differences in how browsers interpret these standards.

This is not a complete list about mode switching, but it covers what most web designers / web carpenters need to know about the subject. Look at descriptions on each browser's homepages for more details.
More on the subject: Activating the Right Layout Mode Using the Doctype Declaration.

Note: W3C-defined standards have nothing to do with pixel-perfection. That's the browsers' department...
Differences in how browsers render our web pages are not necessarily a sign of browser-bugs. Bad design-work and the standards themselves, can create pretty unclear situations. See: do your homework.

Run IE6 in quirks mode:

IE6 has a badly implemented "standard mode" (and no "almost standard mode"). Apart from adopting the W3C box-model, the sk. "standard mode" is the opposite of an improvement. It's up to each web designer's own preference, of course, but IE6 is a lot easier to get somewhat "standard-compliant" in quirks mode, in my opinion. Se additional article: IE works best in Quirks mode.

"standard" mode:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

IE6 will go into "standard mode" as long as a proper DTD is at the very top in our source-code.

All other new browser will do the same, and render in standard mode or almost standard mode (see above).

quirks mode:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

…or

<!-- a comment -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

IE6 will go into quirks mode if there's anything above the DTD in our source-code. I use an xml declaration because I am sure how future versions of IE/win will handle that.

All other new browsers will recognise our DTD, and render in standard mode or almost standard mode (see above).

More on the subject is found on W3C, Serving XHTML 1.0.

Update [16.sep.2005]: According to Chris Wilson on the IE7 team, the xml declaration will no longer work as a switch in IE7. See IEBlog on: The <?xml> prolog, strict mode, and XHTML in IE.
What this means to me should be obvious: IE7 will handle my pages in "standard mode" – just as I hoped it would. Lucky me.

html or xhtml…

First: whether we use HTML or xhtml makes little or no difference as of today. We have to serve it as text/html for IE/win anyway, so we may use HTML 4.01 or xhtml 1.0 as it suits us – as long as we use them correctly. I have a purely personal preference for xhtml 1.0, and leave the details to a well-tuned version of HTML Tidy.

Just note that only xhtml 1.0 can be served as text/html – xhtml 1.1 and above are "off limit" with that MIME-type. See: W3C: HTML and XHTML Frequently Answered Questions for more details.

My own preference is based on many factors, some of which are mentioned around on this page and elsewhere in this site-section. I will sum it up here:

  • I am taking advantage of the xml declaration as switch between "standard mode" and quirks mode in IE6. I won't have to switch tactics or "fix hacks" when IE7 comes around, because I am prepared for that IE-version.
  • HTML and xhtml are treated the same when served as text/html, so I can't come up with a single, good, reason to switch to HTML when there's no advantage in it for me.
  • I have become used to the "well-formedness" of xhtml. Writing 'source-code' this way is more in line with my old profession, and it is easy to go one step further and serve xhtml as 'application/xhtml+xml' as support grows across browser-land. I intend to be around for a while...

So much for an issue that's more or less a non-issue to me.

comments in (x)html…

Comments in our source-code are meant to be invisible and "non existent" to browsers. Normal comments are just that, but Microsoft came up with some special-looking comments that made what's commented visible to IE/win only. One comment-version for each browser-version from IE5.0 and later, and some variants.

One of these IE-comments simply adresses all IE5.0+ on the windows operating system, which makes it handy for dealing with all those buggers in one go.

separate style sheet for Internet Explorer win:
<!--[if IE]>
<link rel="stylesheet" href="IEwin-style.css" 
type="text/css" />
<![endif]-->

I use this "IE-comment" in almost every page - because I'm lazy I guess. I also run IE6 in quirks mode to avoid its "not very standard compliant mode". I see few reasons to address IE/win-versions separately, since differences can be handled in other ways.

However, as future IE-versions may actually be improved upon and therefore need fewer corrections, we may save ourselves from problems caused by serving unwanted corrections to them, by drawing a line after IE6.

<!--[if lte IE 6]>
<link rel="stylesheet" href="IEwin-style.css" 
type="text/css" />
<![endif]-->

No problems with this one. It adresses versions less than and equal to IE6, which are the versions we have to deal with at the time of writing.

We may also wrap ordinary (x)html elements inside such a comment if we need to hack really deep into our source-code. No use inside CSS itself though.

Note [26.oct.2005]: If you're looking at the source-code of this page, you won't find an 'IE-commented stylesheet link' – because there isn't any. I've taken a completely different approach across the entire site.

separate style sheet for all browsers except Internet Explorer win:
<![if !IE]>
<link rel="stylesheet" href="GoodBrowserStyle.css" 
type="text/css" />
<[endif]>

This is what Microsoft calls a Downlevel-revealed Conditional Comment (see: About Conditional Comments for the complete picture. Note that the above example, copied directly from the MSIE site, is not valid.)

This "not IE comment" keeps IE/win from seeing parts of our source-code. Sneaking in and out of MSIE-land is quite useful at times, and it's not always practical to use CSS-only methods and hacks.

valid 'IE/not IE' conditional comments:

We all want our mark-up to stay valid, so let us clean up the mess from the MSIE site About Conditional Comments and comment our way in and out of MSIE-land. We have a couple of valid variants to our disposal.

valid comment v.1:

Commenting in and out of IE/win, means that only Internet Explorer can not see this...
... and that's fine with me.

The source-code for this test is tightly packed by HTML Tidy, inside a paragraph. It all looks like this (without the spans for colors) :

<p>Commenting in and out of IE/win, means that <!--[if IE]>
<em>only</em> Internet Explorer can see this...<br />
<!--[endif]>
<!--[if !IE]>-->
only Internet Explorer <em>can not</em> see this...<br />
<!--<![endif]--> ... and that's fine with me.</p>

See: 456bereastreet for more on the above. update: 15.nov.2005

valid comment v.2:

Following is a well known variant that I've used for quite a while. I't basically the same as above, but with a complete comment inside the conditional one, acting as an on/off trigger.

Commenting in and out of IE/win, means that only Internet Explorer can not see this...
... and that's fine with me.

<p>Commenting in and out of IE/win, means that <!--[if IE]>
<em>only</em> Internet Explorer can see this...<br />
<!--[endif]>
<!--[if !IE]><!-->
only Internet Explorer <em>can not</em> see this...<br />
<!--><![endif]--> ... and that's fine with me.</p>

See: Andrew Gregory on MSIE for more on this last one. update: 15.nov.2005

Any of these methods can be used for serving elements some versions of IE/win can/can not handle. We can in extreme cases target different IE-versions with different source-code, while serving something completely different to non-IE browsers.

valid 'not IE' comment (v.2) for stylesheet:
<!--[if !IE]><!-->
<link rel="stylesheet" href="GoodBrowserStyle.css" 
type="text/css" />
<!--><[endif]-->

Blocking IE from seeing source-code and/or stylesheets which contain stuff IE cannot possibly handle, may save both IE/win and the designer from having nervous breakdowns.

IE-expressions in CSS…

It would've been a good thing – in my opinion – if expressions were adopted into W3C's CSS standards, as many shortcomings of CSS as we know it would have been solved then. CSS3 may however provide us with some working solutions, once it becomes reality and the browsers catch up.

As expressions are javascript-based, all their functionality can be handled by proper javascript. Guess that's why these functions are in the functional layer (scripting) anyway.

As it is now, these expressions can be used to work around some of IE5.0, IE5.5 and IE6' shortcomings and lack of CSS support.

IE-expressions can:

The simple fact that IE-expressions fail if javascript-support is turned off, is “no big deal” in my opinion. If Users choose to turn off support for the only life-line we can throw IE/win, then so be it. IE doesn't lose anything by not being able to do what it wasn't able to do anyway.

min/max expression for Strict/Quirks modes

Always some who “feel sorry” for IE6 and wants it to run in standard or Strict mode. That's fine with me.

The following exact expression is now controlling this page in IE/win, and it does work regardless of what mode IE6 is in.

pixel-based dual-mode 'min/max-width' expression:
CSS for standard compliant browsers:
#wrapper {max-width: 1200px; min-width: 550px;}

CSS for MSIE/win:
#wrapper {width: 760px;}

div#wrapper { width:expression(((document.compatMode && 
document.compatMode=='CSS1Compat') ? 
document.documentElement.clientWidth : document.body.clientWidth) 
> 1218 ? "1200px" : (((document.compatMode && 
document.compatMode=='CSS1Compat') ? 
document.documentElement.clientWidth : 
document.body.clientWidth) < 570 ? "552px" : "99.7%")); }

@media print {
div#wrapper {width: 100%!important;}
}

Se additional article: min/max – making IE/win work for more details – including an em-based dual-mode 'min/max-width' variant.

Print-styles not working in IE?

Expressions tend to override any equivalent print-style, and that doesn't work too well since expressions take their variables from the browser as it acts on screens. So even though these expressions won't work on printing-media, they may freeze page-width so it doesn't fit on paper.

This is where the additional print-style comes in. We can override expressions by using '!important', and give more meaningful definitions in our print-styles. Simple, but it works.

@media print {
div#wrapper {width: 100%!important;}
}

Note that this page is running in quirks mode in IE6, since that's what the author wants.

progressive filtering…

Progressive filtering isn't browser-hacking really. Instead we make use of the simple fact that old browsers don't understand the newest CSS-standards. New and standard-supporting browsers may thereby be given more detailed and refined styles to work on.

We use 'progressive filtering' a lot at this site, because we're tired of waiting for all browsers to catch up with existing W3C-standards. This makes our pages 'grow' with the progress across browser-land, and they will tend to reveal most in the latest and best browser-versions at any time.

The trick is to avoid using 'progressive filtering' as hacks for feeding corrections to specific browsers. Instead we must leave it open to all browsers to recognize and act upon as many standard rules as each of them can handle, and simply let the weaker browsers ignore rules they don't understand. Standard-support is the key here.

complicated by buggy browsers

Browser-bugs may complicate this method quite a bit, because "understanding" doesn't mean "bug free". We have to test all our 'progressive filtering' in every new version of every browser to make sure it is working as intended, so it may not be everyone's preferred method.

It is better to avoid this method if we're unable to follow up on a site. In short: don't sell this method to clueless clients.

apply everything you need – now

Some say that we should avoid using parts of W3C CSS standards that aren't supported by all major browsers. I think that's complete nonsense, as standard-support won't be improved much if no one starts using the existing standards in their designs.

Web designers are the driving force behind standard-support across browser-land. If we don't apply some force, then nothing much will happen in that field. It may in fact be better for progress if we break some weak browsers instead of carrying them through on a lot of weak CSS.

Example: I won't avoid Projection and Small Screen Rendering just because so few browsers supports these parts of CSS in W3C standards. Visitors who use a browser with proper standard-support should be able to see what their browser can do, and visitors with less capable browsers haven't lost a thing.

(non-)valid filtering…

This section on our site have gone one step further and invalidated itself. No big deal in my opinion – as long as it's only the CSS that has non-valid parts , but most certainly not recommended. It is however the only way we can perform full-scale testing of how different browsers really parse and act upon our stylesheets.

This testing is done by linking in test-stylesheets containing browser targeting CSS hacks to some of our pages, and a more active, separate, stylesheet to our main stylesheets in this section. These extra stylesheets include both valid and non-valid filters and hacks. We're constantly in search of valid solutions, so the state of validity may change at any time.

don't compensate for your own bugs

We do not use filtering to introduce major browser-corrections or alterations – except for IE. This is live testing, not compensations for lousy craftmanship. Nothing much will happen even if we delete these extra stylesheets.

You can see how tests are performed on the pages linked in under testing browser-support in this CSS sledgehammer series. Bugs and errors, and other strange creatures, are explored in depth there.

If you wanna give it a try, then this browser targeting stylesheet may be worth looking into. Check the date, and use at your own risk.

valid – or not..?

The W3C CSS validator is clearly not up to standards at all times. I'm not making any claims here, but when both standards and browsers seems to say that a declaration is OK, and the validator mark it is an error, then someone got to be wrong.

I expect either the standards or the validator to be corrected so they get in line, in the not too distant future. I'll mess around with both in the mean time.

do your homework…

My (x)html source-code and my CSS is a bit heavy. Some say: "too heavy", and they may be right. However, I won't skip the basics, so I tell all browsers what I want them to do, even if they'll do so by default. Not too many "bugs" and differences left when they have swallowed my stylesheets, so it pays to include all the tiny details.

I don't complain too much about bad rendering in any browser. Most often I just have to see what's on screen, and add in or correct some basics if it doesn't look right. I use hacks too, but only when and where they won't hurt too much if they fail.

minimize the use of hacks

I've deleted a few dozen pages on our site that contained descriptions of hacks, filters, tips and tricks. The reason: excessive use of hacks don't solve problems when used on weak web pages, so I won't recommend their use—unless you know exactly what you're doing.

However, I've been through the whole bug-house myself (and will probably never get out of it), so I've added a whole set of links to other sites that may help those of you who are about to enter this "lovely" part of web design. I visit some of these resources from time to time, to make sure my CSS sledgehammer is well balanced.

plan well, and don't count pixels

Well planned, well built and well organized web pages don't need all that many hacks. Web-designers who take the time to create cross-browser stable web pages, will also learn how to get around what's left of major differences with none or only a few hacks (except for IE/win of course).

Why a web page should look identical in two browsers, is beyond me. It may be fun to achieve it, but it isn't important. None of my pages are "pixel perfect", but few will ever notice and even fewer will have a problem because of these differences.
No two visitors provide our pages with the same environment on screens anyway, so what's it all about?

…It's balancing-time…

sincerely  georg; sign

Hageland 01.nov.2004
last rev: 08.dec.2008

CSS sledgehammer…


about…
…2005 - 2008
last rev: 08.dec.2008