24

CSS and XML

Share on TwitterShare on TumblrSubmit to StumbleUponSave on DeliciousDigg This

In this article I’ll explain how to format a well-formed XML document by using CSS. The techniques explained below can be used to stylize an (X)HTML document as well.

Table of contents

Adding a style sheet to an XML document

To add a style sheet to an XML document, you need only to insert the following declaration at the beginning of your file.

Listing 1. Adding a style sheet to an XML document

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <?xml-stylesheet href="style.css" type="text/css"?>

Keep in mind that the href attribute of the style sheet declaration works exactly as its (X)HTML counterpart, the link element. In this case we’re using a relative URL because the style sheet shares the same directory with the XML document.

Choosing the appropriate markup

When choosing the markup for our document, we should only keep in mind that the names of the elements should be meaningful and semantic. For example, the markup for a blog could be the following.

Listing 2. The markup for a blog

  1. <blog>
  2. <header>
  3. <title>My Blog</title>
  4. </header>
  5. <navigation>
  6. <current>Home</current>
  7. <nlink xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
  8. xlink:href="#">Articles</nlink>
  9. ...omission...
  10. </navigation>
  11. <content>
  12. <post>
  13. <ptitle>Post title</ptitle>
  14. <pdate>7/19/2008</ptitle>
  15. <para>Lorem ipsum dolor...</para>
  16. ...omission...
  17. <plink xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
  18. xlink:href="#">Permanent link to this article</plink>
  19. </post>
  20. ...omission...
  21. </content>
  22. <extra>
  23. <etitle>Blogroll</etitle>
  24. <elist>
  25. <elink xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
  26. xlink:href="#">Link 1</elink>
  27. ...omission...
  28. </elist>
  29. </extra>
  30. <footer>
  31. <signature>Gabriele Romanato</signature>
  32. </footer>
  33. </blog>

View the exampleView the screenshot

As you can see, the document is rendered as a whole set of anonymous text, since browsers can’t actually use their default style sheet nor their predefined algorithms to give a basic formatting to our elements which are, in fact, completely unknown to them. However, the resulting DOM tree is perfectly consistent and we can summarize it as follows.

  • blogIt’s the actual root element of our document.
    • headerThe header section of our blog.
      • titleThe document’s title.
    • navigationThe navigation menu of our blog.
      • currentThe current section of our blog.
      • nlinkA navigation link. To insert hyperlinks in a XML document, we can use XLink. For the time being, this feature is supported only by Gecko-based browsers.
    • contentThe main section of our blog.
      • postA post of our blog.
        • ptitleThe title of a post.
        • pdateThe date of a post.
        • paraA simple paragraph.
        • plinkThe permanent link to a post.
    • extraA section with miscellaneous things.
      • etitleThe title for this section.
      • elistA list of links.
        • elinkA link to an external site, for example a friend’s site.
    • footerThe footer section of our blog.
      • signatureThis element can contain the author’s name or a copyright notice.

Basic styles

As we’ve seen above, our elements are unknown to browsers, so we have to specify a formatting role for each element. Let’s start with declaring block-level elements.

Listing 3. Declaring block-level elements

  1. blog, header,
  2. title, post,
  3. ptitle, pdate,
  4. para, plink,
  5. etitle, footer,
  6. signature {
  7. display: block;
  8. }

View the exampleView the screenshot

Now elements start to take their form. Let’s go on with our root element.

The root element

The root element will set a basic backbone for our layout. The attached styles are very simple.

Listing 4. Styles for the root element

  1. blog {
  2. margin: 0;
  3. width: 100%;
  4. height: 100%;
  5. min-height: 100%;
  6. background: #fff;
  7. color: #333;
  8. font: 0.85em/1.5 Arial, Helvetica, sans-serif;
  9. }

View the exampleView the screenshot

Since we want a full page layout, we set a width and a height equal to 100% of the browser window. The declaration of a minimum height stretches the root element until it reaches the bottom edge of the window. This declaration is especially useful when we’re dealing with different background colors, due to the fact that in XML the root element is not “magic” as in (X)HTML. Now we can go on with our header.

The header will have a background image as a banner. So we can write the following.

Listing 5. Styles for the header

  1. header {
  2. height: 6em;
  3. background: #000 url("img/banner.jpg") no-repeat 0 0;
  4. color: #fff;
  5. }

View the exampleView the screenshot

As you can see, we’ve set a height in ems, so that the text and the banner’s height will scale accordingly. It’s important to notice that we’ve also specified a background color in the case that the image is not available. Obviously the text’s color should be set with the right contrast.

The title

The title will be simple text, so the styles are the following.

Listing 6. Styles for the title

  1. title {
  2. font: italic 3em/normal Georgia, serif;
  3. margin-left: 25%;
  4. }

View the exampleView the screenshot

We’ve reduced the line-height to normal in order to put the text on the top of the header. At the same time, we’ve pushed the text rightwards by using a left margin expressed in percentages. Now it’s time to take care of our navigation menu.

We want a simple tabbed menu with a rollover effect and different styles for the current section. So we could write the following.

Listing 7. Styles for the navigation menu

  1. navigation {
  2. display: block;
  3. width: 100%;
  4. height: 1.4em;
  5. background: #333;
  6. color: #fff;
  7. }
  8. current, nlink {
  9. float: left;
  10. width: 10%;
  11. height: 1.4em;
  12. line-height: 1.4em;
  13. margin: 0 0.5em;
  14. text-align: center;
  15. font-weight: bold;
  16. }
  17. nlink {
  18. text-decoration: none;
  19. color: #ffc;
  20. cursor: pointer;
  21. }
  22. nlink:hover {
  23. background: #fff;
  24. color: #333;
  25. }
  26. current {
  27. text-transform: uppercase;
  28. margin-left: 1em;
  29. background: #fff;
  30. color: #333;
  31. }

