The one bug the Omni Group must not fix
November 18, 2002
Feedback Farm
Have something to say about this article? Let us know below and your post might be the Post of the Month! Please read our Official Rules and Sponsor List.
Forums
Want to dig even deeper? Post to the new MacEdition Forums!
If you’re looking at this page in OmniWeb, it should look horrible. The text should be magenta on a hideous yellow-green background, and the other parts of the page should be similarly vile. For everyone else, it should look like a familiar MacEdition page, with readable black text on a white background, and the familiar dark teal and black backgrounds around the content and the ochre-ish sidebar.
How did I do this? It wasn’t browser sniffing or JavaScript of any kind. Go on, OmniWeb users, change your user agent string and see if it makes a difference. No, it’s much simpler than that. I have discovered the ultimate technique for hiding specific CSS from OmniWeb – the CSS it can’t cope with – and I’m presenting the trick for you today. I’m going to suggest you call it “CodeBitch’s OmniWeb hack,” or, if your site is G-rated, “CB’s OmniWeb hack.”
Hiding CSS from buggy browsers has a long and distinguished history in
standards-based Web authoring. Netscape 4 is the usual subject and so
we’ve all had to become familiar with tricks like
@import
-ing
the complex styles that Netscape 4 can’t cope with, or using the
media="all"
attribute in the link
element to hide a linked stylesheet
from that browser, among others. There is also a
comment-based hack
discovered by Caio Chassot that
is more precisely focused on hiding CSS from Netscape 4.
There are other ways of referencing styles that OmniWeb doesn’t support
– the @media
syntax, for example. Until now, however,
none of those documented tricks and hacks were suitable for hiding CSS
from OmniWeb’s buggy CSS implementation. Every other trick that hid CSS
from OmniWeb also hides it from IE5/Mac. This is almost certainly not
what you want to do, as IE5/Mac has a very good CSS implementation,
especially for CSS1. Indeed, some of the
advanced CSS2 selectors used
in hiding techniques,
like the direct-child, sibling and attribute selectors, are downright
disastrous in OmniWeb. You can find out more about what goes wrong by
checking out the MacEdition
Guide to CSS Support in Mac-only Browsers.
Simple but effective
Here’s the technique. First, call the stylesheet that OmniWeb can
handle using a normal link
element syntax, making sure you
include a media
attribute like media="screen"
or media="all"
.
<link rel="Stylesheet" rev="Stylesheet" href="owcanseethis.css"
type="text/css" media="screen">
Then call the stylesheet with the CSS that OmniWeb can’t cope with, but use a media attribute with a value that has an initial capital, like this:
<link rel="Stylesheet" rev="Stylesheet" href="owcannotseethis.css"
type="text/css" media="Screen">
All CSS-supporting browsers that I’ve tested other than OmniWeb see
both stylesheets, so if there’s a style that you want to use for
OmniWeb only, not other browsers, you need to override it exactly in
the second stylesheet, matching the selector and property exactly, or
using a more specific selector. For example, suppose you have styled
headings in the sidebar of your page to have gray dotted bottom
borders. OmniWeb doesn’t support dotted borders, so you might decide to
use a solid border for it instead. So in the first stylesheet you would
use the OmniWeb-specific style, #sidebar h3 {border-bottom: 1px
solid #999;}
, while the second stylesheet would include the
style #sidebar h3 {border-bottom:1px dotted #999;}
.
Using a combination of the cascade and the two stylesheets, you can hide styles from OmniWeb completely, or pass it styles that only it uses. You can see a simple example in this test page. This CSS-hiding hack is one of the “purest” that I’ve ever seen. We’ve tested widely, and as far as we can tell, it only affects OmniWeb. It’s completely valid HTML, although the CSS validator at the W3C does complain about the capital letters in the media types (probably incorrectly, as I’ll explain below).
The hows, whys and wherefores
It’s such a remarkably simple hack that I’m surprised that nobody mentioned it before. It’s doubly surprising since the initial capital in the media attribute is the way BBEdit inserts it by default (that’s how I discovered it). Maybe people who previously noticed it didn’t think to publicise it. More likely, OmniWeb just isn’t on the radars of standards-oriented Web authors. Everyone knows that OmniWeb’s CSS support is limited, and ignores it.
The reason why this hack works is also a bit surprising. OmniWeb is, of
course, treating the media
attribute values as
case-sensitive, and not recognising values with capital letters in
them. There is a reason for this: it appears that OmniWeb is the only
browser taking a specified option in HTML spec. The
relevant part of
the spec reads “A
case-sensitive match is then made with the set of media types defined
above. User agents may ignore entries that don’t match." But if you go
to the CSS spec,
it flatly contradicts the HTML spec:
“Media type names
are case-insensitive.” (This is why it’s funny that the CSS validator
complains about the capital letters but the HTML validator doesn’t.) At
some point, the W3C managed to write slightly contradictory
specifications. It’s a reminder that the standards themselves aren’t
perfect any more than the browsers are. But
as I’ve argued before,
it’s better to have
imperfect standards than no standards at all. I hope they will rectify
this soon, in favour of the CSS spec.
I’m not the first person to notice the inconsistency, and the view seems to be that case-insensitivity is the way to go here. Indeed, there is some suggestion that it’s simply a typographical error in the spec, given that the text links to the explanation for case-insensitivity. Another possible interpretation is that both behaviours are correct. As W3C staffer Dave Raggett emphasised during the drafting process for the HTML spec, browsers may ignore media types that don’t match a case-sensitive search, but they don’t have to. A brief Google search shows that the tutorial sites disagree on this point: some say it’s insensitive, while others say it’s case-sensitive.
From a practical point of view, case-insensitivity makes more sense.
CSS doesn’t only apply to HTML and XHTML, it can apply to other markup
languages. So at some level, the CSS spec is more general than the HTML
spec. Also, media types enter into @import
statements,
covered by the CSS spec, as well as the link
element
covered by the HTML spec. It would be stupid to have these two contexts
for media types treated differently, so the CSS spec’s interpretation
should stand.
What the Omni Group must not do
Since this isn’t, strictly speaking, a bug in OmniWeb, the Omni Group shouldn’t feel obliged to fix it. In fact, I’m going to call on it to never, ever fix this bug. Not now. Not in Version 5.0. Not even if CodeBitch says it’s okay to fix it. There will always be some bugs we need to work around.
Let’s face it, OmniWeb has some pretty egregious CSS bugs and misimplementations, and I have little confidence that Version 5.0 will fix all of these problems (although many of them should be fixed, or I’ll be even more disappointed in the Omni Group than I am now). Web authors who have significant proportions of OS X users in their audience might want to work around these bugs. This hack allows them to do so. The Omni Group should continue to allow this consideration of its own users. Long live the “CodeBitch OmniWeb Hack”!