最近工作中做了幾件事情都與頁面元素定位相關,是以這裡将工作中遇到的問題以及解決方法記錄在部落格裡,以便日後查閱。
疊壓
有一個任務是做一個清單元件,清單中的每一行都要向上疊壓上一行的底邊,注意,是疊壓,不是接壤。
問題分析:
利用相對定位(position:relative)來制造相對于行(row)的偏移量,使行内元素向上偏移,并疊壓上一行的行内元素的底邊。
既然是相對定位,那就不能讓每一行的定位基準點基于上一行的底邊。因為,基準點不會因為上一行元素被CSS搞過之後而同時發生偏移。
舉例說明: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的底邊。
解決思路:
就像問題分析中開頭說的那樣,解決方法很簡單,就是不要讓後續元素的定位基準點基于前一個會改變位置的元素。如下圖:
上圖是原先的元素排列結構。這種結構中,每個要向上偏移的元素定位基準點就是上一個也需要變動位置的元素的左下角。這樣是不能實作我們的需求的。隻要在元素結構上稍加改變,就可以了。下圖是結構改造後的元素結構:
在原來每個元素内部再添加一個box元素(藍色元素)。将偏移設定在這個box元素上。因為每個淺藍色的box元素都是基于其上層box元素(黑色邊框的div)的,而非前面一個需要變動位置的box元素,是以每個淺藍色的box元素進行偏移時、增加高度時,都不會改變下一個淺藍色box的定位基準點。而且,每個淺藍色box元素的高度增加,也不會導緻其上層box元素(黑色邊框的div)高度改變,因為淺藍色box元素改變了其top屬性後,它就被認為是個浮動元素。一個浮動元素不會撐大包含它的上層box元素。是以第二個黑框div,以及第三個黑框div的定位基準點都不會發生改變。如此一來,我們便可以實作淺藍色box元素互相疊壓的效果了。
實作代碼:
<code><!DOCTYPE html></code>
<code><</code><code>html</code><code>></code>
<code> </code><code><</code><code>head</code><code>></code>
<code> </code><code><</code><code>meta</code> <code>charset</code><code>=</code><code>"UTF-8"</code><code>></code>
<code> </code><code><</code><code>title</code><code>></</code><code>title</code><code>></code>
<code> </code><code><</code><code>style</code><code>></code>
<code> </code><code>body {</code>
<code> </code><code>margin: 20px;</code>
<code> </code><code>}</code>
<code> </code><code>.nav-menu-bar {</code>
<code> </code><code>height: 500px;</code>
<code> </code><code>width: 350px;</code>
<code> </code><code>overflow-x: auto;</code>
<code> </code><code>.menu-item-slot {</code>
<code> </code><code>height: 50px;</code>
<code> </code><code>width: 100%;</code>
<code> </code><code>.nav-menu-bar .menu-item {</code>
<code> </code><code>background-color: rgba(128,176,224, 1.0); /*rgba()#6699cc;*/</code>
<code> </code><code>border-radius: 8px 8px 0px 0px;</code>
<code> </code><code>box-shadow: 0px -5px 5px -2px #375e8c;</code>
<code> </code><code>position: relative;</code>
<code> </code><code>top: -8px;</code>
<code> </code><code>height: 58px; /* ------ Be careful ------ */</code>
<code> </code><code>overflow: hidden;</code>
<code> </code><code>.menu-item .content {</code>
<code> </code><code>margin-top: 8px;</code>
<code> </code><code>margin-left: 8px;</code>
<code> </code><code>width: 94%;</code>
<code> </code><code>height: 72%;</code>
<code> </code><code>vertical-align: top;</code>
<code> </code><code>overflow-x: hidden;</code>
<code> </code><code>color: #fafafa;</code>
<code> </code><code>.nav-menu-bar .menu-item-slot:hover {</code>
<code> </code><code>transition: height 0.3s;</code>
<code> </code><code>height: 200px;</code>
<code> </code><code>.nav-menu-bar .menu-item-slot:first-child:hover {</code>
<code> </code><code>height: 208px;</code>
<code> </code><code>.nav-menu-bar .menu-item-slot:first-child .menu-item:hover {</code>
<code> </code><code>.nav-menu-bar .menu-item:hover {</code>
<code> </code><code>.nav-menu-bar .menu-item-slot:first-child {</code>
<code> </code><code>height: 58px;</code>
<code> </code><code>.nav-menu-bar .menu-item-slot:first-child .menu-item {</code>
<code> </code><code>box-shadow: none;</code>
<code> </code><code>top: 0px;</code>
<code> </code><code>.nav-menu-bar .menu-item-slot:last-child .menu-item {</code>
<code> </code><code>border-radius: 8px 8px 8px 8px;</code>
<code> </code><code></</code><code>style</code><code>></code>
<code> </code><code></</code><code>head</code><code>></code>
<code> </code><code><</code><code>body</code><code>></code>
<code> </code><code><</code><code>div</code> <code>class</code><code>=</code><code>"nav-menu-bar"</code><code>></code>
<code> </code><code><</code><code>div</code> <code>class</code><code>=</code><code>"menu-item-slot"</code><code>></code>
<code> </code><code><</code><code>div</code> <code>class</code><code>=</code><code>"menu-item"</code><code>></code>
<code> </code><code><</code><code>div</code> <code>class</code><code>=</code><code>"content"</code><code>>Created in 1998, its name is derived from the World Wide Web,</</code><code>div</code><code>></code>
<code> </code><code></</code><code>div</code><code>></code>
<code> </code><code></</code><code>div</code><code>></code>
<code> </code><code><</code><code>div</code> <code>class</code><code>=</code><code>"menu-item"</code><code>></</code><code>div</code><code>></code>
<code> </code><code></</code><code>div</code><code>></code>
<code> </code><code></</code><code>body</code><code>></code>
<code></</code><code>html</code><code>></code>
本文轉自 rickqin 51CTO部落格,原文連結:http://blog.51cto.com/rickqin/2051430