在HTML中实现表单布局的最佳实践 -- 使用表格还是流式布局?

8
什么是在HTML中布局表单的最佳实践?特别是当您有一组带标签和可能的错误指示器的字段时。我所能做的最好的方法就是使用表格,但这在基于CSS的布局设计中并不起作用。例如:
<table>
  <tr>
    <td>Name:</td>
    <td><input type="text" /></td>
    <td style="display: none" id="NameError">*</td>
  </tr>
  <tr>
    <td>Phone:</td>
    <td><input type="text" /></td>
    <td style="display: none" id="PhoneError">*</td>
  </tr>
  <tr>
    <td>Birthday:</td>
    <td><input type="text" /></td>
    <td style="display: none" id="BirthdayError">*</td>
  </tr>
</table>

这似乎与CSS无关,但我不确定如何使用基于CSS的布局来使其正常工作。

什么是最佳实践?


@WTP - 严格来说,<dl> 是一个定义列表(一组项目及其定义的列表),因此在我看来并不是特别合适 - 不过,我确实见过它们被用在这种方式上。 - David Precious
“最佳实践”和“实际操作”有时是不同的。表格在表单(而非页面)布局方面比CSS更具优势。1)表格是古老的基础技术。每个浏览器都知道如何呈现它们,并以相同的方式呈现它们,它们不会很快消失,也不会在未来被“修改”并产生意外行为。 - KWallace
2)表格布局实际上比等价的div和span的CSS样式要简单得多。列宽度可以(或者可以被自动处理)自动处理大小以匹配内容,从而使垂直和水平对齐变得微不足道。尽管具有Balrog特性,但是表格仍然响应现代CSS样式,例如min-width和max-width以控制宽度/溢出。 - KWallace
6个回答

13

我不知道你们怎么看,但是我在表单布局方面用的标记很少。

以下是一个简单登录表单的标记(没有布局标记,如div、table等)

<form method="post">
    <label>Username</label>
    <input type="text" name="username" />

    <label>Password</label>
    <input type="password" name="password" />

    <input type="submit" name="Log In" />
</form>

这是表单的CSS样式

label,input{float:left}
label,input[type="submit"]{clear:left}

这是结果:

上述HTML和CSS的渲染结果

这个东西惊人之处在于:

  • 缺乏标记
  • 缺乏CSS
  • 灵活性

如果您查看CSS,label元素被清除到左侧(并向左浮动)。这意味着标签将与其伙伴的input一起浮动,但每个label将成为新行。

这使得添加额外输入非常容易。即使在输入之后添加验证消息也很容易。

以这个表格为例。

<form method="post">
    <label>Name</label>
    <input type="text" name="username" />

    <label>Password</label>
    <input type="password" name="password" />

    <label><abbr title="Date of Birth">D.O.B.</abbr></label>
    <input type="text" name="dob_day" />
    <input type="text" name="dob_month" />
    <input type="text" name="dob_year" />

    <input type="submit" name="Log In" />
</form>

使用此CSS

label,input{float:left}
label,input[type="submit"]{clear:left}
input[name^="dob_"]{width:44px;margin:2px}
label{width:70px}

我们得到:

上述HTML和CSS的呈现结果

就是这么简单 :)

使用这个概念,您可以创造大量的可能性,再也不必使用表格进行布局了!


8

使用实际的<label>元素作为字段标签,这对可用性也有好处,使用CSS适当地进行样式设置。

例如,

<label for="name">姓名</label> <input type="text" name="name">

然后在您的CSS中,您可以使用display:block和所需宽度以及适当的clear值来设置LABEL元素的样式。

对于复选框/单选按钮输入,输入本身应位于<label>元素内 - 这意味着标签本身应可点击以选择该输入,例如:

<label for="mycheckbox"> <input type="checkbox" name="mycheckbox"> 勾选我如果你敢</label>


1
你能再具体一些吗?我不想在标签上设置显式宽度,我希望控件占用它们需要的空间,然后标签占用其余的空间,就像上面的表格布局一样。例如:http://jsfiddle.net/roger_davis/7h3bC/ 看起来很糟糕。 - Roger Davis

5

有人会争论表格数据可以用表格呈现,所以使用表格是可行的。正如David所说,主要问题在于您希望使用适当的LABEL标签。

但是,在您的示例中,我不确定使用表格与CSS相比有何优势。


恶魔的代言人说,使用表格而不是 CSS 可以获得更“强大”的布局,可以将相同的标记部署到可能具有其自己不同首选列宽的多个网站上。 使用 div 和浮动通常需要指定宽度,如果您想要相同类型的强大非表格布局...我总是发现自己调整 CSS 来匹配每个特定的网站,可悲的是永远没有一个通用的“一刀切”的解决方案。 - Funka
哈...我想说的是“不确定使用CSS相比表格有什么好处”。至少在给出的例子中,我认为表格是最合适的选择。 - DA.

3

最佳实践 = 永远不要使用表格进行布局。

您可以尝试使用CSS框架,如Blueprint或960网格系统。


4
除非您展示表格数据,否则始终适合使用 <table> 作为结构选项。尽管应避免使用 <table> 标签来进行布局上的hack,但按照其预期用途使用 HTML 标签是没有问题的。在 <table> 中呈现表格数据不会违反结构和样式的分离原则。您是在告诉消费者,“这是经过结构化处理的表格数据!” - Boris Nikolaevich
2
是的,我同意。这就是为什么我说“对于布局;-)”在一般布局方面。 - Cygnusx1
1
我们意见一致——我只是在你的回答基础上进行了扩展,而不是反对它。 - Boris Nikolaevich

2
“最佳实践”是使用表格来展示数据,并使用div、span或其他元素来设计您的输入表单。

你能提供一个这样做的示例吗?我试图避免使用表格,但是所有聪明的人似乎都无法想出一个合理稳健的解决方案。作为第二个数据点,我查看的几乎所有大型网站都采用表格或固定宽度列的方法,这两种方法都不理想。 - Roger Davis
@Roger:这是一个使用div元素创建表单的好例子:https://secure.blippy.com/signup - Brad Christie
@Brad Christie:你的例子使用了固定宽度列。 - Russell Silva

1
“我在这里回答你的后续问题,因为它很可能会被关闭为重复内容。”
“我不确定浏览器对此的支持情况如何,在FF4中进行了测试:http://jsfiddle.net/shanethehat/7h3bC/11/
<div id="tableForm">
    <div class="tableRow">
        <div class="tableCell">
            <label for="mycheckbox">  Tick me if you dare</label>
        </div>
        <div class="tableCell">
            <input type="checkbox" name="mycheckbox" id="mycheckbox">
        </div>
    </div>
    <div class="tableRow">
        <div class="tableCell">
            <label for="mytext">  Give me some text test test</label>
        </div>
        <div class="tableCell">
            <input type="text" name="mytext" id="mytext">
        </div>
    </div>
</div>


div#tableForm {
 display:table;   
}
div.tableRow {
  display:table-row;  
}
div.tableCell {
    display:table-cell;   
    width:inherit;
}

是的,我知道,我刚刚使用div创建了一个表。但重点是这样非常易于访问和语义上正确。

编辑:在IE7中失败而且只能使用固定宽度,但8和9似乎还好。

编辑2:将标签/字段交换并设置右对齐:http://jsfiddle.net/shanethehat/7h3bC/12/。此时标记略微复杂。:first-child是使用左侧类的替代方法,但代价是IE8。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接