最近突然遭遇许多复杂表单,于是干上了。
一直有种说法:table用于数据表,对于复杂表单,table也是最好的选择,由于一直没有遇见过也就没有认真去研究,到底复杂表单是否应该使用table。
好了,机会来了,我拿着复杂表单的图样,看来看去都觉得不应该用table呀,除非是有行标和列标的数据表表单。反而类似于登陆这种简单表单,我倒是一直使用table,理由是能够在纯文档的时候对齐文本与输入框,但是对于复杂表单就不一样了,复杂表单涉及到页面布局了。
为什么要研究?因为我希望程序员不要涉及到界面的任何部分,对于页面,他只需要关注结构,而复杂表单如果采用table,很容易就将程序员带进对布局的操作中去。
好,经过一阵艰苦奋斗,还算好,xHTML部分自己觉得还算摸清了一些规律,页面的分析信手捻来,div结构下的复杂表单真是漂亮,但是但是……CSS部分……我靠,真是难搞,干了几个复杂表单的CSS都没摸清规律,太JB麻烦了,尤其是文本长度不一致,表单控件又各种各样交错,还有错误提示隐藏的文本,时不时中间又加个按钮……迷茫了……算了,继续干CSS,希望最后能得出结论,对于复杂表单到底用table还是div?
先给一个对于登陆界面这样简单的表单,我最常用的xHTML代码,使用table,理由见上:
<h3><span>用户登陆</span></h3>
<table>
<tr>
<td><label for="name">用户名</label></td>
<td><input id="name" />
</tr>
<tr>
<td><label for="pw">密码</label></td>
<td><input id="pw" /></td>
</tr>
</table>
<p><button /></p>
</div>
另外不使用table的如下:
<h3><span>用户登陆</span></h3>
<div>
<label for="name">用户名</label>
<input id="name" />
</div>
<div>
<label for="pw">密码</label>
<input id="pw" />
</div>
<p><button /></p>
</div>
怎么说呢?第一种我视这样的简单表单为2行2列数据,用了table。第二种则是div模块化操作。一般我都使用第一种,除非文本长度一样(比如姓名,密码)才用第二种。当然我觉得第二种是正确的,所以我会优先在文案上先做文章使之长度一致。为什么?因为只有模块化,才能固定xHTML而通过CSS随意布局,比如形式上为一行四列之时,第一种就做不到(其实FF可以正确解释对tr的浮动操作,例如2列tr,但是ie不支持,一个tr怎么都得占table的一行。)。
好了,复杂表单的图样和xHTML部分在公司,明天上班发上,现在睡觉问梦去。
这份表单够份量不?

