CSS: come usare i selettori di namespace

I selettori di namespace CSS3 al momento vengono utilizzati molto poco dagli sviluppatori. La motivazione principale sta nel fallimento quasi completo dei fogli di stile applicati ai documenti XML, nel senso che questa pratica è assai poco diffusa. Tuttavia, questi selettori risolvono dei problemi specifici.

Consideriamo questo frammento XML:


<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>

Vogliamo assegnare due colori diversi agli elementi. Ma se proviamo istintivamente a scrivere:


p:Code {
  color: green;
}

p:Price {
  color: purple;
}

otteniamo un errore, perché il token : è un delimitatore di uno pseudo-elemento o di una pseudo-classe nei CSS. Quindi dobbiamo utilizzare i selettori di namespace. Per prima cosa dichiariamo il namespace di riferimento:


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

Questa regola accetta due argomenti: il primo è il local name dell'elemento XML che ha quel namespace, il secondo è l'URI del namespace. Quindi:


p|Product * {
   display: block;
}

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

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

Il selettore | gestisce i qualified name e seleziona il local name più il suffisso che si trova dopo il token :. Le specifiche ci permettono di definire più di un namespace. Quindi dato un documento XML come questo:


<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>

potete usare namespace multipli:


@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;
}

L'unica cosa da tenere presente è che le regole @namespace devono sempre essere inserite all'inizio del foglio di stile o non funzioneranno.