We have hardly modified the look of the elements we have created so far. XUL uses CSS (Cascading Style Sheets) to customize elements.
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 do the same for the style sheet. 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 that in means your application will not be skinnable. The second method involves placing your files as part of a skin.
Let's assume that we are building the find files dialog for skinability. Our find files dialog can be refered to with the URL chrome://findfile/content/findfile.xul so the style sheet file will stored in chrome://findfile/skin/filefile.css. The only difference is the skin directory instead of content.
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.
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 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 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.
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"?>
...
<spring class="titlespace"/>
<titledbox orient="horizontal">
<title>lt;text value="Search Criteria"/></title>
<menulist id="searchtype">
<menupopup>
<menuitem value="Name"/>
<menuitem value="Size"/>
<menuitem value="Date Modified"/>
</menupopup>
</menulist>
<spring class="springspace"/>
<menulist id="searchmode">
<menupopup>
<menuitem value="Is"/>
<menuitem value="Is Not"/>
</menupopup>
</menulist>
<spring class="springspace"/>
<box context="editpopup" flex="1">
<textfield id="find-text" flex="1" context="editpopup"/>
</box>
...
<progressmeter id="progmeter" value="50%" style="display:none;"/>
...
<button id="find-button" class="dialog" value="Find" default="true"
onclick="doFind();"/>
<button id="cancel-button" class="dialog" value="Cancel" onclick="window.close();"/>
|
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 springs so that they can be refered to.
A style sheet also needs to be created. Create a file findfile.css in the directory chrome/skins/modern/findfile/skin. You'll have to create some directories too. In this file, we'll add the style declarations, as shown below:
#find-text {
min-width: 15em;
}
#progmeter {
margin: 4px;
}
#find-button {
width: 8ex;
}
#cancel-button {
width: 8ex;
}
.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.
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, since the specific filename was indicated here. We have done a similar thing with the global style sheet file (chrome://global/skin).
CSS has a command for importing other style sheets from with-in another one. Normally, you will only import one style sheet from each XUL file. The global style sheet can be imported from with-in 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 prefered because it reduces the number of dependencies with-in 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 table 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.bugbuttons: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.
(Next) In the next section, we will look at how to change the default Mozilla skin.