質問
使っています ColdFusion
以下を含むテンプレートを設定するには HTML
リスト (<ul>
さん)。
これらのほとんどはそれほど長くありませんが、いくつかは途方もなく長いもので、本当に 2 ~ 3 列に収まる可能性があります。
ありますか? HTML
, ColdFusion
多分 JavaScript
(jQuery`が利用可能です)これを簡単に行う方法はありますか?スクロールを節約するために、過度に複雑で強力なソリューションを使用する価値はありません。
解決
そこで私はA List Apartからこの記事を掘り出しました CSS スワッグ:複数列のリスト. 。私は最終的に最初の解決策を使用しました。これは最良ではありませんが、他の解決策では、動的に生成できない複雑な HTML を使用するか、多数のカスタム クラスを作成する必要があります。これは可能ですが、大量のインライン スタイル設定と処理が必要になります。おそらく巨大なページ。
ただし、他のソリューションも引き続き歓迎されます。
他のヒント
Safari と Firefox のサポートが十分であれば、CSS ソリューションがあります。
ul {
-webkit-column-count: 3;
-moz-column-count: 3;
column-count: 3;
-webkit-column-gap: 2em;
-moz-column-gap: 2em;
column-gap: 2em;
}
オペラについてはよくわかりません。
私の知る限り、これを実現する純粋な CSS/HTML 方法はありません。最善の策は、前処理でこれを行うことです(if list length > 150, split into 3 columns, else if > 70, split into 2 columns, else 1
).
もう 1 つのオプションは、JavaScript を使用する方法です (JavaScript には詳しくありません)。 jQuery 特にライブラリ)は、おそらく特定のクラスであることに基づいてリストを反復処理し、子の数を数え、それが十分に大きい場合は、最初のリストの後に新しいリストを動的に作成し、いくつかのリスト項目を新しいリスト。列を実装する限り、おそらく列を左にフロートさせ、その後にスタイルを持つ要素を続けることができます。 clear: left
または clear: both
.
.column {
float: left;
width: 50%;
}
.clear {
clear: both;
}
<ul class="column">
<li>Item 1</li>
<li>Item 2</li>
<!-- ... -->
<li>Item 49</li>
<li>Item 50</li>
</ul>
<ul class="column">
<li>Item 51</li>
<li>Item 52</li>
<!-- ... -->
<li>Item 99</li>
<li>Item 100</li>
</ul>
<div class="clear">
私はこれを jQuery で実行しました。これはクロスプラットフォームであり、最小限のコードで済みます。
UL を選択してクローンを作成し、前の UL の後に挿入します。何かのようなもの:
$("ul#listname").clone().attr("id","listname2").after()
これにより、リストのコピーが前のリストの後に挿入されます。元のリストが float:left でスタイル設定されている場合は、並べて表示されるはずです。
次に、左側のリストから偶数項目を削除し、右側のリストから奇数項目を削除します。
$("ul#listname li:even").remove();
$("ul#listname2 li:odd").remove();
これで、左から右への 2 列のリストが完成しました。
使用したい列をさらに実行するには .slice(begin,end)
および/または :nth-child
セレクタ。つまり、21 LI の場合、次のことが可能です。 .slice(8,14)
元の UL の後に挿入された新しい UL を作成し、元の UL を選択して、選択した li を削除します。 ul :gt(8)
.
jQuery に関する Bibeault/Katz の本を試してみてください。これは素晴らしいリソースです。
ここにバリエーションがあります サムキンさんの 例 (Jquery を使用):
var $cat_list = $('ul#catList'); // UL with all list items.
var $cat_flow = $('div#catFlow'); // Target div.
var $cat_list_clone = $cat_list.clone(); // Clone the list.
$('li:odd', $cat_list).remove(); // Remove odd list items.
$('li:even', $cat_list_clone).remove(); // Remove even list items.
$cat_flow.append($cat_list_clone); // Append the duplicate to the target div.
ありがとうサムキン!
次の JavaScript コードは Spidermonkey と Rhino でのみ機能し、E4X ノードで動作します。つまり、これはサーバーサイド JavaScript でのみ役立ちますが、jQuery バージョンを実行するための出発点となる可能性があります。(これはサーバー側では非常に便利ですが、クライアントでは実際に構築するほど必要になりませんでした。)
function columns(x,num) {
num || (num = 2);
x.normalize();
var cols, i, j, col, used, left, len, islist;
used = left = 0;
cols = <div class={'columns cols'+num}></div>;
if((left = x.length())==1)
left = x.children().length();
else
islist = true;
for(i=0; i<num; i++) {
len = Math.ceil(left/(num-i));
col = islist ? new XMLList
: <{x.name()}></{x.name()}>;
if(!islist && x['@class'].toString())
col['@class'] = x['@class'];
for(j=used; j<len+used; j++)
islist ? (col += x[j].copy())
: (col.appendChild(x.child(j).copy()));
used += len;
left -= len;
cols.appendChild(<div class={'column'+(i==(num-1) ? 'collast' : '')}>{col}</div>);
}
return cols;
}
あなたはそれを次のように呼びます columns(listNode,2)
2 列の場合、次のようになります。
<ul class="foo">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
の中へ:
<div class="columns cols2">
<div class="column">
<ul class="foo">
<li>a</li>
<li>b</li>
</ul>
</div>
<div class="column collast">
<ul class="foo">
<li>c</li>
</ul>
</div>
</div>
これは次のように CSS とともに使用することを目的としています。
div.columns {
overflow: hidden;
_zoom: 1;
}
div.columns div.column {
float: left;
}
div.cols2 div.column {
width: 47.2%;
padding: 0 5% 0 0;
}
div.cols3 div.column {
width: 29.8%;
padding: 0 5% 0 0;
}
div.cols4 div.column {
width: 21.1%;
padding: 0 5% 0 0;
}
div.cols5 div.column {
width: 15.9%;
padding: 0 5% 0 0;
}
div.columns div.collast {
padding: 0;
}
ほとんどの人が忘れていることは、浮いているとき <li/>
項目をすべて同じ高さにしないと、列がおかしくなり始めます。
サーバー側言語を使用しているため、CF を使用してリストを 3 つの配列に分割することをお勧めします。その後、アウターを使用できます ul
3つの内側を包みます ul
そのようです:
<cfset thelist = "1,2,3,4,5,6,7,8,9,10,11,12,13">
<cfset container = []>
<cfset container[1] = []>
<cfset container[2] = []>
<cfset container[3] = []>
<cfloop list="#thelist#" index="i">
<cfif i mod 3 eq 0>
<cfset arrayappend(container[3], i)>
<cfelseif i mod 2 eq 0>
<cfset arrayappend(container[2], i)>
<cfelse>
<cfset arrayappend(container[1], i)>
</cfif>
</cfloop>
<style type="text/css">
ul li { float: left; }
ul li ul li { clear: left; }
</style>
<cfoutput>
<ul>
<cfloop from="1" to="3" index="a">
<li>
<ul>
<cfloop array="#container[a]#" index="i">
<li>#i#</li>
</cfloop>
</ul>
</li>
</cfloop>
</ul>
</cfoutput>
モジュロ演算を使用すると、リストを複数のリストにすばやく分割できます。 </ul><ul>
ループ中に。
<cfset numberOfColumns = 3 />
<cfset numberOfEntries = 34 />
<ul style="float:left;">
<cfloop from="1" to="#numberOfEntries#" index="i">
<li>#i#</li>
<cfif NOT i MOD ceiling(numberOfEntries / numberOfColumns)>
</ul>
<ul style="float:left;">
</cfif>
</cfloop>
</ul>
使用 ceiling()
の代わりに round()
リストの最後に余分な値がないこと、および最後の列が最短であることを確認するためです。
リストを複数のグループ化されたタグに出力するには、この方法でループできます。
<cfset list="1,2,3,4,5,6,7,8,9,10,11,12,13,14">
<cfset numberOfColumns = "3">
<cfoutput>
<cfloop from="1" to="#numberOfColumns#" index="col">
<ul>
<cfloop from="#col#" to="#listLen(list)#" index="i" step="#numberOfColumns#">
<li>#listGetAt(list,i)#</li>
</cfloop>
</ul>
</cfloop>
</cfoutput>
次のスタイルで列リストを使用できる別のソリューションを次に示します。
1. 4. 7. 10.
2. 5. 8. 11.
3. 6. 9. 12.
(ただし、これは純粋な JavaScript であり、フォールバックなしの jQuery が必要です)
以下には、配列プロトタイプを変更して、指定された配列を指定されたサイズのチャンクに分割する「chunk」と呼ばれる新しい関数を提供するコードが含まれています。次は、UL セレクター文字列と、列に含めることができる行数を指定するために使用される数値を受け取る「buildColumns」と呼ばれる関数です。(これは動作するJSFiddleです)
$(document).ready(function(){
Array.prototype.chunk = function(chunk_size){
var array = this,
new_array = [],
chunk_size = chunk_size,
i,
length;
for(i = 0, length = array.length; i < length; i += chunk_size){
new_array.push(array.slice(i, i + chunk_size));
}
return new_array;
}
function buildColumns(list, row_limit) {
var list_items = $(list).find('li').map(function(){return this;}).get(),
row_limit = row_limit,
columnized_list_items = list_items.chunk(row_limit);
$(columnized_list_items).each(function(i){
if (i != 0){
var item_width = $(this).outerWidth(),
item_height = $(this).outerHeight(),
top_margin = -((item_height * row_limit) + (parseInt($(this).css('margin-top')) * row_limit)),
left_margin = (item_width * i) + (parseInt($(this).css('margin-left')) * (i + 1));
$(this[0]).css('margin-top', top_margin);
$(this).css('margin-left', left_margin);
}
});
}
buildColumns('ul#some_list', 5);
});
フレックスボックスを使用すると、行方向と列方向の両方で項目を折り返すことができます。
主なアイデアは、 flex-direction
コンテナ上でどちらかに row
または column
.
注意:最近では ブラウザのサポート かなり良いです。
フィドル
(サンプルマークアップは以下から取得 この古い「リストアップ」記事)
ol {
display: flex;
flex-flow: column wrap; /* flex-direction: column */
height: 100px; /* need to specify height :-( */
}
ol ~ ol {
flex-flow: row wrap; /* flex-direction: row */
max-height: auto; /* override max-height of the column direction */
}
li {
width: 150px;
}
a {
display: inline-block;
padding-right: 35px;
}
<p>items in column direction</p>
<ol>
<li><a href="#">Aloe</a>
</li>
<li><a href="#">Bergamot</a>
</li>
<li><a href="#">Calendula</a>
</li>
<li><a href="#">Damiana</a>
</li>
<li><a href="#">Elderflower</a>
</li>
<li><a href="#">Feverfew</a>
</li>
<li><a href="#">Ginger</a>
</li>
<li><a href="#">Hops</a>
</li>
<li><a href="#">Iris</a>
</li>
<li><a href="#">Juniper</a>
</li>
<li><a href="#">Kava kava</a>
</li>
<li><a href="#">Lavender</a>
</li>
<li><a href="#">Marjoram</a>
</li>
<li><a href="#">Nutmeg</a>
</li>
<li><a href="#">Oregano</a>
</li>
<li><a href="#">Pennyroyal</a>
</li>
</ol>
<hr/>
<p>items in row direction</p>
<ol>
<li><a href="#">Aloe</a>
</li>
<li><a href="#">Bergamot</a>
</li>
<li><a href="#">Calendula</a>
</li>
<li><a href="#">Damiana</a>
</li>
<li><a href="#">Elderflower</a>
</li>
<li><a href="#">Feverfew</a>
</li>
<li><a href="#">Ginger</a>
</li>
<li><a href="#">Hops</a>
</li>
<li><a href="#">Iris</a>
</li>
<li><a href="#">Juniper</a>
</li>
<li><a href="#">Kava kava</a>
</li>
<li><a href="#">Lavender</a>
</li>
<li><a href="#">Marjoram</a>
</li>
<li><a href="#">Nutmeg</a>
</li>
<li><a href="#">Oregano</a>
</li>
<li><a href="#">Pennyroyal</a>
</li>
</ol>
私も同じ問題を抱えていて、「きれいな」ものが見つからなかったので、解決策を投稿しようと思いました。この例では、反転したものを使用しています while
使用できるようにループします splice
の代わりに slice
. 。現在の利点は、slice() がインデックスと合計を必要とするのに対し、splice() はインデックスと範囲のみを必要とすることです。後者はループ中は難しくなる傾向にあります。
欠点は、追加中にスタックを反転する必要があることです。
例:
列 = 4;リカウント = 35
スライス = [0, 9] の for ループ。[9、18];[18、27];[27、35]
スプライス = [27, 8] の場合は反転します。[18、9];[9、9];[0、9]
コード:
// @param (list): a jquery ul object
// @param (cols): amount of requested columns
function multiColumn (list, cols) {
var children = list.children(),
target = list.parent(),
liCount = children.length,
newUl = $("<ul />").addClass(list.prop("class")),
newItems,
avg = Math.floor(liCount / cols),
rest = liCount % cols,
take,
stack = [];
while (cols--) {
take = rest > cols ? (avg + 1) : avg;
liCount -= take;
newItems = children.splice(liCount, take);
stack.push(newUl.clone().append(newItems));
}
target.append(stack.reverse());
list.remove();
}
これを列単位で変換してみることができます。
CSS:
ul.col {
width:50%;
float:left;
}
div.clr {
clear:both;
}
HTML 部分:
<ul class="col">
<li>Number 1</li>
<li>Number 2</li>
<li>Number 19</li>
<li>Number 20</li>
</ul>
<ul class="col">
<li>Number 21</li>
<li>Number 22</li>
<li>Number 39</li>
<li>Number 40</li>
</ul>