Styling a Tree

The following describes how to style a tree.

Styling the Tree

You can style the tree border and the column headers in the same way as other elements. Style added to the tree element will apply to the entire tree. Adding a style to the treecol element does not cause the style to be applied to the column but only to the header.

The body of the tree must be styled in a somewhat different way than other elements. This is because the tree body is stored in a different way to other elements. The outer treechildren is the only real element in the tree body. The inner elements are just placeholders.

Setting Properties

Instead, you must use the properties attribute on the rows or cells to set one or more named properties. This can be used with trees with static content, RDF built content or with those with a custom view. Let's say we want a particular row to have a blue background color. This would be used to implement Mozilla Mail's labels feature. We'll use a property called 'makeItBlue'. You can use whatever name you want. You can set multiple properties by separating them with spaces.

Set the property on a row or cell, as in the following example:

<treerow properties="makeItBlue">

CSS Selectors for the Tree

The style sheet can take this property and use it to change the appearance of the row for unread messages or labels. You can think of the properties as functioning much like style classes, although they require a somewhat more complex syntax to use in a style sheet. This is because you can specify the style for a number of parts of the cell individually. You can style not only the cell and its text, but the twisty and indentation. The following is the syntax that needs to be used:

treechildren::-moz-tree-row(makeItBlue)
{
  background-color: blue;
}

This style which has a complex selector is used to style the background color of rows that have the 'makeItBlue' property. This special syntax is needed because the cells themselves are not separate elements. All of the content inside the tree's body is rendered by the treechildren element. However, CSS has a concept to access parts of elements considering them to be pseudo-elements. This selector matches some tree rows inside the treechildren element as pseudo-elements. The style sets style rules for particular parts of what it displays. This style rule means, inside a treechildren element, set the background color to blue for all tree rows that have the 'makeItBlue' property.

The text '::-moz-tree-row' specifies what content area is desired, which in this case is a row. You can also use the following values:

  • ::-moz-tree-cell: a cell. Use this to set borders and background colors.
  • ::-moz-tree-cell-text: the text in a cell. Use this to set the font and text color.
  • ::-moz-tree-twisty: the appearance of the twisty used to expand and collapse child rows.
  • ::-moz-tree-image: the image for a cell. You can set the image with the list-style-image property.
  • ::-moz-tree-row: a row. Use this to set the background color of a row.
  • ::-moz-tree-indentation: the indentation to the left of rows that are children of other rows.
  • ::-moz-tree-column: a column.
  • ::-moz-tree-line: the lines that are drawn to connect child rows to parent rows.
  • ::-moz-tree-separator: a separator in a tree.
  • ::-moz-tree-progressmeter: content for progressmeter cells. You can create a progressmeter column by setting the type attribute on the column to progressmeter.
  • ::-moz-tree-drop-feedback: the drag and drop feedback.
  • ::-moz-tree-checkbox: the image to use for checkbox columns.

You can check for multiple properties by separating them with commas. The example below sets the background color to grey for rows that have the 'readonly' and 'unread' properties. For properties that are 'readonly', it adds a red border around the row. Note that the first rule will apply to any row that is 'readonly' regardless of whether other properties such as 'unread' are set.

treechildren::-moz-tree-row(readonly)
{
  border: 1px solid red;
}
treechildren::-moz-tree-row(readonly, unread)
{
  background-color: rgb(80%, 80%, 80%);
}

Default Properties

The properties list for tree elements contain a small number of default properties, which you can also use in a style sheet. You can use these extra properties to set the appearance of containers or selected rows. The following properties are automatically set as needed:

