关于表单布局

今天终于在博客园开博了,不为什么,只为将自己在学习上的收获作个收藏积累。经常在谷歌搜索问题,经常都能在博客园找到满意的答案,这是个好地方,所以我决定在这里安家。

我不是个善于文字的人,也就不多说了。直接进入主题。

一直以来,对表单布局没有一个好的习惯,有时候想用p,有时候想用li,也经常遇到一些问题,总没有一个好的解决方案。

今天,哥下定决定尝试用不同的方法实现同一个表单,然后总结出最优结果。以后好采用,而不用每次都有这样那样的问题,然后通过hack或者啥的小技巧解决。

首先,先上效果图

首先,我先尝试了用li来作结构,结构如下:

<form id="reg">
		<ul>
			<li>
				<label for="usernmae">用 户 名:</label>
				<input type="text" id="usernmae" name="username" class="text" />
				<em class="notice">提示信息</em>
				<strong class="notice wrong">出错信息</strong>
			</li>
			<li>
				<label for="pwd">密  码:</label>
				<input type="password" id="pwd" name="pwd" class="text" />
			</li>
			<li>
				<label for="repwd">确认密码:</label>
				<input type="password" id="repwd" name="repwd" class="text" />
			</li>
			<li>
				<label for="qq">Q  Q:</label>
				<input type="text" id="qq" name="qq" class="text" />
			</li>
			<li>
				<label for="email">邮  箱:</label>
				<input type="text" id="email" name="email" class="text" />
			</li>
			<li class="con">
				<label for="content">座 右 铭:</label><textarea id="content" ></textarea>
			</li>
			<li class="sub">
				<input type="submit" value="提交" class="btn" /><input type="reset" value="重置" class="btn" />
			</li>
		</ul>
	</form>

由于后面出错信息等长度不固定,所以ul的长度也不能固定,这样,如果li浮动的话,那将是排成了一排,则达不到要求,所以,只能通过label和input都作浮动,然后li清除浮动,才能勉强达到要求。做这个效果时,也发现了一个问题,就是必需给textarea所在区域和按钮的区域作高度,如若不然将有问题产生,直接上CSS代码吧。

