将列表包装成列
我正在使用ColdFusion
填充包含HTML
列表(<ul>
's)的模板。
这些中的大多数都没有那么长,但是有一些长度却很可笑,实际上可以放在2-3列中。
有没有一种HTML,ColdFusion或者JavaScript(我有jQuery)可用的方法来轻松做到这一点?为了节省一些滚动,不值得使用过于复杂的笨重解决方案。
解决方案
回答
据我所知,没有纯粹的CSS / HTML方式可以实现这一目标。最好的选择是在预处理中进行此操作("如果列表长度> 150,则分为3列,否则,如果> 70,则应分为2列,否则为1")。
使用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">
回答
因此,我从A List Apart CSS Swag:Multi-Column Lists中挖了这篇文章。我最终使用了第一个解决方案,但这不是最好的解决方案,但是其他解决方案则需要使用无法动态生成的复杂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; }
我不确定Opera。
回答
要将列表输出到多个分组标签中,我们可以以这种方式循环。
<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>
回答
以下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)
两列,它变成:
<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; }
回答
我已经使用jQuery实现了它的跨平台和最少的代码。
选择UL,对其进行克隆,然后将其插入上一个UL之后。就像是:
$("ul#listname").clone().attr("id","listname2").after()
这将在上一个列表之后插入列表的副本。如果原始列表的样式为float:left,则它们应并排出现。
然后,我们可以从左侧列表中删除偶数项目,并从右侧列表中删除奇数项目。
$("ul#listname li:even").remove(); $("ul#listname2 li:odd").remove();
现在,我们具有从左到右的两列列表。
要执行更多列,我们将需要使用.slice(begin,end)和/或者:nth-child选择器。
也就是说,对于21个LI,我们可以使用.slice(8,14)在原始UL之后插入一个新的UL,然后选择原始UL并通过`ul:gt(8)删除所选的li。
试试jQuery上的Bibeault / Katz书,这是一个很好的资源。
回答
大多数人忘记的是,当浮动<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()
来确保列表末尾没有多余的值,并且最后一列最短。
回答
这是Thumbkin的示例的一个变体(使用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.
谢谢Thumbkin!