checked
this property is set cells whose column is type="checkbox"
focus
this property is set if the tree currently has the focus.
selected
this property is set for rows or cells that are currently selected.
current
this property is set if the keyboard cursor is at the row. Only one row will have this property set at a time.
hover
this property is set if the mouse cursor is on the row. Only one row will have this property set at a time.
container
this property is set for rows or cells that have child rows.
leaf
this property is set for rows or cells that do not have child rows.
open
this property is set for rows or cells which are expanded.
closed
this property is set for rows or cells which are collapsed.
primary
this property is set for cells in the primary column.
sorted
this property is set for cells in the current sorted column.
even
this property is set for even numbered rows.
odd
this property is set for odd numbered rows. This property, along with the even property allow you to set, for example, alternating colors for each row.
dragSession
this property is set if something is currently being dragged.
dropOn
if a drag is occuring over the tree, this property is set for the row currently being dragged over, as long as the mouse pointer is hovering over the row.
dropBefore
this property is set if the mouse pointer is hovering before the row currently being dragged over.
dropAfter
this property is set if the mouse pointer is hovering after the row currently being dragged over.
progressNormal
this property is set for progress meter cells.
progressUndetermined
this property is set for undeterminate progress meter cells.
progressNone
this property is set for non-progress meter cells.

The properties are set for rows or cells in rows with the necessary state. For columns and cells, one additional property, the id of the column or column the cell is in will be set.

Setting Properties for the RDF-built Trees

For RDF-built trees, you can use the same syntax. However, you will often set the properties based on values in the datasource.

Setting Properties for the Custom View

For trees with a custom view script, you can set properties by supplying the functions getRowProperties(), getColumnProperties() and getCellProperties() in the view. These return information about an individual row, column and cell. Arguments to these functions indicate which row and/or column.

Prior to Gecko 22 the last argument to each of these functions is a properties list which the view is expected to fill with a list of properties. The function getColumnProperties() also supplies the corresponding treecol element for the column.

getRowProperties : function(row,prop){}
getColumnProperties : function(column,columnElement,prop){}
getCellProperties : function(row,column,prop){}

From Gecko 22 you can return a string of space-separated property names from these functions.

getRowProperties : function(row){ return ''}
getColumnProperties : function(column,columnElement){ return ''}
getCellProperties : function(row,column){ return ''}

Let's look at an example of changing a specific cell. Let's make every fourth row have blue text, using the example from a previous section. We'll need to add code to the getCellProperties() function, to add a property 'makeItBlue' for cells in every fourth row. (We don't use getRowProperties() as the text color will not be inherited into each cell.)

Prior to Gecko 22 the properties object that is passed as the last argument to the getCellProperties() is an XPCOM object that implements nsISupportsArray. It is really just an XPCOM version of an array. It contains a function AppendElement() which can be used to add an element to the array. We can use the interface nsIAtomService to construct string atoms for the properties.

getCellProperties: function(row,col,props){
  if ((row %4) == 0){
    var aserv=Components.classes["@mozilla.org/atom-service;1"].
              getService(Components.interfaces.nsIAtomService);
    props.AppendElement(aserv.getAtom("makeItBlue"));
  }
}

The properties list requires an array of atom objects, which can be thought of as constant strings. We create them using the XPCOM interface nsIAtomService and add them to the array using the AppendElement() function. Here, we create an atom 'makeItBlue'. You can call AppendElement() again to add additional properties.

From Gecko 22 your function should return a string containing the property.

getCellProperties: function(row,col){
  if ((row %4) == 0){
    return "makeItBlue";
  }
}

To support Gecko versions before and after this change use.

getCellProperties: function(row,col,props){
  if ((row %4) == 0){
    if (props) {
      var aserv=Components.classes["@mozilla.org/atom-service;1"].
                getService(Components.interfaces.nsIAtomService);
      props.AppendElement(aserv.getAtom("makeItBlue"));
    } else {
      return "makeItBlue";
    }
  }
}

This function would be defined as part of a view object. It first checks to see which row is being requested and sets a property for cells in every fourth row.

Example style sheet

treechildren::-moz-tree-row(selected)            { background-color: #FFFFAA; }
treechildren::-moz-tree-row(odd)                 { background-color: #EEEEEE; }
treechildren::-moz-tree-row(odd, selected)       { background-color: #FFFFAA; }
treechildren::-moz-tree-cell-text(selected)      { color: #000000; }
treechildren::-moz-tree-cell-text(odd, selected) { color: #000000; }

Note that you can also style e.g. all rows, without the need of using properties; see Building Trees for an example.

Next, we'll look at how to modify the default skin.

Document Tags and Contributors

 Last updated by: Sheppy,