I was recently working on a page where the layout was perfect in IE6 and Safari, but an element was off by 1px (to the left) in Firefox. The problem was that if I added "margin-left: 1px" to the element, then it was 1px too far to the right in IE6 and Safari, and this had the effect of messing up the whole layout – an entire div that made up part of the layout no longer fit in its container, and so was bumped down to the next line.
So, somehow, I needed to apply the "margin-left: 1px" ONLY to Firefox. I came up with this solution:
Here’s how it works:
In the first selector, margin-left is specified twice. Normally, the browser would take the second value (0px) because it comes later in the stylesheet. However, I added "!important" to the first line, which tells the browser to use that value (1px) above all others. Firefox adheres to this and uses the 1px. IE6, which does support "!important," just so happens to ignore it in this context (for whatever reason), and so it reads the 0px instead.
That took care of Firefox and IE6. However, Safari also saw the "margin-left: 1px !important" line and used the 1px value as well, but I wanted it to use 0px instead.
Here’s where the second selector comes in. The ":first-of-type" pseudo-selector matches the first occurrence of any element of a particular type in the document. Since you only ever have one body element, "body" and "body:first-of-type" are equivalent, but Safari is the only browser that recognizes the latter – other browsers will skip it. So inside here I added "margin-left: 0px !important". The "!important" is needed because it overrides the "margin-left: 1px !important" from before (since both use "!important," they are equivalent, so the second one takes precedence because it occurs later in the stylesheet).
Whew! So the end result is that IE6 sees this:
Firefox sees this:
And Safari sees this:
Note that this won’t work with IE7, because it supports "!important" correctly. Also note that this method isn’t "future-proof" because other browsers can (and probably will) add support for ":first-of-type" in later versions.
However, for the time being, this is an easy, CSS-only way to direct three different styles to IE6, Firefox, and Safari simultaneously. It also validates as CSS3 :)
i didnt read all of this but its exactlly why i design for FF first and then go back through for IE as i go. you can add .margin:whatever for all ie or _margin:whatever for ie6. if you get it right in FF first most likely it works in safari. especially if youre as semantic as possible and you dont use a ton of mark up thats not needed.
I usually do the "Design for Firefox first, then deal with the other browsers" technique too. Typically I don’t have any problems with Safari, but that’s cool to know there is a way to target it, I didn’t know about that technique.
For dealing with IE issues though, I seriously recommend just using IE-specific stylesheets instead of hacks. This keeps you CSS valid, works great, and then you have a nice little separate file to reference for IE stuff (which is also valid).
I am by no means advocating using this method to build an entire site. I too code for Firefox/Safari first, then fix any IE issues with a separate IE-only stylesheet wrapped in a conditional comment. That’s clearly the best way to work around IE-specific issues.
I posted this more as a proof of concept to show that you can target the three major browsers individually from one stylesheet, without doing anything invalid. Also, in my particular case, an IE-only stylesheet wouldn’t have solved everything on its own since I still needed to direct one value to Firefox and another to Safari.
Again, for a major site, I would never rely on this, as it’s bound to break in the future (in fact it already has, since it won’t work for IE7).
You must be logged in to reply to this topic.