最近工做中作了幾件事情都與頁面元素定位相關,因此這裏將工做中遇到的問題以及解決方法記錄在博客裏,以便往後查閱。html
疊壓ide
有一個任務是作一個列表組件,列表中的每一行都要向上疊壓上一行的底邊,注意,是疊壓,不是接壤。spa
問題分析:3d
利用相對定位(position:relative)來製造相對於行(row)的偏移量,使行內元素向上偏移,併疊壓上一行的行內元素的底邊。htm
既然是相對定位,那就不能讓每一行的定位基準點基於上一行的底邊。由於,基準點不會由於上一行元素被CSS搞過以後而同時發生偏移。blog
舉例說明:2個div上下排列,第一個div(class="div1")height爲100px,而且向上偏移-10px。第二個div(class="div2")height也是100px,但願疊壓到div1的底邊10px,因此也設置了top: -10px。若是div1的基準點Y軸座標=0px,那麼,在div1沒有發生偏移的狀況下,div2的基準點Y軸座標= div1.top + div1.height,也就是0px + 100px = 100px。如今,div1.top = -10px,即向上偏移10px,按理說,div2的基準點= -10px + 100px = 90px。惋惜,現實並不是如此。div2的基準點並無任何改變。因此,div2.top = -10px 依舊沒法疊壓到div1的底邊。只有當div2.top=-20px纔可能疊壓到div1底邊10px處。有人說此處應該讓div1的高度增長10px,這樣,div2就能疊壓到div1了。我作了嘗試,發現當div1的高度增長10px後,div2的原始基準點Y軸座標也跟着+10px。如此,從新套用公式:div2的定位基準點Y軸座標 = div1的定位基準點Y軸座標 + div1高度,從新獲得div2的定位基準點Y軸座標爲110px。110px-10px的向上偏移量=100px,而div1雖然高度增長到了110px,但是它向上偏移了-10px,div2仍是疊壓不到div1的底邊。博客
解決思路:it
就像問題分析中開頭說的那樣,解決方法很簡單,就是不要讓後續元素的定位基準點基於前一個會改變位置的元素。以下圖:io
上圖是原先的元素排列結構。這種結構中,每一個要向上偏移的元素定位基準點就是上一個也須要變更位置的元素的左下角。這樣是不能實現咱們的需求的。只要在元素結構上稍加改變,就能夠了。下圖是結構改造後的元素結構:ast
在原來每一個元素內部再添加一個box元素(藍色元素)。將偏移設置在這個box元素上。由於每一個淺藍色的box元素都是基於其上層box元素(黑色邊框的div)的,而非前面一個須要變更位置的box元素,因此每一個淺藍色的box元素進行偏移時、增長高度時,都不會改變下一個淺藍色box的定位基準點。並且,每一個淺藍色box元素的高度增長,也不會致使其上層box元素(黑色邊框的div)高度改變,由於淺藍色box元素改變了其top屬性後,它就被認爲是個浮動元素。一個浮動元素不會撐大包含它的上層box元素。因此第二個黑框div,以及第三個黑框div的定位基準點都不會發生改變。如此一來,咱們即可以實現淺藍色box元素相互疊壓的效果了。
實現代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style> body { margin: 20px; } .nav-menu-bar { height: 500px; width: 350px; overflow-x: auto; } .menu-item-slot { height: 50px; width: 100%; } .nav-menu-bar .menu-item { background-color: rgba(128,176,224, 1.0); /*rgba()#6699cc;*/ border-radius: 8px 8px 0px 0px; box-shadow: 0px -5px 5px -2px #375e8c; position: relative; top: -8px; height: 58px; /* ------ Be careful ------ */ width: 100%; overflow: hidden; } .menu-item .content { margin-top: 8px; margin-left: 8px; width: 94%; height: 72%; vertical-align: top; overflow-x: hidden; color: #fafafa; } .nav-menu-bar .menu-item-slot:hover { transition: height 0.3s; height: 200px; } .nav-menu-bar .menu-item-slot:first-child:hover { transition: height 0.3s; height: 208px; } .nav-menu-bar .menu-item-slot:first-child .menu-item:hover { transition: height 0.3s; height: 208px; } .nav-menu-bar .menu-item:hover { transition: height 0.3s; height: 208px; } .nav-menu-bar .menu-item-slot:first-child { height: 58px; } .nav-menu-bar .menu-item-slot:first-child .menu-item { box-shadow: none; top: 0px; } .nav-menu-bar .menu-item-slot:last-child .menu-item { border-radius: 8px 8px 8px 8px; } </style> </head> <body> <div class="nav-menu-bar"> <div class="menu-item-slot"> <div class="menu-item"> <div class="content">Created in 1998, its name is derived from the World Wide Web,</div> </div> </div> <div class="menu-item-slot"> <div class="menu-item"> <div class="content">Created in 1998, its name is derived from the World Wide Web,</div> </div> </div> <div class="menu-item-slot"> <div class="menu-item"> <div class="content">Created in 1998, its name is derived from the World Wide Web,</div> </div> </div> <div class="menu-item-slot"> <div class="menu-item"></div> </div> </div> </body> </html>