views:

177

answers:

3

I'm developing an application that uses ubiquity-xforms. Previously I had been serving the pages up as text/html with the XHTML 1.0 doctype.

If I switched the mime-type to application/xhtml+xml, I would see a pretty big performance improvement, because the javascript could use the get____NS() functions, instead of what it's doing now (slowly iterating through the entire DOM tree every time it needs to select an element).

But when I tried this, a bunch of my CSS stopped working. I noticed that when I inspected the elements, either in Firebug or in the WebKit Nightly Web Inspector, the point of failure were '.classname' and '#id' css selectors on elements in the XFORMS namespace. I also noticed that in the listed DOM properties for those elements they were lacking both 'id' and 'className' attributes.

My question is, is there a way that I can get the UA to recognize these as classes and ids?

Things I've tried, to no avail:

  1. specifying the "id" attributes as ID in an inline doctype's ATTLIST
  2. trying every doctype I could, or no doctype at all
  3. qualifying the id and class name attributes in the xhtml namespace (ie. xhtml:id)

Here's some sample xhtml. Doesn't work in either Firefox 3.5 or Safari 4 / WebKit Nightly

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
  xmlns:xf="http://www.w3.org/2002/xforms"&gt;
<head>
    <style type="text/css">
    /* <![CDATA[ */
    #test {
        background-color: red;
    }
    .testing {
        color: blue;
    }
    /* ]]> */
    </style>
</head>
<body>
    <xf:group id="test" class="testing">Test</xf:group>
</body>

A: 

You have no doctype, character encoding, etc. Here you go:

Change to this exactly:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;

<head>
    <!--Always include character encoding and content-type-->
    <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
</head>
orokusaki
I suppose I could have been more clear, but I didn't include those because they did not seem to make a difference with regard to my problem. Even with that doctype, or any other XHTML or HTML5 doctype, the problem persists that I can't style elements not in the xhtml namespace with #id and .classname css selectors
Frankie
I've also read that you shouldn't include a doctype if you are serving content as application/xhtml+xml, but it seems like reasonable people differ on the topic. I don't really care either way, as long as I don't have to switch all of my #idname to *|*[*|id='idname'] in the css or whatever nonsense it would require
Frankie
I don't understand. I just copied your exact code into Dreamweaver and replaced the top with my version and it worked perfectly fine in Safari, and Firefox 3.5 (didn't test Chrome, IE6, et al).
orokusaki
The doctype should be included not just because of what others say but because it determines what style of rendering your browser uses (ie, Qwarks mode, etc). The W3 is who invented XHTML and they say use a doctype or else your code is not compliant. It's not to say they set the law, but they did create the specification and browsers are built according to their specs (hence Google Gears to get around spec limitations without building Chrome outside of spec).
orokusaki
The key is that the content has to be served with the mime-type application/xhtml+xml. I'm not sure how you can get it to open that way when it is stored locally (perhaps a .xhtml extension? It probably varies by platform).True XHTML mode is only triggered in Safari and Firefox if it is sent with "Content-Type: application/xhtml+xml" headers (with or without charset). It seems to ignore the <meta> content-type declaration.So yes, the same page, when I send it from my server as "text/html" looks perfectly fine, but as soon as I change the Content-Type it all goes to hell.
Frankie
And by "goes to hell" I mean that it doesn't style xform elements with id (#) and class (.) selectors in the css
Frankie
Oh, geese. I tried it on my server and the same thing happened which I obviously did not expect. If you pass it as text/html and set the application/xhtml+xml in your <meta /> you may have better luck, but if you can't change that I don't know what to suggest. I'm sorry.
orokusaki
This `<meta>` is ridiculous. It's read only in `text/html` mode, so at best it's self-contradictory and ignored.
porneL
@porneL Really. So, the content meta doesn't affect any modern browser?
orokusaki
@orokusaki it only affects charset in `text/html` documents. It can never change type of document. It's completely ignored in `application/xhtml+xml` documents. To change type of document you _must_ use real HTTP headers. Metatags, DOCTYPEs or anything in the document itself cannot work.
porneL
+1  A: 

You don't have to use #id/.class selectors. Instead you can use:

[id=test] {}
[class|=testing] {}

which are equivalent.

AFAIK class is HTML-specific thing, and because XML namespaces are completely insane, XHTML attributes aren't in the XHTML namespace! You're probably out of luck with this one.

For ID you might try xml:id, but I haven't checked if anything actually supports it.

In case you wanted to match namespaced elements, that's possible with CSS Namespaces:

@namespace xf "http://www.w3.org/2002/xforms";
xf|group {}
porneL
+4  A: 

Frankie,

porneL's answer is right -- in XHTML mode you have to use different CSS rules, because there is nothing 'special' about @id an @class.

Even armed with this knowledge, your problems aren't over though. :)

The temptation might be to just put HTML and XHTML CSS selectors together, and apply them to the same rule:

@namespace xf url(http://www.w3.org/2002/xforms);

xf\:input.surname, xf|input[class~="surname"] {
  color: green;
}

However, a further problem is that IE will ignore the entire rule, because it doesn't like the XHTML syntax. So littered through Ubiquity XForms you'll see things like this:

@namespace xf url(http://www.w3.org/2002/xforms);

xforms\:hint.active, xf\:hint.active {
  display: inline;
}

xf|hint[class~="active"] {
  display: inline;
}

As you can see we've had to repeat the styling with different selectors. (This is something we're hoping to address with a function that will abstract out the style-setting task. Then you'll only have to write one rule.)

Note a couple of extra things:

  • that the HTML rules are using ':' as a literal character (hence the '\' to escape), and know nothing of namespaces;
  • the XHTML CSS rules use the '~=' operator, which means that the attribute must contain the value specified, rather than be exactly equal to it.
Mark Birbeck
Since I'm developing an internal application I was given permission to set the browser requirements, so IE isn't a problem (baseline is Firefox 3.6 and Safari 4).I was hoping that I could avoid having to modify all of the styles, but it looks like I don't have much of a choice.
Frankie