Adding Style Sheets

We have hardly modified the look of the elements we have created so far. XUL uses CSS (Cascading Style Sheets) to customize elements.

Style Sheets

A style sheet is a file which contains style information for elements. It was originally designed for HTML elements but can be applied to XUL elements also, or to any XML for that matter. The style sheet contains information such as the fonts, colors, borders, and size of elements.

Mozilla applies a default style sheet to each XUL window. In many cases, it will suffice to leave the defaults as is. Other times, however, you will want to provide a custom style sheet. In general, you will associate a single style sheet with each XUL file.

You can place a style sheet anywhere you wish. If your XUL file is stored remotely and accessed via an HTTP URL, you can store the style sheet remotely as well. If you are creating a XUL package to be installed as part of the chrome system, you have two choices. First, you could store the style sheet in the same directory as the XUL file. This method has the disadvantage because it means your application will not be themeable. The second method involves placing your files as part of a theme.

Let's assume that we are building the find files dialog for themeability, because the find files dialog can be referred to with the URL chrome://findfile/content/findfile.xul so the style sheet file will be stored in chrome://findfile/skin/findfile.css.

All the XUL examples so far have actually been using a style sheet already. The second line has always been:

<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

This line indicates that we want to use the style provided by chrome://global/skin/. In Mozilla, this will be translated as the file global.css, which contains default style information for XUL elements. You could leave the line out and the elements will still work, however they will look fairly plain. The style sheet applies various fonts, colors and borders to make the elements look more suitable.

Changing the Styles

However, there will be times when the default look of elements will not give the look that is desired. For this, we will need to add a style sheet of our own. So far, we have been applying styles using the style attribute on elements. Although this works, it is not really the best thing to do. It is much better to create a separate style sheet. The reason is so that different looks, or skins, can be applied easily.

There may be certain cases where the style attribute is acceptable. An example would be when a script changes the style, or where a difference in layout might change the meaning of the element. However you should avoid this as much as possible.

For installed files, you'll have to create or modify a manifest file and install the skin.

Our Find Files Dialog Example

Let's modify the find files dialog so that its style comes from a separate style file. First, the modifed lines of findfile.xul:

<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="findfile.css" type="text/css"?>
  ...
<spacer class="titlespace"/>
  <groupbox orient="horizontal">
    <caption label="Search Criteria"/>

      <menulist id="searchtype">
        <menupopup>
          <menuitem label="Name"/>
          <menuitem label="Size"/>
          <menuitem label="Date Modified"/>
        </menupopup>
      </menulist>
      <spacer class="springspace"/>
      <menulist id="searchmode">
        <menupopup>
          <menuitem label="Is"/>
          <menuitem label="Is Not"/>
        </menupopup>
      </menulist>

      <spacer class="springspace"/>
      <menulist id="find-text" flex="1"
          editable="true"
          datasources="file:///mozilla/recents.rdf"
          ref="http://www.xulplanet.com/rdf/recent/all"/>
  ...
<spacer class="titlespace"/>
<hbox>

  <progressmeter id="progmeter" value="50%" style="display:none;"/>

The new xml-stylesheet line is used to import the style sheet. It will contain the styles instead of having them directly in the XUL file. You can include any number of style sheets in a similar way. Here the style sheet is placed in the same directory as findfile.xul.

Some of the styles in the code above have been removed. One that wasn't was the display property on the progressmeter. This will be changed by a script so it was left in, as it doesn't really make sense to have the progress bar visible initially. You could still put this in a separate style sheet if you really wanted to. A class was added to the spacers so that they can be referred to.

A style sheet also needs to be created. Create a file findfile.css in the same directory as the XUL file. (It would normally be put into a separate skin). In this file, we'll add the style declarations, as shown below:

#find-text {
  min-width: 15em;
}

#progmeter {
  margin: 4px;
}

.springspace {
  width: 10px;
}

.titlespace {
  height: 10px;
}

Notice how these styles are equivalent to the styles we had before. However, it is much easier for someone to change the look of the find files dialog now because they could add or modify the style declarations by either modifying the file or by changing the skin. If the user changes the interface skin, the files in a directory other than default will be applied.

Importing Style Sheets

We've already seen how to import style sheets for use. An example is shown below:

<?xml-stylesheet href="chrome://bookmarks/skin/" type="text/css"?>

This might be the first lines of a bookmarks window. It imports the bookmarks style sheet, which is bookmarks.css. Mozilla's skin system is smart enough to figure out which style sheet to use, because the specific filename was not indicated here. We have done a similar thing with the global style sheet file (chrome://global/skin).

A style sheet may import styles from another stylesheet using the import directive. Normally, you will only import one style sheet from each XUL file. The global style sheet can be imported from within the style sheet associated with the XUL file. This can be done with the code below, allowing you to remove the import from the XUL file:

Style import from XUL:
<?xml-stylesheet href="chrome://global/skin/"  type="text/css"?>

Style import from CSS:
@import url(chrome://global/skin/);

The second syntax is preferred because it reduces the number of dependencies within the XUL file itself.

Remove the global style sheet import from findfile.xul and add the import to findfile.css.

All elements can be styled using CSS. You can use selectors to select the element that you wish to have styled. (The selector is the part before the curly brace in a style rule). The following list summarizes some of the selectors available:

button
Matches all button tags.
#special-button
Matches the element with an id of special-button.
.bigbuttons
Matches all elements with a class of bigbuttons.
button.bigbuttons
Matches all button elements with a class of bigbuttons.
toolbar > button
Matches all buttons that are directly inside toolbar elements.
toolbar > button.bigbuttons
Matches all button elements with a class of bigbuttons that are directly inside toolbar elements.
button.bigbuttons:hover
Matches all button elements with a class of bigbuttons but only while the mouse is over them.
button#special-button:active
Matches all button elements with an id of special-button but only while they are active (being clicked on).
box[orient="horizontal"]
Matches all box elements that have an orient attribute that is set to horizontal.

You can combine these rules in any way that you wish. It is always a good idea to be as precise as possible when specifying what gets styled. It is more efficient and it also reduces the likelihood that you'll style the wrong thing.

Find files example so far : Source View

In the next section, we will look at how to apply styles to trees.