# XSLTForms/CSS
## Minimal Styling Rules

There are probably two basic kinds of layout that people might want:
(1) Inline Forms All Xform controls "flowing" into the page and moving to the next line when there isn't enough room for the control to fit on the end of the current line;
(2) Block Forms All XForm controls appearing each on a separate line down the page and aligned vertically.
By 'XForm controls' we mean the 'label', the 'value' and the associated 'icons' (help, valid/invalid). For both of the above cases we want all of the parts of the control to stay on the same line, a label shouldn't be separated from its value. So, in the first case all of the parts should move down to the next line if there isn't enough space.
Each xform control is converted to something like the following HTML structure via the XSLTForms stylesheet
span.xforms-control |_span  |_span  |_span  |_span  | |_label  |_span.value  |_input
By default a span will have no 'display' function so by adding styling to the span elements created by XSLTForms we can achieve what we want.
So for minimal styling rules, firstly to get everything within an Xform control to stay together we can use the following CSS rule:
span.xforms-control span {display:inline-block; white-space:nowrap; }
Using 'white-space:nowrap' seems to be enough on most browsers but adding 'display:inline-block' seems to force the nowrap behaviour.
Then to make the control label appear to 'belong' to the control value we can set the width of the label and make it display as an inline-block as well:
label.xforms-label { display:inline-block; width:300px; text-align:right; margin-right:4px;}
The above two selectors seem to achieve the flow layout that you'd expect as default with HTML but also makes each XForm control behave as an atomic unit.
To get the second tabular layout is simply a matter of forcing each control to appear on a new line as follows:
span.xforms-control {display:block;}
The fact that we have made each label one standard width means that the values will align nicely.
However, if you don't want xform trigger buttons to behave the same way as other controls then instead you have to be more specific in your display:block selector, something like:
span.xforms-input, span.xforms-select1, span.xforms-textarea, span.xforms-output {display:block;}

## XSLTForms classes for XForms pseudo-elements and pseudo-classes

The CSS XForms pseudo-element and pseudo-class selectors are not implemented in XSLTForms; instead, XSLTForms generates elements carrying equivalent classes that can be selected by CSS rules.
For example, instead of
write
Pseudo-elements defined by XForms :
| CSS | Equivalent XSLTForms class values |
| ::value | .xforms-value |
| ::repeat-item | .xforms-repeat-item |
| ::repeat-index | .xforms-repeat-item-selected |
Pseudo-classes defined by XForms :
| CSS | Equivalent XSLTForms class values |
| :enabled & :disabled | .xforms-enabled .xforms-disabled |
| :required & :optional | .xforms-required .xforms-optional |
| :valid & :invalid | .xforms-valid .xforms-invalid |
| :read-only & :read-write | .xforms-readonly .xforms-readwrite |
| :out-of-range & :in-range | (Not implemented) |
| :value-empty & :value-non-empty | (Not implemented) |
It helps to be clear about the nesting relations here. The pseudo-properties :valid, :invalid, etc. are assigned to controls; the pseudo-element ::value is a child of the control, not the control itself. So neither the CSS selector ::value:invalid nor the equivalent selector using the equivalent XSLTForms classes, .xforms-value.xforms-invalid will select anything: the ::value pseudo-element doesn't have the :invalid class. Instead, the pseudo-element is inside an element with that class. (Theoretically, XForms says the ::value pseudo-element is a child of the control; in practice, for practical reasons XSLTForms makes it a descendant, not a child.)
In case of doubt, careful study of the HTML generated by XSLTForms can help a form author understand how to write CSS selectors that select the intended elements.