这里是xHTML部分,做了些必要的删除,没破坏结构就好了。留意我补充的部分,比如h2、h3。
<div>
<h2>导航</h2>
<div>
<button>新增</button>
<button>刷新</button>
</div>
<div>
<h3>当前批次采用的标准为</h3>
<div>
<label>本人补贴</label>
<ASP:label id="" Runat="server"></ASP:label>
</div>
<div>
<label>本人工龄补贴</label>
<ASP:label id="" Runat="server"></ASP:label>
</div>
<div>
<label>配偶补贴</label>
<ASP:label id="" Runat="server"></ASP:label>
</div>
<div>
<label>配偶工龄补贴</label>
<ASP:label id="" Runat="server"></ASP:label>
</div>
<div>
<label>特殊补贴</label>
<ASP:label id="" Runat="server"></ASP:label>
</div>
</div>
<iewc:treeview id="" ExpandLevel="1" runat="server" AutoPostBack="True"></iewc:treeview>
</div>
<div>
<h2>表单内容</h2>
<div>
<h3>申请人信息</h3>
<div>
<label>本人姓名</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>身份证号码</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>本人工龄(年)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
<ASP:regularexpressionvalidator id="REVY" runat="server" Display="Dynamic" ValidationExpression="\d{0,2}" ErrorMessage="必须输入整数"
ControlToValidate="txt_WorkAge"></ASP:regularexpressionvalidator>
</div>
<div>
<label>工作单位</label>
<ASP:label id="" Runat="server"></ASP:label>
</div>
<div>
<label>职务或职称</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
</div>
<div class="personinfo">
<h3>现住房信息</h3>
<div>
<label>现住房地址</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>建筑面积(平方米)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>其中个人按市场价自购面积(平方米)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>现住房性质</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>补贴住房面积标准(平方米)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>申请住房补贴理由</label>
<ASP:dropdownlist id="" Runat="server"></ASP:dropdownlist>
</div>
<div>
<label>申请住房补贴标准</label>
<ASP:radiobuttonlist id="" runat="server" RepeatDirection="Horizontal">
<ASP:ListItem>无房户一次性补贴</ASP:ListItem>
<ASP:ListItem>一次性补面积差</ASP:ListItem>
</ASP:radiobuttonlist>
</div>
</div>
<div>
<h3>配偶信息</h3>
<div>
<label>配偶姓名</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>配偶身份证号码</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>配偶工龄</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>年
<ASP:regularexpressionvalidator id="" runat="server" Display="Dynamic" ValidationExpression="\d{0,2}" ErrorMessage="必须输入整数"
ControlToValidate=""></ASP:regularexpressionvalidator>
</div>
<div>
<label>配偶工作单位</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>职务或职称:</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
</div>
<div>
<h3>享受住房分配或货币补贴情况</h3>
<div>
<label>(1)已享受房改购房面积(平方米)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>(2)已享受购房补贴(元)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>(3)已享受住房补贴(元)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<ASP:button id="" Text="计算" Runat="server"></ASP:button>
<label>本次补贴面积(平方米)</label>
<cc1:acceptnumber id="" runat="server"></cc1:acceptnumber>
</div>
</div>
<div>
<h3>住房补贴</h3>
<div>
<label>本人补贴(元)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>本人工龄补贴(元)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>配偶补贴(元)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>配偶工龄补贴(元)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>特殊补贴(元)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>合计(元)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>实际发放补贴(元)</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
</div>
<div>
<h3>请申请人根据不同情况填写</h3>
<div>
<label>现购房地址</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>售房单位</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>偿还贷款帐号</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
<div>
<label>贷款银行</label>
<cc1:XMLdropdownlist id="" runat="server" XMLNodeName="" XMLPath=""></cc1:XMLdropdownlist>
</div>
<div>
<label>本人公积金存储号</label>
<ASP:textbox id="" Runat="server"></ASP:textbox>
</div>
</div>
<div>
<ASP:button id="" Text="保存" runat="server" CSSClass="button"></ASP:button>
<ASP:Button id="" Text="退回" runat="server" CSSClass="button"></ASP:Button>
<ASP:Button id="" Text="删除" runat="server" CSSClass="button"></ASP:Button>
<button id="" onclick="JavaScript:window.close();">关闭</button>
</div>
</div>
再补充一个,这里有两个部分很明显的表格结构,所以在那里使用了table,而其他部分没有用。

table部分xHTML。CSS部分还没琢磨出来规律,结论没有,继续琢磨,不过感觉没有用table结构很漂亮也很灵活,但是CSS确实让人头大,权衡得失中,再补充了。
..<div class="personinfo">
<h2><span>个人信息</span></h2>
<div>
<h3><span>购房人</span></h3>
<table>
<tr>
<td><span>选择</span></td>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>关系</td>
<td>户籍所在地</td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td><select /></td>
<td><input /></td>
<td><input /></td>
<td><select /></td>
<td><input /></td>
</tr>
</table>
</div>
<div>
<h3><span>家庭成员</span></h3>
<table>
<tr>
<td><span>选择</span></td>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>关系</td>
<td>户籍所在地</td>
<td>工作单位</td>
<td>编辑</td>
<td>删除</td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td><select /></td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
<td><button /></td>
<td><button /></td>
</tr>
</table>
<p>
<button />
</p>
</div>
</div>


