Useragent Rules in CSS

Just thought I'd chime in here.

The first thing that needs to be done is to recognize that the desire
for this type of @useragent filtering of CSS rules is _legitimate_.
The need _exists_, and it is something which CSS developers struggle
with every day.  Even if some people can handwave and say, "oh,
server-side munging will solve it," the fact still remains that this
is a problem which deserves to be taken seriously.  Ignoring designer
input, such as that from Dave Shea, is deadly to the standards
process.

So basically, Dave is saying, "I need some way to ensure that what
I write is either going to (a) work, or (b) not do anything at all,
because (c) partially work will screw up the presentation for the
user."  (At least, that's what I hear him saying!)  And this is a
valid and legitimate request.

The next question is how to meet that request within the context of
the CSS philosophy, existing user agents, and web standards.  And
the problem is, there's no easy answer.

The first idea, relying on user agent strings, is limited.  Browser
detection can only go so far, and relies on each browser supplying the
appropriate and correct string, which is then matched against the
style sheet's expectations.  This requires that the style sheets have
knowledge not only of today's browsers, but also tomorrow's -- which
is an impossibility.  This is why, by and large, server-side adaptation
based on user agent strings is only a partial solution to this type
of problem, one with very serious limitations that make it unworkable
over the long term.  This applies to both client-side and server-side
interpretation of user agent strings.

The next idea is to test specific support of CSS features, using a
proposed @supports() rule as suggested by this example from Felipe
Gasper:

      @supports(td:hover) {
	     /* CSS code */
      }

That's not a bad starting point.  However, it's hard to figure out how
the tests will be done, as the rule above seems to rely on a selector
(td:hover) and the question becomes, "well, what about support for
specific properties?"  I understand that Felipe's suggestion is not a
fully fleshed out proposal, so let's talk about the core concept.

The core concept is that only the browser knows exactly what the
browser is capable of -- there's no need for specific lists within the
style sheet that contain browser capabilities intelligence.  Each
browser is effectively self-identifying to specific tests applied
against it.

This, it turns out, is the same philosophy behind Composite Capabilities
and Preferences Profiles (CC/PP), which is a W3C recommendation for
creating browsers which are self-identifying.

Thus, an ideal "complete" solution would involve:

1.  Creating a CC/PP vocabulary for CSS3.
2.  Having each browser generate its own profile against the CSS3
     CC/PP vocab.
3.  Creating a way (perhaps based on @support or similar) for encoding
     CC/PP tests into CSS style sheets.

Once steps #1 and #2 are done, #3 is actually not that hard to do.
The good thing is that such a model might push along browser support
for CC/PP.

So let's talk about step #3.  Let's assume we've got some decent
way to do a test between CC/PP properties and values, and those will
include such things as a CC/PP encoded version of something like
"this supports outline when hovering over <td>."  While complex, this
shouldn't be impossible under a well-designed CC/PP vocabulary for
CSS3.  We'll call the exact encoding of this test "X", since the
encoding isn't the most important thing right now.

Here's an example CSS rule using this:

      @support("X") {
        td:hover { outline: 2px solid lime;
                   color: lime; }
      }

This isn't too bad, apart from the complexity of "X".

There might be some alternate approaches, such as using a :support()
pseudo-class on selectors for an additional check, like this:

      td:hover:support("outline") {
        outline: 2px solid lime;
        color: lime;
        /* only turn bright green if the "outline" property is
           supported for this selector */
      }

      :support("columns") #content {
        columns: 3;
        font-size: medium;
        /* only put this in medium columns if columns are
           supported */
      }

      #content {
        font-size: small;
        /* otherwise use small font size */
      }

I dunno.  Right now I'm thinking out loud.  What's clear to me is that
brainstorming is necessary, as well as not dismissing the need out
of hand.  The need exists, and if we don't give Web designers any
non-hack ways to meet that need, they'll just use hacks.

--Kynn

--
Kynn Bartlett <kynn@idyllmtn.com>                     http://kynn.com
Chief Technologist, Idyll Mountain                http://idyllmtn.com
Author, CSS in 24 Hours                       http://cssin24hours.com
Instructor, Blogging Basics Online Course    http://class.blogcap.com
Online Campaign Manager                   http://ByronForCongress.org

Received on Tuesday, 30 March 2004 15:27:46 UTC