minimal form layout

I'm not a big fan of minimal html, but reality is such that in some cases I don't have any control over the html code I have to style. And implementing a design on some standard piece of html code can be quite tricky indeed, especially when the html is completely outdated or not up to modern standards. On the other hand, it's those cases that allow you to expand your box of css tricks.


Recently I've come across some pretty bare html form structures. At first I quickly turned away from them, saying there was little that could be styled, but after a while little tricks started popping up in my head. Being a csser really is a full-time job. I don't pretend to have invented the following css compositions, I'm pretty sure people have used them before, but following are two rather common html form structures complemented with a few styling tricks.

The wanted result is a basic form layout, labels to the left of the input field but right aligned, input elements to the right of the labels and left aligned. One line for each label-input combination.

rows, no labels

<div class="row">form label <input type="text" id="a" name="a"></div>

The first html snippet is pretty inaccessible, but like I said in the introduction, sometimes you just have no control at all over the html. There's usually one base element for each row (div or even p tags most probably), and that's about all you have to go on.

.row {width:12em; text-align:right; position:relative;} .row input {position:absolute; left:100%; margin-left:1em;} /* ie 6 fix */ .row {zoom:1;}

The above css code gives us the correct layout. The row div is given a width and will act as a wrapper for the form label. We apply a text-align:right so the text will nicely sit against the right edge of the box. We also set a position relative so we can position the input element away. The input element is given a position:absolute and left:100%. This will put it right at the outer right edge of the row container. We then add an extra margin to push it away from the label.

You can shorten the css a little by adding a bigger left value (110%) or a fixed left value (13em) to the input. On the other hand, this makes your css less flexible, should you want to change the width on the row. With this solution, the input will always remain in the right position, the margin controlling the distance between the label and the input element. If you have select (dropdown) elements in your form, don't forget to give them the same rules as the input elements.

One thing to note is that this solution is pretty rigid. Since the input element is placed trough a pos:abs it is taken out of the regular document flow. So this method only really works if the input elements has a height smaller or equal to that of the label. This poses a big problem if your form has textarea elements. Sadly, there's little you can do about this, besides giving those rows an explicit height covering the height of the input element.

labels, no rows

<label for="a">form label a</label> <input type="text" id="a" name="a"> <label for="a">form label b</label> <input type="text" id="b" name="b">

The above solution is more accessible, but completely fails on a structural level. The form is just a big list of label and input elements. Still, it's not impossible to style it as wanted.

label {float:left; clear:left; width:12em; margin:0em 1em; text-align:right;} input {margin:0.5em 0em; margin-left:13em; display:block; }

The label is given a width and floated to the left, the text is placed to the right using text-align:right. The input is given a display:block and a left margin that places it behind the form label. The margin/block isn't really necessary, but like this it feels a little cleaner to me. To make sure the next form label and input appear on the next line, we've added a clear:left; to the label css. This css solution is actually a bit more robust, as there are no pos:abs elements. No matter the height of the input or the label, the visual structure will remain intact.


If you like minimal html this tricks could come in handy, but I would really advise against setting up your html like this. If only because it's structurally messy and leaves you with very little to enhance the design if needed. But these tricks still come in handy when you have to quickly adapt a pre-made form without access to the html code. Just be aware of the limitations these methods have.