2016-10-21 70 views
2

我有一個CSS滑動下拉菜單,可以在顯示的元素數量上有所不同。爲什麼使用高度的保證金最高百分比以及如何解決該問題?

我使用overflow: hidden包裝和margin-top: -100%來隱藏菜單,並使用margin-top: 0進行CSS轉換以向下滑動動畫。

問題似乎是margin-top: -100%似乎正在拾取任何父元素的顯式width並忽略內容高度。

.outer { 
 
    overflow: hidden; 
 
    border: 10px solid red; 
 
    cursor: pointer; 
 
} 
 
.outer > .slide { 
 
    margin-top: -100%; 
 
    transition-property: margin-top; 
 
    transition-duration: 1s; 
 
} 
 
.outer:hover > .slide { 
 
    margin-top: 0; 
 
} 
 
.outer.bug { 
 
    width: 100px; 
 
}
<div class="outer"> 
 
    <div class="slide"> 
 
    <ul> 
 
     <li> 
 
     Ayy 
 
     </li> 
 
     <li> 
 
     Bee 
 
     </li> 
 
     <li> 
 
     See 
 
     </li> 
 
     <li> 
 
     Dee 
 
     </li> 
 
     <li> 
 
     Eee 
 
     </li> 
 
     <li> 
 
     Eff 
 
     </li> 
 
     <li> 
 
     Gee 
 
     </li> 
 
    </ul> 
 
    </div> 
 
</div> 
 

 
<div class="outer bug"> 
 
    <div class="slide"> 
 
    <ul> 
 
     <li> 
 
     Ayy 
 
     </li> 
 
     <li> 
 
     Bee 
 
     </li> 
 
     <li> 
 
     See 
 
     </li> 
 
     <li> 
 
     Dee 
 
     </li> 
 
     <li> 
 
     Eee 
 
     </li> 
 
     <li> 
 
     Eff 
 
     </li> 
 
     <li> 
 
     Gee 
 
     </li> 
 
    </ul> 
 
    </div> 
 
</div>

運行該代碼段,你應該看到兩個紅色箱子,鼠標移到要麼趴下菜單中的幻燈片。

問題是第二個盒子 - 唯一的區別是父母有width: 100px;集合。

如果您檢查第二個框,您應該看到margin-top: -100%;已計算爲-100像素。

事實上,對父div的任何顯式或繼承寬度將成爲負邊距。

我發現它的唯一方法是明確設置margin-top與滑動菜單的高度相同,但涉及到DOM佈局和JS,我並不想爲每個菜單執行此操作。

這是一個瀏覽器如何處理margin-top負數百分比的錯誤? IE11,Chrome和FX似乎都以同樣的方式對待它。

有沒有更好的解決方法,不需要明確的高度計算和額外的Javascript?

+5

這是利潤率如何在CSS定義。 'margin-top',如果給定一個百分比值,則指「包含塊的寬度」。 https://www.w3.org/TR/CSS22/box.html#propdef-margin –

+0

@JamesDonnelly啊,所以它必須使用寬度(這是繼承)的高度(計算從一堆兒童+保證金),因爲這將是一個循環參考。那麼我的問題就變成了:沒有JS calcs的任何方式? – Keith

+0

所以,你可以寫margin-top:-160%或更多,但是我不知道這是不是一件好事。如果使用_viewport height_,可能會更好。 –

回答

1

要移動一個元素(不管它的高度)與其自己的尺寸有關,可以使用transform:translate()而不是邊距。

因此,將元件向上移動自己的高度需要在Y軸上平移-100%。像這樣:

* { 
 
    margin: 0; 
 
    padding: 0; 
 
} 
 
.outer { 
 
    /* overflow: hidden; */ 
 
    padding: 10px; 
 
    background: red; 
 
    cursor: pointer; 
 
    position: relative; 
 
} 
 
.outer > .slide { 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
    transform: translateY(-100%); 
 
    transition-property: transform; 
 
    transition-duration: 1s; 
 
} 
 
.outer:hover > .slide { 
 
    transform: translateY(0%); 
 
}
<div class="outer"> 
 
    <div class="slide"> 
 
    <ul> 
 
     <li>Ayy</li> 
 
     <li>Bee</li> 
 
     <li>See</li> 
 
     <li>Dee</li> 
 
     <li>Eee</li> 
 
    </ul> 
 
    </div> 
 
</div>

然後我們可以使用絕對定位從文檔流取出孩子。

+0

歡呼聲,但那不起作用 - 翻譯保留了元素周圍的原始迴流,因此,您的剪輯具有始終展開的外部紅色邊框div。 – Keith

+0

然後你需要絕對定位,這是一個問題,因爲'overflow-hidden'。這是一個要求嗎? –

+0

是的,雖然在我的代碼片段中,它只是一個非常醜陋的紅色邊框,在我的實際代碼中,包裝本身是絕對定位的,並提供UI提示,如滑動下來的內容上的投影,直到動畫完成。 – Keith

1

margin-top:-100%只有當我們刪除20px分配的.outer的邊界時纔有效,它被使用兩次10px + 10px。所以我們可以在這裏使用CSS calc()函數來獲取我們的輸出。

ul有一個默認padding-top:40px所以這也是使用兩次40px + 40px,我們必須設置爲0px

所以UL和邊界是不工作的margin-top:-100%;

缺省UL屬性的原因:

ul{ 
display: block; 
list-style-type: disc; 
margin-before: 1em; 
margin-after: 1em; 
margin-start: 0; 
margin-end: 0; 
padding-start: 40px; 
} 

.outer { 
 
    overflow: hidden; 
 
    border: 10px solid red; 
 
    cursor: pointer; 
 
    width:auto; 
 
    height:auto; 
 
} 
 
.outer > .slide { 
 
    margin-top: calc(-26px + (-100%)); 
 
    transition-property: margin-top; 
 
    transition-duration: 1s; 
 
    background:#ccc; 
 
} 
 
.outer > .slide > ul{ 
 
    padding:0; 
 
    margin:0; 
 
} 
 
.outer:hover > .slide { 
 
    margin-top: 0; 
 
} 
 
.outer.bug { 
 
    width: 100px; 
 
}
<div class="outer"> 
 
    <div class="slide"> 
 
    <ul> 
 
     <li>Ayy</li> 
 
     <li>Bee</li> 
 
     <li>See</li> 
 
     <li>Dee</li> 
 
     <li>Eee</li> 
 
     <li>Eff</li> 
 
     <li>Gee</li> 
 
    </ul> 
 
    </div> 
 
</div> 
 

 
<div class="outer bug"> 
 
    <div class="slide"> 
 
    <ul> 
 
     <li>Ayy</li> 
 
     <li>Bee</li> 
 
     <li>See</li> 
 
     <li>Dee</li> 
 
     <li>Eee</li> 
 
     <li>Eff</li> 
 
     <li>Gee</li> 
 
    </ul> 
 
    </div> 
 
</div>

+0

@Keith Hope這個工程。 – frnt

+0

它沒有,calc的輸入仍然是寬度,而不是高度 - 嘗試使列表長於寬度,問題再次出現。 – Keith

+0

@Keith檢查這個jsfiddle https://jsfiddle.net/fpLc76xw/我已經添加了幾個li並對calc()進行了更改。第二個.slide ul的自動高度增加了,並且使用calc()減去了它,它起作用。但是會隨着我在另一個解決方案上的輸出而更新。 – frnt

相關問題