同早年~
问题描述
在xx项目中,羊城通卡号的输入框处使用了xx库中的实现方式,即将提示文字标签<label>通过负margin移位到<input>框的下面。静态时展现良好,js逻辑添加后发现,输入文字时<input>框会抖动。排查后发现,是重置了<label>的负margin值引起的。这引起了我对负margin定位的兴趣,于是乎,做了个简单的测试。
Demo测试
初始状态:
图 (1)
灰框 {margin-bottom:-10px;}:
图 (2)
灰框 {margin-bottom:-30px;}:
图 (3)
绿框 {margin-top:-10px;}:
图 (4)
绿框 {margin-top:-30px;}:
图 (5)
灰框 {margin-top:-30px;}:
图 (6)
以上可以看出:
- 元素的margin-bottom为负值时,元素本身不动,其下的元素上移(图2、3)。
- 元素的margin-top为负值时,元素上移,其下的元素也跟着上移(图4、5、6)。
- 上下紧邻的两个元素,设置上面元素的margin-bottom与设置下面元素的margin-top,视觉效果相同(图2与4、3与5的比较)。
让灰框和绿框都左浮,下面添加一没有清浮的段落,再来测一组:
初始状态:
图 (1)
绿框 {margin-bottom:-29px;}:
图 (2)
绿框 {margin-bottom:-30px;}:
图 (3)
从上一组测试的图2、3,以及这组数据可以很形象地看出,当元素的margin-bottom设为负的x像素时,就好像这个元素释放出了下方x像素的空间,当x等于该元素的高度时,空间完全被释放,其它元素就当该元素不存在似的。故本组图2中的”text”还卡在绿框的右边,而图三中(负margin-bottom值等于元素高度)”text”“穿”过绿框,直接卡到了灰框的右侧。
水平方向的大致类似,即元素的margin-right为负值时,元素本身不动,右侧的元素左移,元素的margin-left为负值时,元素左移,右侧的元素也跟着左移。
问题分析
了解了负margin尤其是负margin-bottom的定位原则,再来看前面提到的抖动问题:
因为<input>框中输入文字时,提示文字是要消失的(<label>标签{display:none;}),故<label>的负margin-bottom值要与<label>的高度一致。否则若值过大(如-31px),输入文字时<input>框会向下抖动,若值过小(如-29px),则输入文字时<input>框会向上抖动。知道了这些,也就不难理解库中为什么通过设置<label>的负margin-bottom,而不是通过设置<input>的负margin-top来实现两个元素的叠加效果了。
2012.12.8