View the exampleView the screenshot

Since we want to use floats, we have to set an explicit height for the floats container in order to prevent space from collapsing. The height of the floated elements equals the height of their container, and this is a basic aspect to grasp when dealing with tabbed menus. Moreover, the height of elements is expressed in ems, so that it scales along with text, and their width is specified in percentages, so that it scales along with browser’s window. For the vertical centering of text inside the floats, we’ve specified a line-height equal to the height of the elements. Since the line-height of the elements is 1.4em, we have an half line-height of 0.7em, so that the text will have the same amount of space above and belove itself. The current section gains its tabbed effect by specifying a white background.

Finally, since the overwhelming majority of web browsers don’t support XLink, we have to change the default appearance of the cursor by turning it into a pointer. Note that this declaration is pointless in a browser that supports XLink.

The main sections

Now it’s time to start stylizing our main sections, content and extra. We want to create a two-columns layout. The styles are the following.

Listing 8. Styles for the main sections

  1. content {
  2. float: left;
  3. width: 58%;
  4. margin: 2%;
  5. }
  6. extra {
  7. float: left;
  8. width: 23%;
  9. margin: 2% 0;
  10. }

View the exampleView the screenshot

We’ve used floating to create a simple two-columns layout. By specifying dimensions in percentages, we’ve actually created a fluid layout that will scale along with browser’s window.

The content section

Let’s go on with the content section by using the following styles.

Listing 9. Styles for the content section

  1. post {
  2. padding: 0 15%;
  3. background: transparent url("img/quote1.gif") no-repeat 8% 1%;
  4. }
  5. ptitle {
  6. margin-bottom: 0.5em;
  7. line-height: normal;
  8. border-bottom: 1px dotted #999;
  9. font: italic 1.4em Georgia, serif;
  10. color: #666;
  11. }
  12. pdate {
  13. float: right;
  14. padding: 0.4em;
  15. background: #666;
  16. color: #fff;
  17. font-weight: bold;
  18. }
  19. para {
  20. margin-bottom: 0.5em;
  21. }
  22. plink {
  23. margin-bottom: 0.5em;
  24. padding-top: 0.1em;
  25. border-top: 3px double #999;
  26. color: #00c;
  27. text-decoration: underline;
  28. text-indent: 1.4em;
  29. background: transparent url("img/file.gif") no-repeat 0 50%;
  30. cursor: pointer;
  31. }

View the exampleView the screenshot

Two things are interesting here: background images (on the post and plink elements) and fluid floats (the pdate element). When dealing with background images, keep in mind that the dimensions of the host element should be proportional to the dimensions of the hosted images. If an element is not wide enough to host a background image, the image will be cropped or not displayed at all. Another thing to keep in mind is the order of values in the background-position property: the first values refers to the horizontal axis (x), from left to right, while the second refers to the vertical axis (y), from top to bottom. So the values 0 50% on the plink element mean “put the image on the left and center it vertically”.

Fluid floats are a little bit tricky. With the expression fluid floats I mean floated elements without any stated dimension. In this case, CSS specifications state that a browser should apply the shrink-to-fit algorithm, that is, the dimensions of the float will be determined by the amount of content inside the element. This turns out to be particularly useful in the case of little chunks of text that need to be floated, such as blog dates.

The extra section

In this section we have a vertical navigation menu with a rollover effect.

Listing 10. Styles for the extra section

  1. etitle {
  2. background: #666;
  3. color: #fff;
  4. padding: 0.2em;
  5. text-indent: 0.5em;
  6. font: 1.3em/normal Georgia, serif;
  7. margin-bottom: 0.5em;
  8. }
  9. elist {
  10. display: block;
  11. margin-left: 0.8em;
  12. margin-right: 0.8em;
  13. }
  14. elink {
  15. display: block;
  16. margin-bottom: 0.5em;
  17. border-bottom: 1px solid #999;
  18. line-height: normal;
  19. padding-bottom: 0.1em;
  20. text-decoration: none;
  21. cursor: pointer;
  22. color: #00c;
  23. }
  24. elink:hover {
  25. background: transparent url("img/flower.png") no-repeat 100% 50%;
  26. color: #00f;
  27. }

View the exampleView the screenshot

In this case, the background image is shifted rightwards by using 100% as the first value of the background-position property. To align the image vertically to the text, we’ve used the value 50% and we’ve reduced the line-height of the elink element.

The following styles are similar to the header’s ones, with some exceptions.

Listing 11. Styles for the footer

  1. footer {
  2. clear: left;
  3. background: #333 url("img/footer.jpg") no-repeat 0 0;
  4. color: #fff;
  5. height: 4em;
  6. line-height: 4em;
  7. font: italic 1.3em Georgia, serif;
  8. }
  9. signature {
  10. text-align: center;
  11. height: 4em;
  12. line-height: 4em;
  13. }

View the exampleView the screenshot

Since we’ve used the float property on the main sections, we have to restore the normal flow by using the clear property with its value set to left because of the floating direction.

The final touch

To complete our layout, we add a background image to the root element.

Listing 12. Adding a background image to the root element

  1. blog {
  2. background-image: url("img/me.png");
  3. background-repeat: no-repeat;
  4. background-position: 80% 24em;
  5. }

View the exampleView the screenshot

The second value of the background-position property comes from a rough calculation that takes into account the overall height of the header and extra sections. 24em is a good value, since it scales along with text so that we can avoid dealing with browsers discrepancies in the calculations of percentages related to the vertical positioning of a background image.

Download examples

examples.zip

prajapat