同早年~
問題描述
在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