tags:

views:

10932

answers:

5

Using conditional comments it is easy to target Internet Explorer with browser-specific CSS rules:

<!--[if IE 6]>
...include IE6-specific stylesheet here...
<![endif]-->

Sometimes it is the Gecko engine (Firefox) that misbehaves. What would be best way to target only Firefox with your CSS rules and not a single other browser? That is, not only should Internet Explorer ignore the Firefox-only rules, but also Webkit and Opera should.

Note: I'm lookin for a 'clean' solution. Using a Javascript browser sniffer to add a 'firefox' class to my HTML does not qualify as clean in my opinion. I would rather like to see something that depends on browser capabilities, much like conditional comments are only 'special' to IE…

A: 

Might want to look at some similar questions and thier related answers...

http://stackoverflow.com/questions/738831/how-to-display-browser-specific-html/738949#738949

AnonJr
I get your point; we should accept that sites render differently across user agents, and browser sniffing is not future-proof. Still, I think this has genuine practical value (even though I wouldn't need it very often) and is theoretically interesting.
avdgaag
+3  A: 

The only way to do this is via various CSS hacks, which will make your page much more likely to fail on the next browser updates. If anything, it will be LESS safe than using a js-browser sniffer.

jvenema
+2  A: 

A variation on your idea is to have a server-side USER-AGENT detector that will figure out what style sheet to attach to the page. This way you can have a firefox.css, ie.css, opera.css, etc.

You can accomplish a similar thing in Javascript itself, although you may not regard it as clean.

I have done a similar thing by having a default.css which includes all common styles and then specific style sheets are added to override, or enhance the defaults.

Kekoa
That does some like a nice and stable approach — thanks — although it still depends on browser sniffing. I'd rather use something that depends on capability, like a Gecko-only CSS rule or something.I do use the same basic approach: default styles and browser-specific add-ons.
avdgaag
+2  A: 

First of all, a disclaimer. I don't really advocate for the solution I present below. The only browser specific CSS I write is for IE (especially IE6), although I wish it wasn't the case.

Now, the solution. You asked it to be elegant so I don't know how elegant is it but it's sure going to target Gecko platforms only.

The trick is only working when JavaScript is enabled and makes use of Mozilla bindings (XBL), which are heavily used internally in Firefox and all other Gecko-based products. For a comparison, this is like the behavior CSS property in IE, but much more powerful.

Three files are involved in my solution:

  1. ff.html: the file to style
  2. ff.xml: the file containg the Gecko bindings
  3. ff.css: Firefox specific styling

ff.html

<!DOCTYPE html>

<html>
<head>
<style type="text/css">
body {
 -moz-binding: url(ff.xml#load-mozilla-css);
}
</style>
</head>
<body>

<h1>This should be red in FF</h1>

</body>
</html>

ff.xml

<?xml version="1.0"?>

<bindings xmlns="http://www.mozilla.org/xbl"&gt;
    <binding id="load-mozilla-css">
        <implementation>
            <constructor>
            <![CDATA[
                var link = document.createElement("link");
                    link.setAttribute("rel", "stylesheet");
                    link.setAttribute("type", "text/css");
                    link.setAttribute("href", "ff.css");

                document.getElementsByTagName("head")[0]
                        .appendChild(link);
            ]]>
            </constructor>
        </implementation>
    </binding>
</bindings>

ff.css

h1 {
 color: red;
}

Update: The above solution is not that good. It would be better if instead of appending a new LINK element it will add that "firefox" class on the BODY element. And it's possible, just by replacing the above JS with the following:

this.className += " firefox";

The solution is inspired by Dean Edwards' moz-behaviors.

Ionuț G. Stan
+1 for an awesome new-learn, thanks =]
David Thomas
Yay for an awesome solution, but I do think it is a bit messy. Also, it depends on Javascript — which I'm trying to avoid. Still, very interesting.
avdgaag
+24  A: 

OK, I've found it. This is probably the most clean and easy solution out there and does not rely on JavaScript being turned on.

<!DOCTYPE html>

<html>
<head>
<style type="text/css">
@-moz-document url-prefix() {
    h1 {
        color: red;
    }
}
</style>
</head>
<body>

<h1>This should be red in FF</h1>

</body>
</html>

It's based on yet another Mozilla specific CSS extension. There's a whole list for these CSS extensions right here:

https://developer.mozilla.org/en/CSS_Reference/Mozilla_Extensions

Ionuț G. Stan
Awesome. Too bad about the domain name (and of course the invalid (?) CSS, but that was to be expected).
avdgaag
I've soled the domain name problem, but the CSS validation... I believe is part of the solution. I was afraid other browsers will ignore the @at rule and parse its contents.
Ionuț G. Stan