Styling

Since formsPlayer is hosted inside Internet Explorer, it relies on IE for its CSS support, which is mainly CSS 1, plus a little of CSS 2. This means that fP does not support namespaces, or the new pseudo-elements and pseudo-classes defined for XForms. However, there are various workarounds that have been added to give the author control over the look-and-feel of their forms, and many of these workarounds have been adopted by other processors.

Namespace support

Assuming that the XForms namespace has been defined with the prefix xf, setting all XForms input controls to have a blue background would require the following style rule:

xf\:input
{
  background-color: blue;
}

Note that unlike the 'proper' namespace support defined in CSS 2.1, the prefix used here must exactly match the prefix used in the mark-up since all that is happening is the element called 'xf:input' being matched.

Pseudo-classes

Pseudo-classes are classes that are automatically added and removed from controls in a form. For example, if a control is bound to some data that is invalid then the control will have the pseudo-class :invalid, but the moment that the data becomes valid again, the control will have the pseudo-class :valid. This change of state is carried out by the processor, and the author does not need to write any code to take advantage of this.

Blurred

The :blurred pseudo-class is applied to controls that have received focus at some point. A typical use is to style invalid controls in such a way that they are not shown as invalid (for example, with a red border) until the user has visited them.

A control that has had the focus can be styled as follows:

.pc-blurred
{
  border : 1px solid blue;
}

Enabled/Disabled

The :enabled and :disabled pseudo-classes are applied to controls when the instance data they are bound to becomes relevant or not.

The CSS rules to use for these pseudo-classes are:

.pc-enabled {
    display    :   block;
    background-color   :   gray;
}

and

.pc-disabled {
    display    :   none;
}

Focus

The :focus pseudo-class is applied to controls when they receive focus. A use could be to draw attention to the current field when a user tabs through controls on a form.

The CSS rule to style a control that has focus is:

.pc-focus {
  border : 1px solid green;
}

Hover

The ::hover pseudo-class is set on an element when the mouse is over it.

The following examples changes the background colour of items in a repeat when the mouse is over them:

xf\:repeat .pc-hover
{
  background-color : silver;
}

Read only/Read write

The :read-only and :read-write pseudo-classes are applied to controls when the instance data they are bound to has a model item property of readonly with a value of true or false.

The CSS classes needed to style controls are:

.pc-read-only {
    background-color  :  #E0E0E0;
}

.pc-read-write {
    background-color  :   #FFFFFF;
}

Required/Optional

The :required and :optional pseudo-classes are applied to controls when the instance data they are bound to becomes required or not via the model item property 'required'.

The CSS rules to use for these pseudo-classes are:

.pc-required {
    border : 1px solid red;
}

and

.pc-optional {
    border : 0px;
}

Valid / Invalid

The :valid and :invalid pseudo-classes are applied to controls when they are made valid or invalid by instance data model item properties such as 'type'.

The CSS rules to style controls that valid or invalid are:

.pc-valid {
    
}

and

.pc-invalid {
    border   :   1px solid red;
}

Pseudo-elements

The pseudo-element ::value is represented as an element with a class of 'value'. To style this element we would normally use the following syntax:

xf\:input .value
{
 width: 100px;
}

Note the space between xf\:input and .value; this is the CSS syntax for 'descendant of'. However, in the current formsPlayer architecture this won't work, and there are two alternatives.

The first is that an additional class 'input-value' is available. For example, we can set the size of the pseudo-element ::value on all inputs (i.e., the pseudo-element that would normally be addressed as xf:input::value), by doing this:

.input-value
{
 width: 100px;
}

The same pattern is used for all the controls, for example:

.select1-value
{
 width: 100px;
}

If you need to set styling on a narrower range of controls then it is possible to use classes:

.fc1 .value
{
 width: 100px;
}

<xf:input ref="firstName" class="fc1">
 <xf:label>First Name:</xf:label>
</xf:input>

However, the following will not work:

xf\:input.fc1 .value
{
 width: 100px;
}

Default style

Internet Explorer doesn't provide a way to allow default style rules. This can be confusing for new authors, since all alert messages and non-relevant controls will be viewable by default.

A typical default rule for alert would say that any xf:alert that is a child of a valid form control should be 'hidden':

.valid xf\:alert
{
  display: none;
}

A typical default rule for 'disabled' form controls would say that any control that is disabled should be 'hidden':

.disabled
{
  display: none;
}

Note that we use display: none; in both cases, since visibility: hidden; reserves the space that an element would take up.

Selection lists

Each of the items in a xf:select1 or xf:select is actually a CSS 'list item'. This means that each item in the selection list can have its appearance controlled using the list-style-image CSS property. The default style is for items in a xf:select1 to have a radio button, and for xf:select items to use a check-box. To indicate that there should be no images, simply set the list style image to nothing:

