Different behaviour of repeat in 1.5 and later

Paul Butcher's picture

Forms with xf:repeat may render differently in version 1.5 and later, compared to 1.4, this is due to a change in the relationship between repeat, repeat-item, and the document.

This can best be seen where the background-color of repeat-index or repeat-item differs from the background-color of the document. This is rendered as a strip of differing background colour over the entire width of the page, rather than being constrained to the apparent width of the repeat-iteration (i.e. the width of the contained controls and text), as it is in 1.4.

The behaviour of 1.5+ is the CORRECT behaviour. The 1.4 and earlier behaviour is a quirk of viewlink, the IE technology that formsPlayer was previously using to render all elements, and still uses for most controls, but not container elements.

Unfortunately, as it stands, there is now no pure CSS, standard way to make version 1.5+ repeats act in the same way as 1.4- repeats in this respect.

The culprit is 8.1.1 Implementation Requirements Common to All Form Controls, specifically: "All form controls, including container form controls, should have an inline layout by default (e.g. for a host language that supports CSS, the default styling should be display:inline). By default, repeat items should have a block layout (e.g. a default styling of display:block for host languages that support CSS)."

By default, repeat-iterations must be block, and repeats inline. This means that repeats cannot behave as a "containing block" for the repeat-iterations, and the repeat iterations therefore take up the entire width of the outer containing block (see 10.3.3 Block-level, non-replaced elements in normal flow). If repeat has a display value of block, then although it behaves as a containing block WRT the setting of the width of the iterations, the repeat itself takes up the entire width of the form already, so the same effect is seen.

Setting the repeat display to inline-block allows repeat to act as a containing block, and constrain the widths of its iterations. In isolation, this works well. However, this then means that for the purposes of its own flow, repeat is inline, so, in the context of a form where a repeat is expected to exist on its own line or set of lines, layout is even more "messed up" by this, than the default appearance.

The solution I would propose, is that form authors should make repeats inline-block, then enclose them in a block-level container such as a div, or use br to control line-breaks either side of the repeat. I feel that this is a bit of an unsatisfactory solution, part of the point of css being to prevent the need for messing about with markup. On the other hand, if the form is non-standard, then it shouldn't be expected to work. A similar option would be to make repeat-item display:inline, but use a br element within the repeated content, to create line-breaks.

A second possible solution (within formsPlayer) would be the addition of an extra container pseudoelement within repeat, to contain the iterations. If this has a default display value of block, then it should behave, by default, in a standards-compliant fashion. Form authors could then override this with CSS such that it would behave similar to 1.4. This is also an unsatisfactory solution, as it introduces a new non-standard feature, and form-authors relying on this mechanism to correctly render their forms will see their forms as "messed-up", when using other XForms processors. To some extent, I suppose it could be said that this is the "value" pseudoelement, but it doesn't make sense for container-class XForms elements to have a "value".

Joel on Software's post: Martian Headsets, investigates the issue of standards-compliance and backwards-compatibility, with particular attention to IE8.