CSS3 namespace selectors

Giving styles to XML documents with namespaces can be a really pain in the neck without the proper selectors. Consider the following XML fragment:

<p:Product xmlns:p="http://www.ns.com/ns/Product">
 <p:Code>This should be green.</p:Code>
 <p:Price>This should be purple.</p:Price>
</p:Product>

We want that both elements within the main container have two distinct colors. Surely you cannot write something like this:

p:Code {
  color: green;
}

p:Price {
  color: purple;
}

Because the ':' token is a pseudo-element delimiter in CSS, browsers will return a CSS parsing error (unknown pseudo-element). So you have to use CSS namespace selectors. The first thing to do is declaring a namespace rule in order to define what is the target namespace you're going to use:

@namespace p  "http://www.ns.com/ns/Product";

This rule accepts two arguments: the first is the local name of the XML element that has a given namespace, the latter is the namespace URI. Done this, you can go on and stylize the elements seen above:

p|Product * {
   display: block;
}

p|Code {
   color: green;
   font-weight: bold;
}

p|Price {
   color: purple;
   font-weight: bold;
}

The '|' selector deals with qualified names and matches the local name plus a given suffix occurring after the ':' token. Anyway, CSS namespace selectors allow you to declare more than one single namespace for stylesheet. For example, given an XML document like this:

<Order xmlns="http://www.ns.com/ns/Order"
xmlns:product="http://www.ns.com/ns/Product"
xmlns:client="http://www.ns.com/ns/Client">

  <product:Product>

     <product:Code>This should be green, bold, and with a thick green border.</product:Code>
     <product:Price>Foo</product:Price>

  </product:Product>
  
  <client:Client>

    <client:Code>This should be blue, italic, and with a thick green border.</client:Code>
    <client:Name>Foo</client:Name>
    <client:Address>Baz</client:Address>

  </client:Client>
  
  
  <info>This document should have a silver background.</info>



</Order>

you can use multiple namespaces in your CSS, just like this:

@namespace "http://www.ns.com/ns/Order";
@namespace product "http://www.ns.com/ns/Product";
@namespace client "http://www.ns.com/ns/Client";

Order {
  display: block;
  background-color: silver;
}

Order product|Product,
Order client|Client{
  display: block;
  border: thick solid green;
}


product|Code,
product|Price {
  font-weight: bold;
  color: green;
}

client|Code,
client|Name,
client|Address {
  font-style: italic;
  color: blue;
}

As you can see, we're actually using three namespaces here. Only remember one thing: namespace media rules must occur at the beginning of your stylesheet or they won't work. Just remember this key aspect to avoid any possible confusion.

The sad truth about CSS3 namespace selectors is that Internet Explorer doesn't support them at the time of this writing. We need to wait and hope.

One thought on “CSS3 namespace selectors”

  1. Hi Gabriele,
    thanks 4 your apport, I did not know about this new feature possible since CSS 3 namespace came out. Just 1 think: I was visiting other posts, and seems like is necessary to import in your xml a reference to the stylesheet, other way styles will be not applied to the xml nodes.
    Thanks again!

Leave a Reply

Note: Only a member of this blog may post a comment.