maximized form layout

After my article on minimal form layout I thought it would be fair to explain a little about my preferred way to layout a form. Or at least, the form layout we use at work. It might seem pretty bloated, especially for smaller projects or simpler forms, but that's why I'm dedicating a whole article to it. So bear with me for a second.

disclaimer

Before starting, it might be useful to say a few words about the ideology behind our work. First of all, I work for a company specialized in front-end development. We do everything from information architecture to making static html/css/javascript templates. After that is done, our templates are shipped to a technical partner who then uses this batch of templates to build the actual site. In that sense, it is important that our html is flexible and robust. Changes in css are easy (overwrite the css file), but html changes can mean a lot of extra work and a serious communication overhead.

Secondly, one of my pet peeves is the structural relevance of html. I'm not a fan of "using just enough elements so it can be styled", since such ideology still mixes style and content. Writing structurally "correct" html often results in elements you don't really need for styling, but are needed to group or separate certain elements, ie provide structural meaning to the document.

So let's take a quick tour around the form layout I prefer using.

rows

<div class="row clearfix"> ... <div class="feedback">...</div> </div>

Even though a "row" is not necessarily a semantic element and is definitely not needed in every form, it can still come in handy for several reason. First of all, it has a very strong structural meaning, as it groups input elements which are closely related to each other. Postal code and city, first name and last name, street and nr/bus. These are all typical examples of form data that is so closely connected that it is often displayed on the same line in a form. This grouping of elements is accomplished by our row element.

The second reason for defining the row structure is to mark a feedback area for input elements within a row. This div is used for error messages or confirmation messages (fe writing a numerical date which is then confirmed in full writing) on row level. You could argue that feedback should be possible for each separate input element and thus should be added to each individual input element (and you would be very right indeed), but practically this is almost impossible to do without running into some serious styling troubles later on. One of those situations where semantics have to make way to work around real world problems I'm afraid.

input elements

<div class="inpElement"> <label class="inpCaption" for="a"> input label <span class="captionHint">(...)</span> <span class="req">*</span> </label> <div class="inpControl"> <div class="control"> <input type="text" id="a" name="a" maxlength="20" size="1" /> <span class="controlHint">(...)</span> </div> <div class="controlHelp"><img src="..." alt="..." /></div> </div> </div>

An input element is always defined by a caption and input control. Even when the caption is not visible, all input controls should have exactly one label element so screen readers know what the input control is for. Each form row will always hold at least one input element, but might hold more. The html code you see above is an example of a full-blown input element, all options included. The main structure is easy enough, within the input element are two sections. One section for the caption of the control, one section for the control itself.

The input caption holds everything related to the label. This means a possible label hint and a possible required indication. Since both are important and valuable additions to the label they must be nested within, where screen readers will pick them up. The class "inpCaption" might seem redundant, but is used for consistency's sake so the same html structure can also be used for a list of checkboxes, where the actual label tag will be placed after the input control and the input caption will be defined by a div. This way, the structure and css is singular and remains clear.

The input control holds a separate control div (in the case of a checkbox list, you'll have a series of control divs), inside this element the actual form control is nested with possible input control hints. After the control structure a possible control help can be added (usually an image of a question mark with a popup on click) for lengthier explanations and information about the input data.

css

.row .inpElement {float:left;} .row .inpElement .inpCaption {float:left; width:11em; text-align:right; position:relative;} .row .inpElement .inpCaption .req {position:absolute; right:-0.6em; top:0;} .row .inpElement .inpControl {margin-left:12em;} .row .inpElement~.inpElement .inpCaption {width:auto; margin:0em 0.5em;} .row .inpElement~.inpElement .inpCaption .req {position:static;} .row .inpElement~.inpElement .inpControl {margin-left:0; float:left;}

The above css is all you need for a basic setup. The input element itself is floated to the left (to allow for additional input elements on the same row). The label is also floated and given a width. The control is then positioned past the label with a left margin. You could float it, but if the control hint becomes bigger than the length of a line this will break the layout. All following input elements added inside a row have the same styling, only with the width reset on the inpCaption and the left margin taken off the inpControl. The required indication on the first input element is set absolute (so the text of all labels is neatly lined out), in consecutive input elements the required indication is reset to static.

As you can see, this is relatively little css for a pretty complex and flexible layout. Of course, the css needs to be expanded a little if you want to start adding extra styling to the captionHint, controlHint, controlHelp etc etc.

work in progress

Since the day I started on my current job I've been working on this little piece of html. I'm constantly tweaking it, trying new things and shifting things around. What I don't like about this structure is that I'm using the label tag as a structural element, which is outside its intended purpose (hence the display:inline). As a kind of guidance rule, I try to keep elements on the same structural level with the same css display property, effectively trying never to mix inline with block elements. This is easily solved by nesting the label inside a div.inpCaption (which is how I did it before), but that extra div really is quite useless since all additions to the caption need to be nested inside the label tag anyway.

Another weakness in the css lies with the width on the inpCaption and the left margin on the inpControl that are always related. Change one and you have to change the other if you want to keep your design balanced. I tried fixing this once by floated the inpControl and simply applying a right margin to the inpCaption, which is fine until you cross the line length (which happens pretty quickly when you're adding a checkbox list with longer labels) which causes the layout to break.

Valuable comments (so please nothing about bloated html and divitis) are always welcome!

conclusion

Working with this kind of structure has several advantages. Most importantly, it is robust enough to allow for late changes in the graphical and functional design. Adding an extra hint or help doesn't mess up your complete css and html structure as the structure already takes such elements into account. Graphical changes are made easier too as you have plenty of structural elements to play around with.

On a structural level, this setup makes a lot of sense too, as it groups and separates all the right elements. It's a structure that can be carried over to different projects quite easily without having to make many changes, which adds to the predictability of your code. Advantages a plenty, unless of course you worry about file sizes and "abundant" divs that are not needed for css styling.

Whatever method you use, it's up to you, but consider for a moment the structural relevance of html and whether you think it's okay to throw it overboard just because you don't need certain elements for styling.