关于表单布局
今天终于在博客园开博了,不为什么,只为将自己在学习上的收获作个收藏积累。经常在谷歌搜索问题,经常都能在博客园找到满意的答案,这是个好地方,所以我决定在这里安家。
我不是个善于文字的人,也就不多说了。直接进入主题。
一直以来,对表单布局没有一个好的习惯,有时候想用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。就是这样。