Brian McFarland
Brian McFarland

Reputation: 9422

What is the most correct way to group form elements?

So I'v seen many tutorials and still haven't come up with a cohesive answer to this question: What's the correct/best way to mark up a form where I have a logical grouping of elements consisting of a label, control (input or select), and previous value, i.e. a single field?

I would like the CSS layout to place each grouping on a new horizontal line.

I've seen <div> wrappers, <br> tags, <ul>, <fieldset>, <tr>, and nothing at all (i.e. no markup tag, only CSS) used for this purpose.

Tables, aside from having a bad rep for doing form layout, aren't very flexible when the format of a row needs to vary. And br seems like a horrible idea (even though I've seen it in tutorials). I'm already using fieldset to create logical groupings of fields in a form, but I could always use two different classes if it's more semantically correct than div. The ul approach seems to be common by weird... the outer fieldset groups multiple fields, why do I need a ul that also groups them?

I really like the simplicity of the markup in this design: http://woork.blogspot.com/2008/06/clean-and-pure-css-form-design.html. But I'm having difficultly adapting the CSS to handle more complex fields, e.g. a select and input that logically belong together.

So in this example, what (if anything) to I wrap around field #1 and field #2 below?

<form .....>
  <fieldset> <legend>Group 1</legend>

    <!-- 'field #1' -->
    <label for="newName">Name</label>
    <input type="text" id="newName">
    <!-- oldVal Filled in with Javascript or server-side script -->
    <span class="oldVal" id="oldName">Old Name</span>

    <!-- 'field #2' -->
    <label for="newFood">Favorite Food</label>
    <select id="newFood">
      <option value="pizza">Pizza</option>
      <option value="tacos">Tacos</option>
      <option value="other">Other</option>
    </select>
    <input type="text" id="newFoodOther"> <!-- type here when 'other' is selected -->
    <span class="oldVal" id="oldFood">Pizza</span>

  </fieldset>
  <fieldset> <legend> Group 2</legend>
    <!-- more fields here -->
  </fieldset>
</form>

What's the easiest to use for controlling the form layout, and what's the most semantically correct? And am I fortunate enough to have those be one and the same?

Upvotes: 3

Views: 5048

Answers (2)

zzzzBov
zzzzBov

Reputation: 179136

There is no single correct way to semantically mark up a form. Some methods are more flexible than others, but that doesn't mean you should choose them all the time. Sometimes a bit of quick markup is best.

For flexibility, I typically use a structure as follows:

<form>
    <fieldset>
        <legend></legend> <!-- optional -->
        <label>
            <span>Label Text</span>
            <input type="..." />
        </label>
        <!-- repeat -->
        <input type="submit" ... />
    </fieldset>
</form>

Alternatively to help style with CSS I might use multiple labels:

<form>
    <fieldset>
        <label for="some-id-0">Label Text</label>
        <label class="text-label">
            <input type="text" id="some-id-0" />
        </label>
        <label for="some-id-1">Label Text</label>
        <label class="password-label">
            <input type="password" id="some-id-1" />
        </label>
    </fieldset>
</form>

But then I could separate this out into a list:

<form>
    <fieldset>
        <dl>
            <dt>
                <label for="some-id-0">Label Text</label>
            </dt>
            <dd>
                <label class="text-label">
                    <input type="text" id="some-id-0" />
                </label>
            </dd>
            <dt>
                <label for="some-id-1">Label Text</label>
            </dt>
            <dd>
                <label class="password-label">
                    <input type="password" id="some-id-1" />
                </label>
            </dd>
        </dl>
    </fieldset>
</form>

I find that adding more generic structural elements and classes tends to add flexibility to a certain degree, however you wont need any of that structure if you simply want a mad-lib form:

<form>
    <p>
        Hi, my
        <label for="fullName">name</label>
        is
        <input type="text" id="fullName" name="fullName" placeholder="Full name" />
        and I would like to request a copy of
        <select id="publication" name="publication">
            <option>Super Awesome Newsletter</option>
            <option>Even more awesome-er newsletter</option>
            <option>Lorem Ipsum weekly</option>
        </select>
        please send it to
        <input type="temail" id="email" name="email" placeholder="[email protected]" />
    </p>
    <input type="submit" value="Thank you!" />
</form>

In the end the semantics revolve around how you want the form read. Unfortunately that means restructuring the form if significant changes are made.

Upvotes: 3

Blazemonger
Blazemonger

Reputation: 92943

"Semantically correct" applies to the HTML, not the CSS, and I'd say you already have that covered.

There's an infinite number of ways to style the form, of course, but one thing you can do without adding any extra markup is to make the labels into one "column" and the inputs into another:

label {
    display: block;
    float: left;
    clear: left;
    width: 150px;
}
input, select {
    display: block;
    float: left;
    width: 150px;
}

http://jsfiddle.net/mblase75/ECmwH/

This leaves the problem of where to display your "oldVal" fields, but I think that's a matter of opinion.

Upvotes: 0

Related Questions