*{ margin:0px; padding:0px;}
ul{ list-style-type:none;}
#reg{ width:600px; height:500px; margin:30px auto;}
#reg ul li{ clear:both; margin-bottom:10px; float:left;}
.text{ width:150px; height:20px;}
#content{ width:280px; height:100px; float:left;}
label{ margin-right:10px; float:left;}
input{ float:left;}
.con{  overflow:hidden; height:110px;}  /*去掉这个.con设置,将有问题*/
.btn{ width:50px; height:25px; margin-right:10px;}
.sub{ height:50px; padding:0px 0 0 150px;}    /*这个高度也是必需的*/
.notice{ padding:3px 5px; background:blue; color:#fff; font-size:12px; margin-right:5px; margin-left:10px;}
.wrong{ background:red;}

这里有个奇怪的问题就是,我在li中设置了clear,但在标准浏览器下margin-bottom不起作用,也就是li与li之间都挤在一起,不好看。通过尝试给它加上个float,则解决了这个问题,这样,同一个li中,又是clear又是float,看起来很矛盾。所以,这样的实现方案虽然能做成效果,但总感觉可控性不强。怪怪的。

接着,我尝试了用dl来作表单,这个做好后,我就决定以后作表单首选dl,因为我可以用dt来包含label,在dd来包含input等内容,然后dt跟dd都作浮动,dl清除浮动,实现了我要的表单需求,以后,不管要怎样添加提示信息或出错信息,只需要添加dd就行了,不用担心会产生错位等问题。这样看起来跟上面的li好像也没大区别。其实不然,如果我给表单添加一些不需要用到label的元素,如select,这样,问题就来了,我们上面解决需求是label作浮动,li清除浮动,select前面的文字不需要label,也就是没得浮动,这样就有问题了,如果只为解决这个问题给它加上一个label,不是不行,只是没意义。而dl则不同,标签比较统一可控,看结构代码:

<form id="reg">
		<dl>
			<dt><label for="usernmae">用 户 名:</label></dt>
			<dd><input type="text" id="usernmae" name="username" class="text" /></dd>
			<dd class="notice"><em>提示信息</em></dd>
			<dd class="notice wrong"><strong>出错信息</strong></dd>
		</dl>
		<dl>
			<dt><label for="pwd">密  码:</label></dt>
			<dd><input type="password" id="pwd" name="pwd" class="text" /></dd>
		</dl>
		<dl>
			<dt><label for="repwd">确认密码:</label></dt>
			<dd><input type="password" id="repwd" name="repwd" class="text" /></dd>
		</dl>
		<dl>
			<dt>生  日:</dt>     <!--这里如果用li作,则不可控,需要添加一个无意义只为布局需要的label标签,用dl,则看起来代码好看得多,也可控得多-->
			<dd>
				<select name="birthYear">
					<option value="" selected="selected">-选择-</option>
				</select>
				<select name="birthMonth">
					<option value="" selected="selected">-选择-</option>
				</select>
				<select name="birthDay">
					<option value="" selected="selected">-选择-</option>
				</select>
			</dd>
		</dl>
		<dl>
			<dt><label for="qq">Q  Q:</label></dt>
			<dd><input type="text" id="qq" name="qq" class="text" /></dd>
		</dl>
		<dl>
			<dt><label for="email">邮  箱:</label></dt>
			<dd><input type="text" id="email" name="email" class="text" /></dd>
		</dl>
		<dl class="con">
			<dt><label for="content">座 右 铭:</label></dt>
			<dd><textarea id="content" ></textarea></dd>
		</dl>
		<dl class="sub">
			<dd><input type="submit" value="提交" class="btn" /></dd>
			<dd><input type="reset" value="重置" class="btn" /></dd>
		</dl>
	</form>

CSS也方便编写,很好控制,没有li那么多这样那样的问题,如下:

*{ margin:0px; padding:0px;}
.text{ width:150px; height:20px;}
#reg{ width:600px; height:500px; margin:30px auto;}
#reg dl{ clear:both;}
#reg dl dt,dd{ height:30px; float:left; margin-right:10px; display:inline;}
#reg dl dd select{ width:60px;}
.btn{ width:50px; height:25px;}
#content{ width:200px; height:90px;}
.con{ height:95px; overflow:hidden;}
.sub{ height:50px; padding:10px 0 0 60px;}
.notice{ height:20px; line-height:20px; padding:1px 5px; background:blue; color:#fff; font-size:12px; }
.wrong{ background:red;}

本来,我觉得这样已经很好了,但却有朋友说,这样的布局,用表格最合适,而我一开始学网页时,就是所谓的div+css了,学的第一课讲的就是table的不好,所以我也一直很少用table,但我还是尝试了用table来布局这样的效果。结果发现,table在这方面确是很有优势,几乎是只将内容放进去,效果就出来了,而不用有多少布局的CSS,代码如下:

<form id="reg">
		<table>
			<tr>
				<td class="left"><label for="username">用 户 名:</label></td>
				<td class="short"><input type="text" id="username" class="text" /></td>
				<td><span class="notice">提示信息</span></td>
				<td><span class="notice wrong">出错信息</span></td>
			</tr>
			<tr>
				<td><label for="pwd">密  码:</label></td>
				<td><input type="password" id="pwd" class="text" /></td>
			</tr>
			<tr>
				<td><label for="repwd">确认密码:</label></td>
				<td><input type="password" id="repwd" class="text" /></td>
			</tr>
			<tr>
				<td>生  日:</td>
				<td>
					<select name="birthYear">
						<option value="" selected="selected">-选择-</option>
					</select>
					<select name="birthMonth">
						<option value="" selected="selected">-选择-</option>
					</select>
					<select name="birthDay">
						<option value="" selected="selected">-选择-</option>
					</select>
				</td>
			</tr>
			<tr>
				<td class="top"><label for="con">座 右 铭:</label></td>
				<td><textarea id="con"></textarea></td>
			</tr>
			<tr>
				<td></td>
				<td><input type="submit" value="提交" class="btn" /><input type="reset" value="重置" class="btn" /></td>
			</tr>
		</table>
	</form>

CSS如下:

*{ margin:0px; padding:0px;}
table{ border-collapse:collapse;}
tr{ height:30px;}
td.top{ vertical-align:top;}
td.left{ width:80px;}
#reg{ width:600px; margin:30px auto;}
.text{ width:150px; height:20px;}
textarea#con{ width:200px; height:90px;}
.btn{ width:50px; height:25px; margin:10px 10px 0 0;}
.notice{ padding:3px 5px; background:blue; color:#fff; font-size:12px; margin-right:5px;}
.wrong{ background:red;}
td.short{ width:155px; border:1px solid #ccc}

这样看起来效果也不错,但我也遇到了table上的问题,就是浏览器对表格的宽度是以单元格也就是td的最大宽度作为基准的,想通过下面代码单独调节td的宽度却做不到:

html
<td class="short"><input type="text" id="username" class="text" /></td>
css
td.short{ width:155px; border:1px solid #ccc}

还有,td间的float表现浏览器间也有差异。具体还有待研究。

而在用列表布局这个效果的过程中,我也遇到了一个以前没发现的问题,就是

ie6/7下 li内浮动元素下边距还有4像素bug。

本来就一直奇怪咋下边有一行空白,还以为是继承了上面的li宽度,但重置也不行,用标尺量了下有4个像素,即便是继承这个4像素也不知哪来的,最后谷歌了下4像素,居然一下就找到答案。最好的解决方案就是直接给li添加:vertical-align属性,除baseline的任意值。

好了,结果已经很明显,将来,我的表单布局,将首选table,不行则再dl。就是这样。

posted @ 2011-04-16 10:37  肥杜  阅读(5303)  评论(4编辑  收藏  举报