2015-09-25 40 views
4

我有一個包含一些子菜單的菜單,像這樣的條件多列

.menu { 
 
    position: absolute; 
 
    background: yellow; 
 
    margin-top: 2em; 
 
} 
 
header { 
 
    font-size: 20px; 
 
} 
 
ul { 
 
    -moz-column-count: 2; 
 
    -moz-column-gap: 10px; 
 
    -webkit-column-count: 2; 
 
    -webkit-column-gap: 20px; 
 
    column-count: 2; 
 
    column-gap: 10px; 
 
    list-style: none; 
 
    padding: 0; 
 
} 
 
li:nth-child(odd) {background: lightblue; } 
 
li:nth-child(even) {background: lightyellow; } 
 
div:not(.main) { 
 
    display: inline-block; 
 
    position: relative; 
 
}
<div>menu one 
 
    <div class="menu"> 
 
    <header>menu one header</header> 
 
    <ul> 
 
     <li>Item one</li> 
 
     <li>Item two 2</li> 
 
     <li>Item tree</li> 
 
     <li>Item four</li> 
 
     <li>Item five</li> 
 
     <li>six</li> 
 
     <li>Item 7</li> 
 
    </ul> 
 
    </div> 
 
</div> 
 
<div>menu two</div>

我需要的是2列僅出現如果有超過4項在.menu>ul列表中。

是否有可能使用純CSS?

+0

什麼專欄?這兩個菜單是'列'?如果少於4個項目,是否應該出現?我不認爲你可以這樣做,因爲CSS唯一重要的是孩子,所以你不能做這樣的事情:「當這件事的孩子數量是x或更多時,對父母/其他事情做些事情」 - 那就是什麼是JavaScript的。 – somethinghere

+0

是的,如果不將它分成兩個'ul'元素,你就無法做到這一點......如果有人有解決方案,我會非常好奇,但我敢肯定,這個問題歸結爲CSS只是不擅長計數或if語句... – somethinghere

+0

有一點'hack'已被用於執行此操作:http://alistapart.com/article/quantity-queries-for-css但是,似乎存在一些性能問題方法。 –

回答

1

我們可以做數量查詢,只有訂單問題。如果您對該訂單妥協,我們可以使用數量查詢。

ul { 
    margin:0; padding:0; list-style:none; 
} 

li { 
    width:40%; 
    border:1px solid red; 
    margin:2px; 
} 


ul li:nth-last-child(n+5), 
ul li:nth-last-child(n+5) ~ li { 
    float:left; 
} 

demo

+1

請在這裏添加您的答案的代碼。只有鏈接的答案往往不太有用,如果鏈接停止工作(使您的答案不完整和無用) – ochi

1

你可以利用這裏所描述的絕招 - http://alistapart.com/article/quantity-queries-for-css,已經提出的通過@Jesse Kernaghan in the comments above

但是,爲了能夠做到這一點,你需要做兩件事硬連線:

  1. 修復容器ul的高度和寬度,以及
  2. 修復li的高度並確保此寬度乘以n等於容器的高度ul。其中n是你的幻數,你的情況爲4

這是必需的,這樣的CSS columns不迴流的內容和該li排列成列在可預見的方式。

如果您的標記和使用情況也可以與上述兩個約束工作,那麼你可以使用下面的CSS選擇:

li:nth-last-child(4):first-child, 
li:nth-last-child(4):first-child ~ li { 
    width: 160px; 
} 

中的第一選擇會選擇li這是4 從並且恰好是第一個,在一組恰好四個li s中僅有效地選擇第一個li,其中4是您的幻數。

第二個選擇器(一般兄弟組合器)將選擇第一個之後存在的所有li

將固定寬度應用於這些li s給出出現一列。

例摘錄

div.menu { 
 
    display: inline-block; vertical-align: top; 
 
    background: yellow; margin: 2em 1em; 
 
} 
 
header { font-size: 20px; } 
 
ul { 
 
    width: 160px; -moz-columns: 2 auto; -moz-column-fill: auto; 
 
    -webkit-columns: 2 auto; columns: 2 auto; 
 
    list-style: none; padding: 0; height: 8em; 
 
} 
 
li { height: 2em; } 
 
li:nth-child(odd) {background: lightblue; } 
 
li:nth-child(even) {background: lightyellow; } 
 

 
li:nth-last-child(4):first-child, li:nth-last-child(4):first-child ~ li { 
 
    width: 160px; 
 
}
<div class="menu"> 
 
    <header>menu one</header> 
 
    <ul> 
 
    <li>Item one</li> 
 
    <li>Item two 2</li> 
 
    <li>Item tree</li> 
 
    <li>Item four</li> 
 
    <li>Item five</li> 
 
    <li>six</li> 
 
    <li>Item 7</li> 
 
    </ul> 
 
</div> 
 
<div class="menu"> 
 
    <header>menu two</header> 
 
    <ul> 
 
    <li>Item one</li> 
 
    <li>Item two 2</li> 
 
    <li>Item tree</li> 
 
    <li>Item four</li> 
 
    </ul> 
 
</div> 
 
<div class="menu"> 
 
    <header>menu three</header> 
 
    <ul> 
 
    <li>Item one</li> 
 
    <li>Item two 2</li> 
 
    <li>Item tree</li> 
 
    <li>Item four</li> 
 
    <li>Item five</li> 
 
    </ul> 
 
</div>

+0

@Siguza:謝謝指出。我錯過了「-moz」規則。更新。 – Abhitalks

+0

這也爲'ul'外的每4個元素創建新的列,所以第9個元素將在第3列中,第4列中的第13個元素,... – Siguza

+0

是@Siguza。 Op必須根據「li」的數量來製作這個。在這種情況下,超越8會破壞它。 – Abhitalks

1

這裏是一個方式,用鍍鉻,FF,IE11和邊緣測試,但仍與一些固定值,並且需要的,如果被調整超過8個項目。

li高度需要固定,然後負margin-top將是該高度的4倍,以將正確的項目推到頂部。

這裏的訣竅是當需要2個「列」時,讓每個項目的寬度超過可用寬度的50%,因此浮動塊保持在其一側,然後向上推動右側「列」,使其與左側對齊。

.menu { 
 
    position: absolute; 
 
    background: yellow; 
 
    margin-top: 2em; 
 
} 
 
header { 
 
    font-size: 20px; 
 
} 
 
ul { 
 
    list-style: none; 
 
    padding: 0; 
 
} 
 
li:nth-child(odd) {background: lightblue; } 
 
li:nth-child(even) {background: lightyellow; } 
 

 
li { position: relative; height: 20px; } 
 
li:nth-child(-n+4) { float: left; width: 48%; margin-right: 3%; } 
 
li:nth-child(n+5) { float: right; width: 48%; margin-left: 3%; top: -80px } 
 

 
li:nth-last-child(4):first-child, li:nth-last-child(4):first-child ~ li { 
 
    width: 94%; margin-right: 6% 
 
} 
 

 
div:not(.main) { 
 
    display: inline-block; 
 
    position: relative; 
 
}
<div>menu one 
 
    <div class="menu"> 
 
    <header>menu one header</header> 
 
    <ul> 
 
     <li>Item one</li> 
 
     <li>Item two 2</li> 
 
     <li>Item tree</li> 
 
     <li>Item four</li> 
 
     <li>Item five</li> 
 
     <li>six</li> 
 
     <li>Item 7</li> 
 
    </ul> 
 
    </div> 
 
</div> 
 
<div>menu two 
 
    <div class="menu"> 
 
    <header>menu two header</header> 
 
    <ul> 
 
     <li>Item one</li> 
 
     <li>Item two 2</li> 
 
     <li>Item tree</li> 
 
     <li>Item four</li> 
 
    </ul> 
 
    </div> 
 
</div>

更新這裏是另一種方式,具有柔性。

基於li高度和ul高度n項目將適合每列。

.menu { 
 
    position: absolute; 
 
    background: yellow; 
 
    margin-top: 2em; 
 
} 
 
header { 
 
    font-size: 20px; 
 
} 
 
ul { 
 
    list-style: none; 
 
    padding: 0; 
 
    display: flex; 
 
    flex-direction: column; 
 
    flex-wrap: wrap; 
 
    height: 100px; 
 
} 
 

 
li { 
 
    height: 22px; 
 
} 
 

 
li:nth-child(odd) {background: lightblue; } 
 