@[天道酬勤]/@NeedForSleep/@一帆(老鼠粮仓之路)
对于复杂表单而言,table和div的选择现在还没有那个是绝对正确的说法。我的感觉是对于个人而言,table快,对于团队而言,div快。如果说从正确上而言,我更偏向于div。
非表状的表单如果使用table,这个时候table的作用是用于布局,违背了Web标准的初衷。对于个人而言,牺牲一下理论换取更快的速度没什么不对,但是对于需要协作的团队而言就不一样了。
较大的业务系统里面会出现很多类似的复杂表单,比如前段时间,需要将一本合同做出来,这个时候怎么办?如果用table,我是不可能给出一个标准和固定的东西,不同的表单拥有不同的表格切分。但用div则可以,而且固定xHTML写法,结构是一样的。这样一来,程序员不用考虑表格的切分,单元格的对齐等表现方面的工作,即便多个程序员都可以按固定的xHTML写法完成页面,专注于结构和程序,甚至不用了解结构,死记硬背下结构都可以。而前台也无需过多交流来进行CSS设计,闭着眼睛都知道对方会输出什么样的结构,分离的好处我想就不用多说了吧。
所以,我认为复杂表单使用div,遵循Web标准,更多的不是为了适应页面的变化,而是形成前台和后台在团队中的高分离度,把混乱的制作环节避开。何况还有后期维护的灵活性,虽然一般而言复杂表单不会变,但万一呢?比如系统的移植或整合,也就是后期的维护,遵循Web标准下的优势是巨大的。否则谁来做这个table?程序员?设计师?我觉得要乱套。
对于个人而言我还是觉得或许table更合适,因为人的精力有限,一旦牵涉进使用CSS控制布局,就会重新学习很多,虽然说CSS这个东西并不难,但是CSS和设计(平面设计、界面设计)是密切相关的,而设计则是一个很难的东西。所以,我认为CSS的深入研究应该由前台去完成而不是由程序员来完成。
现在Web标准没有真正推广开来,我认为很大程度是前台没跟上,也就是很多公司的前台不敢拍着胸膛说:你如果按xHTML输出,我就可以保效保质的完成CSS。因为xHTML对于程序员其实完全没难度,只要理解了很简单。
@avill^_^
@老燕
1. 积少成多,以小见大。没发现复杂表单是个副标题吗?显然我无意这篇文章就阐述完整个Web标准体系,反而我觉得面面俱到更容易肤浅和出错,所以,我选择随着我的理解一点一点的来,分散记录,不搞大而全,人非全能,我可以明说我的js水平很差,所以在我的文章里几乎不会谈及js或者说Web标准的交互部分,抄概念人人都会,但是关键还是理解和运用。另外Web标准这三个部分,你觉得是同等重要吗?我认为不是,我认为xHTML最重要,他是根基,可以没有CSS,也可以没有js,但是不能没有xHTML。再说我从来不认为CSS有多少技术含量,CSS拥有的都是技巧性的东西,所以我主要会在xHTML上进行文章,CSS部分会涉及不会太深入,因为它是可变的,只能说合适或者不合适,不能说正确或者错误。
2. 同意。
3. 废话。
4. 前面还是废话,说两点,你提到163,163于一年前的昨天完成对科技频道的重构,并于去年3月28日完成整站的重构,我不知道新在哪里?当时查看代码我就认为163做的不好,还不如前年10月闪客帝国的重构,技术是人做的和品牌无关。再说当时标准刚进国内,我想就是阿捷,让他回顾以前的理解,他肯定也是一笑而过。其次“表格化的数据”,都是这么说的,请问你有没有想过什么样的数据是表格化的数据?比如登陆框,请问能不能视为2行2列的表格来使用table标记?又或能不能视作2行数据列表来使用ul/ol标记?好,那么究竟什么样的数据是表格化的数据?为什么我认为163不好,第一个就是满篇的列表标记。我准备在第三篇阐述我对table和ul/ol的语义理解。
5. 表单的复杂度更多来源于不可见的东西,你……。“左右两列式布局”……“左二右六”……“拼装”……你就是这样分析页面的?谁是表格化思维?“就是用DIV嵌套来替代TABLE嵌套”,你完全没看懂我的代码。如果你能解释这个问题,我想你不会这么说。问题:标题tag(h1~h6)设计是否合理?为什么?这个是我准备下一篇写的个人理解。这篇文章重心在讨论复杂表格用table合适还是div合适,和你说得够多了。
2006 2 24 update
突然感觉自己错误了,大处未错,错在小处,仍在琢磨怎么对付复杂表格……
2006 3 2 update
觉得自己没错,哈哈,先传上完成后的界面,时间忘了,不算上设计,写CSS大概1小时左右吧,或许还少,不少地方都能部分或全部应用整体样式。

好了,今天收到了用户变更需求,很快给大家看看标准的威力。
2006 3 9 update
