Styling XML with CSS

by James Diacono 23. April 2010 05:26

I’m sure you’ve heard of XSLT (DON'T GO AWAY I'M NOT SUPPORTING XSLT!). XSLT is used to transform XML into different XML – for example, rendering XML as HTML.  An example:

The XSLT method

<album>
	<title>Funkentelechy Vs. The Placebo Syndrome</title>
	<artist>Parliament</artist> 
	<year>1976</year> 
	<funkativity>10</funkativity> 
</album>

can be transformed (using XSLT) to this:

<div class="album">
	<h1>Funkentelechy Vs. The Placebo Syndrome</h1>
	<p class="artist">Parliament</p>
	<p class="year">1976</p>
	<p class="funkativity">This album has a funkativity rating of 10/10</p>
</div>

Now the question is, "is h1 a better tagname for the artist of the album than artist?". I'm pretty sure the answer is no. However, the HTML engine has no idea how to display an artist tag - it treats every unknown tag like a span tag.

The pure CSS method

So display information has to come from somewhere else. Some people may find the idea of markup depending entirely on CSS for display abhorrent. I do not. I maintain that reading the source of the album XML block makes just as much sense as reading the rendered HTML version. And screenreaders...if I was a screenreader I'd want concise and descriptive XML, rather than having to wade through a bunch of HTML crap. And let's be real: everyone's web client supports CSS.

Styling XML with CSS is actually very simple and very robust. The first thing to understand is that HTML is just a custom namespace of XML. The second thing to understand is you can have multiple namespaces present in any XML document. That means you can use both HTML and, say, a custom namespace...which you can define and set styling rules.

I won't blather much more. I'll just fill you in on how CSS targets namespaces.

The CSS @namespace declaration

In short, I can write up a stylesheet which targets a specific namespace and only a specific namespace. My XML file would look like this:

<?xml version="1.0" encoding="UTF-8" ?>
<albums xmlns="http://jdiacono.org/music">
	<album>
		<title>Funkentelechy Vs. The Placebo Syndrome</title>
		<artist>Parliament</artist> 
		<year>1976</year> 
		<funkativity>10</funkativity> 
	</album>
<albums>

Here I declare that the XML inside and including the albums block is of the namespace http://jdiacono.org/music. Don't be misled by the namespace looking like a URL...I haven't even registered jdiacono.org and this is still valid. This is because namespaces are actually just unique, case-sensitive strings, and URLs tend to be unique and full of information. Let it be known that this block is all there is. It is a completely self descriptive block of pure data, which references nothing external.

Now to style this...here is my CSS:

@namespace url("http://jdiacono.org/music");

albums {
	display:block;
	}
	
album {
	display:list-item;
	list-style-type:decimal;
	margin-bottom:0.5em;
	padding:0.5em;
	border:1px solid;
	}
	
album title {
	display:block;
	font-size:2em;
	font-weight:bold;
	border-bottom:1px dashed;
	}
	
album artist {
	display:block;
	font-size:0.9em;
	}
	
album year {
	display:block;
	font-weight:bold;
	letter-spacing:0.4em;
	color:Green;
	}
	
album funkativity {
	display:block;
	font-style:italic;
	}
	
album funkativity:before {
	content: "This album has a funkativity rating of ";
	}
	
album funkativity:after {
	content: "/10";
	}

Now I have another example that is much more nourishing, which uses HTML and a custom XML namespace in the same page. You will need a browser other than IE to view this.

farmcode.org/sourcecode/cssNamespaces/cssNamespaces.xml

UPDATE: Looks like IE9 is supporting this!

Categories: CSS