Skip to content

Portal Ignored Field Widths

Ed Mozley edited this page Sep 21, 2026 · 1 revision

The portal ignored a form's field widths

Reported by a user Β· Fixed in #1841, #1842, #1848 Β· Released in 2.3.1


What you saw

A form built with two fields side by side - half a row each - looked right when an analyst filled it in, and drew as one long column on the self-service portal. Every width the form's author had set was ignored there.

The report was simply that the form looked different in the two places, which is the right way to describe it: the same form, laid out once, arriving differently for the customer it was written for.


What was actually wrong

Not two renderers disagreeing. That was the first guess and it was wrong.

The walk over a form's fields is already shared between all three surfaces - the analyst filler, the portal and the builder preview - by assets/js/form-render.js. The portal was doing its job correctly and emitting data-width="6" on every field, exactly as the analyst filler does.

A width is expressed in twelfths, and twelfths only mean something relative to a 12-column grid. The portal's <form> element carried:

class="cat-form-table"

A class defined in no stylesheet in the repository. The grid it needed, .cat-form-grid, was sitting in assets/css/self-service.css - fully written, including the rule that collapses to one column on a phone - and referenced by nothing at all.

So every width was calculated, written into the markup, and then silently dropped. The CSS had shipped; the class name never met it.

πŸ”‘ An unrecognised class is not an error. Nothing fails, nothing is logged, and the markup contains no mistake a reader would see. A feature with no front door.


How it was fixed

The container is named correctly, which activates CSS that was already written and already reviewed.

Two further changes came out of it, because a one-word fix that nothing guards is a bug waiting to return.

The list of widths was guarded; the container was not

tests/field-widths-agree.php already checked that the permitted widths agreed across the service, the shared JavaScript and the builder. But a width is only half the mechanism - the other half is the parent that makes twelfths mean anything, and nothing checked that the class a page emits is the class a stylesheet defines.

The test now asserts, for all three surfaces, that the container class is really emitted, that a stylesheet really defines it as a grid, that the page really loads that stylesheet, and that it carries a rule for every width the service will accept.

⚠️ The first version of that check passed against the broken markup. It searched the whole source file for the class name - and the explanatory comment added by the fix contained it. A guard its own documentation can satisfy is not a guard. It now matches inside a class="..." attribute.

Both surfaces were narrow, and differently narrow

With the widths working, the underlying disagreement showed: the analyst filler capped a form at 860px and the portal at 720px, so the same form was about a sixth narrower for the customer.

Both now read one token, --form-card-max in form-shared.css, set to 1040px. The narrow field widths are the argument for the wider value rather than taste: at 720px a quarter-width field measured 167px, which a dd/mm/yyyy input with its calendar button very nearly fills. Fine for Fecha, not fine for FΓ€lligkeitsdatum. The builder was offering a width the portal could not honour.

πŸ”΄ One token still produced two widths, and only measuring caught it. The analyst filler loads inbox.css, whose opening rule is a global * { box-sizing: border-box }; the portal does not load it at all. So on the portal the container's max-width is the form, while on the filler two lots of padding sit inside the constraint. Reasoned out on paper it looked like 100px. Measured, it was 150px, and the first attempt produced a 990px form against the portal's 1040px.


Files changed

File What changed
self-service/catalogue.php the form carries cat-form-grid, the class the stylesheet defines
assets/css/form-shared.css --form-card-max, one value for both surfaces
forms/fill.php reads the token, plus the padding that sits inside its constraint
tests/field-widths-agree.php the container is guarded, not just the width list

How it was proved

By measuring in an iframe, because --window-size is not the layout viewport and a media query measured against the wrong width proves nothing.

before after
two half-width fields at 1200px 1200 + 1200, stacked 591 + 591, side by side
the analyst filler's form 940 1040
the portal's form 1040 1040
a quarter-width field 167 247
on a 400px phone full width full width, stacked

The old class name was measured as a control and gave the reported bug. A second harness, mobile-probe/formwidths.php, lifts the real CSS out of both pages and fails if the two grids ever differ again.


See also

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally