Zawijanie list do kolumn

Używam ColdFusion do wypełnienia szablonu zawierającego HTML Listy (<ul>).

Większość z nich nie jest tak długa, ale kilka ma śmiesznie długie długości i naprawdę może wytrzymać 2-3 kolumny.

Czy istnieje HTML, ColdFusion a może JavaScript (mam jQuery ' dostępny) sposób, aby to łatwo zrobić? Nie warto zbyt skomplikowanych rozwiązań o dużej wadze, aby zapisać przewijanie.

Author: Alive to Die, 2008-08-07

13 answers

Więc wykopałem ten artykuł z listy Apart CSS Swag: Multi-Column Lists . Skończyło się na użyciu pierwszego rozwiązania, to nie jest najlepsze, ale inne wymagają albo za pomocą skomplikowanego HTML, który nie może być generowany dynamicznie, lub tworzenie wielu niestandardowych klas, które można zrobić, ale wymagałoby mnóstwo in-line stylizacji i ewentualnie ogromną stronę.

Inne rozwiązania są jednak nadal mile widziane.

 23
Author: alexp206,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-09 06:00:06

Jeśli Obsługa Safari i Firefoksa jest wystarczająco dobra, istnieje rozwiązanie CSS:

ul {
  -webkit-column-count: 3;
     -moz-column-count: 3;
          column-count: 3;
  -webkit-column-gap: 2em;
     -moz-column-gap: 2em;
          column-gap: 2em;
}
Nie jestem pewien co do Opery.
 15
Author: doekman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-30 09:39:35

Nie ma czystego CSS / HTML sposób, aby to osiągnąć, o ile wiem. Najlepiej byłoby zrobić to w obróbce wstępnej (if list length > 150, split into 3 columns, else if > 70, split into 2 columns, else 1).

Inną opcją, przy użyciu JavaScript (nie znam biblioteki jQuery) byłoby iterację list, prawdopodobnie w oparciu o to, że są one określoną klasą, policzyć liczbę dzieci, a jeśli jest wystarczająco wysoka liczba, dynamicznie utworzyć nową listę po pierwszej, przenosząc pewną liczbę elementów listy do nowej listy. Jeśli chodzi o implementację kolumn, prawdopodobnie można je przenieść w lewo, a następnie element, który miał styl clear: left lub 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">
 9
Author: Chris Marasti-Georg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-05 20:06:40

Zrobiłem to z jQuery - jest wieloplatformowy i minimum kodu.

Wybierz UL, Sklonuj go i Wstaw po poprzednim UL. Coś w stylu:

$("ul#listname").clone().attr("id","listname2").after()

Spowoduje to wstawienie kopii listy po poprzedniej. Jeśli oryginalna lista jest stylizowana na float: left, powinna pojawić się obok siebie.

Następnie możesz usunąć parzyste elementy z listy lewej i nieparzyste z listy prawej.

$("ul#listname li:even").remove();
$("ul#listname2 li:odd").remove();

Teraz masz od lewej do prawej dwa lista kolumn.

Aby zrobić więcej kolumn, użyj .slice(begin,end) i/lub selektora :nth-child. ie, dla 21 LIs możesz .slice(8,14) utworzyć nowy UL wstawiony po oryginalnym UL, następnie wybrać oryginalny UL i usunąć wybrane li za pomocą ul :gt(8).

Wypróbuj książkę Bibeault / Katz na jQuery to świetny zasób.

 5
Author: ScottyDont,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 14:45:56

Oto odmiana Thumbkin ' s example (using 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.
Dzięki Thumbkin!
 4
Author: Community,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:31:55

Poniższy kod JavaScript działa tylko w Spidermonkey i Rhino i działa na węzłach E4X--tzn. jest to przydatne tylko dla JavaScript po stronie serwera, ale może dać komuś punkt wyjścia do wykonania wersji jQuery. (Było to bardzo przydatne dla mnie po stronie serwera, ale nie potrzebowałem go na kliencie wystarczająco mocno, aby go zbudować.)

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;
}

Nazywacie to jak columns(listNode,2) dla dwóch kolumn, a ono się odwraca:

<ul class="foo">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>

Do:

<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>

Jest przeznaczony do użycia z CSS tak:

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;
}
 4
Author: Linus Caldwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-01 01:54:36

Rzeczą, o której większość ludzi zapomina, jest to, że gdy przedmioty unoszą się <li/>, wszystkie przedmioty muszą być tej samej wysokości, albo kolumny zaczynają się bić.

Ponieważ używasz języka po stronie serwera, moją rekomendacją byłoby użycie CF do podzielenia listy na 3 tablice. Następnie możesz użyć zewnętrznego ul, aby owinąć 3 wewnętrzne ul w następujący sposób:

<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>
 4
Author: Leigh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-28 12:42:01

Używając operacji modulo, możesz szybko podzielić listę na wiele list, wstawiając </ul><ul> podczas pętli.

<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>

Użyj ceiling() zamiast round(), aby upewnić się, że nie masz dodatkowych wartości na końcu listy i że ostatnia kolumna jest najkrótsza.

 3
Author: jonah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-21 05:56:31

Aby wyświetlić listę na wiele grupowych tagów, możesz zapętlić ją w ten sposób.

<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>
 2
Author: Dan Roberts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 15:51:01

Oto inne rozwiązanie, które pozwala na tworzenie list kolumnowych w następującym stylu:

1.      4.      7.       10.
2.      5.      8.       11.
3.      6.      9.       12.
Nie jest to jednak żaden problem, ponieważ nie jest on w pełni funkcjonalny.]}

Poniższy kod zawiera pewien kod, który modyfikuje prototyp tablicy, aby dać nową funkcję o nazwie 'chunk', która rozbija dowolną tablicę na kawałki o danym rozmiarze. Następna jest funkcja o nazwie 'buildColumns', która pobiera ciąg selektora UL i liczbę używaną do wyznaczenia, ile wierszy może zawierać Twoje kolumny. (Oto działa 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);
});
 2
Author: bradleygriffith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-29 22:26:12

Flexbox może być używany do owijania elementów zarówno w kierunku wiersza, jak i kolumny.

Główną ideą jest ustawienie flex-direction na kontenerze na row lub column.

Uwaga: obecnie obsługa przeglądarki jest całkiem dobra.

FIDDLE

(przykładowe znaczniki pobrane z tego starego artykułu "lista osobno" )

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>
 2
Author: Danield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-30 11:09:29

Ponieważ miałem ten sam problem i nie mogłem znaleźć niczego "czystego", pomyślałem, że opublikowałem swoje rozwiązanie. W tym przykładzie używam odwróconej pętli while, więc mogę użyć splice zamiast slice. Zaletą jest to, że splice() potrzebuje tylko indeksu i zakresu, w którym slice () potrzebuje indeksu i sumy. Ten ostatni zwykle staje się trudny podczas zapętlania.

Wadą jest to, że muszę odwrócić stos podczas dodawania.

Przykład:

Cols = 4; liCount = 35

Dla pętla z plasterkiem = [0, 9]; [9, 18]; [18, 27]; [27, 35]

Odwrócony podczas splotu = [27, 8]; [18, 9]; [9, 9]; [0, 9]

Kod:

// @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();
}
 1
Author: Tim Vermaelen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-01 20:26:31

Możesz spróbować przekonwertować w kolumnach.

CSS:

ul.col {
    width:50%;
    float:left;
}

div.clr {
    clear:both;
}

Część 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>

 1
Author: Ajay Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-27 12:29:12