<style>
  xf\:select1.my-select xf\:item xf\:label
  {
    list-style-image: none;
  }
</style>
.
.
.
<xf:select ref="x" class="my-select">
  ...
</xf:select>

When an item is selected by a user, it acquires the pseudo-class 'selected', and similarly those which are not currently selected have the pseudo-class 'deselected'. With these pseudo-classes it is possible to use any CSS properties to indicate the state of the items to the user. For example, to modify our selection list such that selected items show as white on black, whilst unselected items are to be black on white, we would use the following CSS rules:

.my-select .pc-deselected
{
  background-color: white;
  color: black;
}

.my-select .pc-selected
{
  background-color: black;
  color: white;
}

NOTE: In versions prior to 1.5.5.1014 the pseudo-classes are 'selected' and 'deselected'.

When the mouse is moved over an item, that item acquires the pseudo-class 'hover'. The default style for a hovered item is to change the background colour to cyan, but this can be overridden. For example, to set the hover style of selected and unselected items in the xf:select above, we would do this:

.my-select xf\:item.pc-selected.pc-hover,
.my-select xf\:item.pc-deselected.pc-hover
{
  background-color: blue;
}

NOTE: In versions prior to 1.5.5.1014 the pseudo-class is 'hover'.

Note that simply using pc-hover wouldn't be sufficient to override this, since the rule needs to be more specific.

The 'selected' and 'deselected' pseudo-classes also allow more specific images to be used to give the form user better feedback. For example, if we have a list of items and want to show a happy face when one is selected, but a sad one otherwise, we would use the following style rules:

.my-select xf\:item.pc-selected xf\:label
{
  list-style-image: url("happy.gif");
}

.my-select xf\:item.pc-deselected xf\:label
{
  list-style-image: url("sad.gif");
}

The appearance state of a xf:select1 or xf:select is also available as a CSS pseudo-class. To illustrate its use, the following CSS rules will remove the radio buttons for all minimal xf:select1 elements:

xf\:select1.attr-appearance-minimal xf\:item xf\:label
{
  list-style-image: none;
}

NOTE: In versions prior to 1.5.5.1014 the class names are 'minimal', 'compact' and 'full'.

By default, xf:select1 is displayed as if appearance were set to 'minimal', whilst xf:select is displayed as if appearance were set to 'full'.

xf:choices can be styled to any level in both minimal and full controls; the default behaviour is to indent each set of choices by 2em per level.

More examples are available in the Subversion repository:

http://svn.x-port.net/svn/public/samples/styling/select/

Messages

From version 1.4.3.1030 on, message elements now contain some pseudoelements to make more fine-grained styling available.

The pseudoelements available are:
pe-message-header, pe-modal-header, pe-modeless-header
which correspond to the titlebar of the message, for all messages, modal messages, and modeless messages, respectively.

pe-header-text, pe-modeless-header-text, pe-modal-header-text
which correspond to the text in the titlebar, for all messages, modal messages, and modeless messages, respectively..

The following rules are included in the default css:


.pe-message-header
{
	width:100%;
	background-color:blue;
	padding:0px;
	margin:0px;
	position:absolute;
	top:0;
}

.pe-header-text
{
	color:white;
}

The modal/modeless distiguished classes can be accessed in the same way - thus:


.pe-modeless-header-text,
.pe-modal-header-text,
.pe-modal-header,
.pe-modeless-header
{
}

Aligning controls

A common requirement is to lay out controls so that labels and data entry areas line up neatly. Most authors assume that tables are needed to do this, but to keep with the spirit of both HTML and CSS, tables should not be used.

The easiest way to obtain a neat layout is to set the size of labels on a control. For example, if all labels were set to 12em then the data entry sections would line up:

xf\:input xf\:label
{
  vertical-align : middle;
  margin-right   : 0.2em;
  width          : 12em;
}

The dimensions of the entire control can also be set. In this example we set all input controls to take the full width of their container, and to have a dotted line at the bottom:

xf\:input,
{
  width            : 100%;
  padding-top      : 0.4em;
  padding-bottom   : 0.1em;
  border-bottom    : #d0c49d 1px dashed;
}

We can also set the data entry part of input controls using the technique for setting ::value. For example, to apply a light green background we would do this:

.input-value,
{
  background-color : lightgreen;
}

If all of these rules are combined (styling the full input control, the label and the ::value pseudo-element) we would get a layout like this:

Screenshot of input controls with light green backgrounds for the data entry part

If you're not clear on why this happens, you might want to revisit Anatomy of a control.