Quick Tip: Encourage Responsive Form Elements to Play Nice


Last weekend I downloaded Dave Gamache's Skeleton boilerplate to have a play with; good, clean, responsive fun. When it came to the form design I was reminded of an issue which can affect inputs in flexible layouts: misbehaving widths. If you've ever had the same problem, or have never been aware of it, read on..

The Problem

Let's say we have a layout with a containing element, which has a flexible width (stretch your browser, and you'll stretch the container). Within our container we have a variety of elements (headings, paragraphs, horizontal rules, divs) and we also have a simple form which plays host to a few typical form bits and bobs.

The contents all grow and shrink depending on the width of the container. Block level elements (such as divs) match the width exactly. They automatically fill 100% of the width of the container, and irrespective of any padding or borders they stay neatly within the boundaries of their parent.

form input width problem

Form inputs don't.

For them to fill the width of the container we have to apply a width: 100%;. Having done that however, adding padding, borders, or margins will cause our inputs to burst from the constraints of the container. Bummer.

form input width problem

Are They Really Misbehaving?

Well, not really. The CSS Box Model dictates the way element dimensions behave, and since web standards were introduced we've come to accept that padding, margins, and borders add to an element's dimensions.

css box model

So arguably, our div in this case is the one behaving unexpectedly, but that's only because we haven't actually defined its width.

It appears to be handling things the way Internet Explorer traditionally used to. The quirks mode approach meant that you defined an element's width and height, and any padding or borders would be taken into account within those dimensions. If you specified a div to be 600px wide, even if you added 10px of padding, it would still be 600px wide. You would know categorically how big your elements were.

Responsive Design

As long as we were aware how our elements were behaving, we could allow for the differences and specify fixed dimensions accordingly. But in this age of fluid layouts, we don't necessarily know how wide containing elements are. Surely there's a way of getting our inputs and textareas to behave in the same way as everything else? Happily there is. And we're going to build a quick demo to illustrate it.

The Demo

As it was the Skeleton boilerplate which reminded me of this issue, we'll go and grab it to quickly build ourselves a demo.

Note: Any styling within the Skeleton boilerplate is for the purpose of layout and basic aesthetics - my adding to its css is not a criticism!

Unpack the files and you'll see something like this:

skeleton boilerplate

The first change I'll make is to index.html. In the last column we'll swap out the content for a form:

<form action="">

  	<!-- Label and text input -->
  	<label for="regularInput">Regular Input</label>
  	<input type="text" id="regularInput" />

  	<!-- Label and textarea -->
  	<label for="regularTextarea">Regular Textarea</label>
  	<textarea id="regularTextarea"></textarea>

  	<!-- Label and select list -->
  	<label for="selectList">Select List</label>
  	<select id="selectList">
    	<option value="Option 1">Option 1</option>
    	<option value="Option 2">Option 2</option>
    	<option value="Option 3">Option 3</option>
  	<button type="submit">Submit Form</button>


and then we'll add a couple of lines to stylesheets/layout.css:

.column {
	background: #f7f7f7;

textarea {
	width: 100%;

All we've done is given the columns a gray background (so we can see where the boundaries lie) and made our form elements 100% wide. Check out the result so far. The problem of misbehaving inputs is illustrated clearly, so now to the solution..

The Solution

We can make our form elements behave according to the old quirks mode box model with one line of css..

textarea {
	box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;

Alright, six lines, but the important one is box-sizing: border-box;, along with its vendor prefixed brothers. We've applied this rule to our text inputs and textareas, telling the browser to render their dimensions with padding and borders inside. Have a look at the resultant demo, perfecto! Resize the browser and you'll see the form elements playing nice just like their block level friends.

In terms of browser support you're well covered too. Ironically, IE7 doesn't recognize the box-sizing property, but it's the only browser you'll have trouble with.

Further Resources

Related Posts