一、需求
典型的注册页面设计一般是一个三列多行的表格,左列为表单项label,中列为文本框,右列为填写说明和验证提示。如下图
因为整个表单的视觉重心在左中两列,所以在考虑表单整体相对页面水平居中和注册提交按钮的位置设计时,应当忽略掉右列。
由此来说,右列显示的填写说明和验证提示应当以一个不影响前整体表格宽度的绝对定位来显示,并且需要显示在文本框的右侧垂直居中位置。
二、html+css实现
absolute定位的提示div放在定位relative的td里面,left设为中列的宽度,top设为50%,margin-top设为-(提示div的高度/2),这样便可以做到右侧垂直居中了,如下
<td style="font-size:14px;text-align:center;height:100px;position:relative;">
<div style="position: absolute;left: 300px;top:50%;height: 20px;line-height: 20px;margin-top:-10px;background: green;margin-left: 5px; 300px;text-align:left;">填写说明</div>
</td>
这种方式在IE8、chrome中完美实现,但是在IE9中出现了兼容性问题,top:50%并没有让它垂直居中。
三、浏览器兼容
测试多次完全看不出这50%的基准高度是根据谁来的(如果哪位朋友路过此地并且看出了这个50%的基准元素,请在下面留下您的脚印),无奈之下只好寻找其他办法,好在纠结良久之后,终于灵光一闪,把div的display设置为inline-block,并取消top的值设定,就可以像文本一样实现在td里的垂直居中了(不设置top时,默认top值和td内top最靠上的子元素一致,比如下图昵称行中的input)。两种css方式在chrome中的效果对比如下
虽然修改后的居中效果并不如第一种的效果理想,但是能够做到兼容ie9,这样的效果也足够了,如果追求完美可以给div调整一下margin-top。
四、更多的兼容性问题
此问题本该到此结束了,但是在我为此表单添加了一个头像行,并且把td内input的width调整为100%时,新的问题又来了,如下图
次奥,又是一阵分析:
.lineTip{position: absolute;left: 300px;top:50%;height: 20px;line-height: 20px;margin-top:-10px;background: green;margin-left: 5px;width: 300px;text-align:left;}/*这是效果最优的方式,但是ie9不兼容*/
.lineTipFix{position: absolute;left: 300px;display:inline-block;height: 20px;line-height: 20px;background: green;margin-left: 5px;width: 300px;text-align:left;}/*这种方式虽然兼容了ie9实现了提示部分相对td中文本框居右并垂直居中的效果(默认top值和td内top最靠上的子元素一致)。但是有一个前提条件:td中不能存在relative定位并且占满整个td宽度的元素(比如td中100%的input ,如chrome下的昵称2;td中display:block的div,如头像)*/
无语,想实现完美的效果并保证兼容性的话,至此,除了放弃table布局,我没有其他办法了。
五、Demo
对比IE8/9、chrome查看效果:http://youryida.duapp.com/demo_css/regTipMiddleShow.html
<!doctype html>
<html>
<head>
<title></title>
<meta http-equiv="X-UA-Compatible" content="IE=9">
<meta charset="utf-8" />
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache, must-revalidate">
<meta http-equiv="expires" content="0">
<style>
*{padding:0;margin:0;font-family: 'Microsoft Yahei';}
table{border-collapse:collapse;margin: 5px auto;}
td{font-size:14px;text-align:center;height:80px;position:relative;}
td.label{width:50px;text-align:right;padding-right:10px;}
td.label:after{content:":";}
td.cont{width:300px;text-align:left;}
td input[type="text"]{width:90%;height:25px;}
.lineTip{position: absolute;left: 300px;top:50%;height: 20px;line-height: 20px;margin-top:-10px;background: green;margin-left: 5px;width: 300px;text-align:left;}/*这是效果最优的方式,但是ie9不兼容*/
.lineTipFix{position: absolute;left: 300px;display:inline-block;height: 20px;line-height: 20px;background: green;margin-left: 5px;width: 300px;text-align:left;}/*这种方式虽然兼容了ie9实现了提示部分相对td中文本框居右并垂直居中的效果(默认top值和td内top最靠上的子元素一致)。但是有一个前提条件:td中不能存在relative定位并且占满整个td宽度的元素(比如td中100%的input、td中display:block的div)*/
</style>
</head>
<body>
<table id="formTable">
<tr style="background:#ddd;">
<td class="label">姓名</td>
<td class="cont">
<input type="text" id="name"/><div class="lineTip">填写真实姓名</div>
</td>
</tr>
<tr style="background:#ccc;">
<td class="label">昵称</td>
<td class="cont">
<input type="text" id="nickName"/><div class="lineTipFix">昵称为字母数字下划线组合,不可为汉字</div>
</td>
</tr>
<tr style="background:#ddd;">
<td class="label">昵称2</td>
<td class="cont">
<input type="text" style="100%;"/><div class="lineTipFix">昵称为字母数字下划线组合,不可为汉字</div>
</td>
</tr>
<tr style="background:#ccc;">
<td class="label">头像</td>
<td class="cont" style="text-align:center;">
<div style="height: 64px;64px;background-color: #eee;"></div><div class="lineTipFix">图片大小应小于2M</div>
</td>
</tr>
</table>
<div style="margin:10px 50px;">
<h3>Intro</h3>
表格有两列,左侧项名,右侧项值,并且这两列决定表格总宽度,整个表格要相对页面水平居中。为了不影响右列td以及整个表格的宽度,绿色填写提示部分放在了右列td里面,并且使用绝对定位。<br/>
需求:绿色部分需要在右列td右面,并垂直居中。<br/>
问题:姓名行的填写提示区域,在IE9中存在错位bug。<br/>
兼容性解决及纠结:<br/>
.lineTip{position: absolute;left: 300px;top:50%;height: 20px;line-height: 20px;margin-top:-10px;background: green;margin-left: 5px; 300px;text-align:left;}/*这是效果最优的方式,但是ie9不兼容*/<br/>
.lineTipFix{position: absolute;left: 300px;display:inline-block;height: 20px;line-height: 20px;background: green;margin-left: 5px; 300px;text-align:left;}/*这种方式虽然兼容了ie9实现了提示部分相对td中文本框居右并垂直居中的效果(默认top值和td内top最靠上的子元素一致)。但是有一个前提条件:td中不能存在relative定位并且占满整个td宽度的元素(比如td中100%的input ,如chrome下的昵称2;td中display:block的div,如头像)*/<br/><br/>
感悟总结及解决办法:<br/>
次奥,td的浏览器兼容性太不靠谱了,我决定放弃table布局了,over。
</div>
</body>
</html>
六、思考总结
如果需要进行比较复杂的定位布局,请不要使用table。