li:nth-child(even) {background: lightyellow; } 
 

 
div:not(.main) { 
 
    display: inline-block; 
 
    position: relative; 
 
}
<div>menu one 
 
    <div class="menu"> 
 
    <header>menu one header</header> 
 
    <ul> 
 
     <li>Item one</li> 
 
     <li>Item two 2</li> 
 
     <li>Item tree</li> 
 
     <li>Item four</li> 
 
     <li>Item five</li> 
 
     <li>six</li> 
 
     <li>Item 7</li> 
 
    </ul> 
 
    </div> 
 
</div> 
 
<div>menu two 
 
    <div class="menu"> 
 
    <header>menu two header</header> 
 
    <ul> 
 
     <li>Item one</li> 
 
     <li>Item two 2</li> 
 
     <li>Item tree</li> 
 
     <li>Item four</li> 
 
    </ul> 
 
    </div> 
 
</div> 
 
<div>menu three 
 
    <div class="menu"> 
 
    <header>menu three header</header> 
 
    <ul> 
 
     <li>Item one</li> 
 
     <li>Item two 2</li> 
 
     <li>Item tree</li> 
 
     <li>Item four</li> 
 
     <li>Item five</li> 
 
     <li>Item six</li> 
 
     <li>Item seven</li> 
 
     <li>Item eight</li> 
 
     <li>Item nine</li> 
 
     <li>Item ten</li> 
 
    </ul> 
 
    </div> 
 
</div>

+0

雖然這會在第二列保留所有元素大於4,但是使12個條目(例如)的菜單看起來相當不平衡。 – Siguza

+0

@Siguza是的,如果超過8個項目需要根據每列或更多列應該有更多項目進行調整,但該解決方案顯示瞭如何執行的方法。 – LGSon

+0

謝謝,不幸的是flex與IE9不兼容,我們必須支持...所以我不能使用它( – Serge

0

嘛,會有一個「乾淨」的方式(不依賴於任何硬編碼的數字),但當然有一個問題...

你可以使用只需使ul始終爲兩列,而不是使用column-span: all使所有li元素跨所有列,並且通過使所有li元素(如果有多於四個(nth-last-child(n + 5)),不是跨越所有列。
Buuut ... Firefox doesn't support this(撰寫本文時)。

.menu { 
 
    position: absolute; 
 
    background: yellow; 
 
    margin-top: 2em; 
 
} 
 
header { 
 
    font-size: 20px; 
 
} 
 
ul { 
 
    -webkit-column-count: 2; 
 
    -webkit-column-gap: 20px; 
 
    column-count: 2; 
 
    column-gap: 10px; 
 
    list-style: none; 
 
    padding: 0; 
 
} 
 
li:nth-child(odd) {background: lightblue; } 
 
li:nth-child(even) {background: lightyellow; } 
 
div:not(.main) { 
 
    display: inline-block; 
 
    position: relative; 
 
} 
 
li { 
 
    -webkit-column-span: all; 
 
    column-span: all; 
 
} 
 
li:nth-last-child(n + 5), li:nth-last-child(n + 5) ~ li { 
 
    -webkit-column-span: none; 
 
    column-span: none; 
 
}
<div>menu one 
 
    <div class="menu"> 
 
    <header>menu one header</header> 
 
    <ul> 
 
     <li>Item one</li> 
 
     <li>Item two 2</li> 
 
     <li>Item t(h)ree</li> 
 
     <li>Item four</li> 
 
    </ul> 
 
    </div> 
 
</div><div>menu two 
 
    <div class="menu"> 
 
    <header>menu two header</header> 
 
    <ul> 
 
     <li>Item one</li> 
 
     <li>Item two 2</li> 
 
     <li>Item t(h)ree</li> 
 
     <li>Item four</li> 
 
     <li>Item five</li> 
 
    </ul> 
 
    </div> 
 
</div>

我希望這將有一天成爲未來的讀者有用,但。

還有一種方法可以用一個包裝的雙列Flexbox做到這一點,但是我的嘗試失敗了。