Я хочу показать элементы списка в виде 2 или более столбцов (динамическое выравнивание) - PullRequest
18 голосов
/ 11 ноября 2011

Я могу сделать список, используя float:left;, как это

enter image description here

Но я бы хотел показать это так (в виде 2 или более столбцов)

enter image description here

Как я могу это сделать?

@ sandeep дал хорошее решение. К сожалению, не работает в IE (нужно ie7 и выше).

любая помощь?

Ответы [ 9 ]

33 голосов
/ 11 ноября 2011

Для этого вы можете использовать свойство column-count:

div#multicolumn1 {
    -moz-column-count: 2;
    -moz-column-gap: 50%;
    -webkit-column-count: 2;
    -webkit-column-gap: 50%;
    column-count: 3;
    column-gap: 50%;
}

Отметьте это jsFiddle .

Примечание. Оно не работает вIE.

Для IE вы можете использовать этот JavaScript: CSS3 - демонстрация многостолбцовой разметки

4 голосов
/ 09 декабря 2011

Ниже приведен колонизатор, принимающий в качестве аргумента количество колонок.

Звоните: $ (elem) .columnize (3)

http://jsfiddle.net/Bdsj9/28/

Протестировано в IE6 из wine в Ubuntu 10.04: работает (выглядит лучше, если вы увеличите ширину таблицы стилей, которую я позаимствовал у @micha - спасибо, кстати)

(function($) {
    $.fn.decolumnize = function() {
        this.children().map(function(index, el) {
            var oldPos = null;
            var posClass = null;
            if($(el).attr("class") && (posClass = $(el).attr("class").match(/orig\-readorder\-[0-9]+/))) {
                oldPos = parseInt(posClass[0].replace("orig-readorder-", ""));
                $(el).removeClass(posClass[0]);
            }
            return {
                elm: el,
                pos: oldPos ? oldPos : index
            }
        }).sort(function(a,b) {
            return a.pos > b.pos ? 1 : -1;
        }).map(function(index, ob) {
            return ob.elm;
        }).appendTo(this);
        return this.children().css("float", "left").css("clear", "none");
    };
    $.fn.columnize = function(numcols) {
        var numItems = this.children().length;
        var divisor = Math.ceil(numItems / numcols);
        var indexOfFinal = null;       
        this.decolumnize();


        var resorted = this.children().map(function(index, el) {
            return {
                position: (index % divisor) + (index / numItems),
                elm: el,
                isFinal: index == numItems - 1,
                origPos: index
            };
        }).sort(function(a, b) {
            return a.position > b.position ? 1 : -1;
        });
        return resorted.map(function(index, ob) {
            if (indexOfFinal) {
/** TODO: fix redundancy  **/
                if ((index - indexOfFinal - 1) % (numcols - 1) == 0) {
                    if ($.browser.msie && resorted[index - 1]) $(resorted[index - 1].elm).css("float", "none");
                    $(ob.elm).css("clear", "left");
                }
            } else {
/** TODO: fix redundancy **/
                if (index % numcols == 0) {
                    if ($.browser.msie && resorted[index - 1]) $(resorted[index - 1].elm).css("float", "none");
                    $(ob.elm).css("clear", "left");
                }
            }

            if (ob.isFinal) indexOfFinal = index;
            $(ob.elm).addClass("orig-readorder-" + ob.origPos);
            return ob.elm;
        }).appendTo(this);
    };
})(jQuery);

Сначала он вычисляет сортировщик, потому что при простом оформлении это не сработает. Чтобы рассчитать сортировщик, вам нужно знать количество столбцов заранее. Это вы можете использовать в качестве делителя, чтобы ввести 'clear: left'.

Кроме того, используя количество элементов списка и количество столбцов, необходимо оценить количество строк. Это можно использовать в качестве делителя для сортировки элементов на основе остатка между их индексом и количеством строк.

Для гранулирования сортировки также учитывается исходный индекс ...

После того, как последний оригинальный элемент был размещен, количество столбцов должно быть уменьшено на 1. Поэтому я сохраняю isFinal-boolean. Я уверен, что это можно сделать более элегантно с помощью некоторых интеллектуальных вычислений.

Затем введите 'clear: left' в нужном месте и сохраните исходную позицию в классе, чтобы вы могли прибегнуть к более поздней стадии (например, при динамическом добавлении или удалении элемента списка)

Best!

4 голосов
/ 09 декабря 2011

Пока ваши элементы списка имеют фиксированную ширину, как в ваших примерах, не могли бы вы просто сделать что-то подобное в этой скрипке? http://jsfiddle.net/swNYE/1/

И там, где ваш список выплеван, просто примените «левый» класс к первой половине, а «правый» класс ко второй. Если вы динамически добавляете контент через Javascript, то вам просто нужно проходить через li каждый раз, когда что-то добавляется, и применять новый правильный класс.

HTML:

<ul>
    <li class="left">1</li>
    <li class="left">2</li>
    <li class="left">3</li>
    <li class="left">4</li>
    <li class="right">5</li>
    <li class="right">6</li>
    <li class="right">7</li>
    <li class="right">8</li>
</ul>

CSS:

li {
    width: 100px;
}
li.left {
    float: left;
    clear: left;
}
li.right {
    margin-left: 100px;
}
4 голосов
/ 08 декабря 2011

Работает просто отлично, кросс-браузер, JS не требуется.Вы просто ограничиваете ширину своих столбцов.

<style>
    ul.col {width:60px;float:left;margin:0 5px 0 0;padding:0;}
    ul.col li {width:50px;background:#999;list-style-type:none;margin:0 0 5px 0;padding:5px;}
</style>

<ul class="col">
    <li>1(li)</li>
    <li>2(li)</li>
    <li>3(li)</li>
    <li>4(li)</li>
    <li>5(li)</li>
</ul>
<ul class="col">
    <li>6(li)</li>
    <li>7(li)</li>
    <li>8(li)</li>
    <li>9(li)</li>
    <li>10(li)</li>
</ul>

Если вы застряли с ними всеми в одном UL при загрузке страницы, вы можете разделить их с помощью jQuery, чтобы получить те же результаты:

<script>
$(function(){ //on document ready
    var perCol = 5;
    var $ul = $('ul.col');
    var rows = Math.ceil($ul.find('li').length/perCol);
    for(var i=1;i<=rows;i++){
        $ul.after('<ul class="col"></ul>');
    }
    for(var i=1;i<=rows;i++){
        $ul.find('li:lt('+(perCol)+')').appendTo('ul.col:eq('+(i)+')');
    }
    $ul.remove();
});
</script>
3 голосов
/ 11 ноября 2011

Я нашел способ сделать это в IE тоже. (используя clear)

HTML:

<div class="left child">1</div>
<div class="child">5</div>
<div class="left child">2</div>
<div class="child">6</div>
<div class="left child">3</div>
<div class="child">7</div>
<div class="left child">4</div>
<div class="child">8</div>

CSS:

.child {
    height:20px;
    width: 20px;
    text-align: center;
    border: 1px solid #CCC;
    background-color: #EEE;
    color: #000;
    padding: 5px;
    float: left;
    margin: 5px;
}
.left {
    clear: left;
}

См. http://jsfiddle.net/pMbtk/31/

2 голосов
/ 07 декабря 2011

СМОТРИ МОЙ НОВЫЙ ОТВЕТ - НАМНОГО ЛУЧШЕ, ЧЕМ ЭТО

Если вы имеете дело с элементами фиксированной ширины, то это чистое решение CSS , которое работает в IE7 +.Пример: http://jsfiddle.net/VVMnq/33/.. Это потребует от вас некоторых сведений о html, с которым вы работаете (где должен начинаться новый столбец).Вот столбец 2 длиннее, просто чтобы посмотреть, как он обрабатывает его: http://jsfiddle.net/VVMnq/42/

HTML

<ul class="TwoColumn">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li class="column2">6</li>
    <li class="column2">7</li>
    <li class="column2">8</li>
    <li class="column2">9</li>
    <li class="column2">10</li>
</ul>

CSS

.TwoColumn {
    width: 20px;
    padding-left: 22px; /* width plus borders of li's */
}

.TwoColumn li {
    display: block;
    width: 100%;
    padding: 0;
    margin: 0 -22px 0 -22px; /* width of ul plus borders on li's */
    float: left;
    clear: left;
    border: 1px solid blue;
}

.TwoColumn .column2 {
    float: none; /* this could be set to float: left and it seemed to work also */
    clear: none;
    margin: 0 -11px 0 0; /* this should be half of margins for column 1 li's */
}
1 голос
/ 11 декабря 2011

НОВЫЙ ОТВЕТ , который полностью отличается от первого.Предполагается, что высота всегда 5 (это из комментариев к решению jblasco, сделанного под углом, это требование).Решением здесь является pure css (хотя, если количество элементов неизвестно, то некоторый javascript потребуется для «подсчета» и установки класса с именем first, чтобы указать, какой элемент находится в первой строке).

Решение работает в IE7 + , а будет содержать любое количество столбцов .

См. http://jsfiddle.net/VVMnq/107/.

HTML

<ul class="MultiColumn">
    <li class="first">1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li class="first">6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
</ul>

CSS

.MultiColumn {
    overflow: auto;
    background-color: yellow;
    padding:0 10px 10px 0;
    float: left;
}

.MultiColumn li {
    display: block;
    width: 20px;
    height: 20px;
    padding: 0;
    margin: 10px 0px 10px 10px ;
    background-color: cyan;
    float: left;
}

.MultiColumn li.first {
    top: 0px;
}

.MultiColumn li.first + li  {
    margin: 40px 0 0 -20px;
}

.MultiColumn li.first + li + li {
    margin: 70px 0 0 -20px;
}

.MultiColumn li.first + li + li + li {
    margin: 100px 0 0 -20px;
}

.MultiColumn li.first + li + li + li + li {
    margin: 130px 0 0 -20px;
}
1 голос
/ 08 декабря 2011

CSS:

ul.parent li {
  float: left;
}

Использование jquery:

$('.parent>li:odd').css("clear", "both");

<ul class="parent">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
</ul>

Пожалуйста, посмотрите на http://api.jquery.com/even-selector/ и http://api.jquery.com/odd-selector/

0 голосов
/ 05 апреля 2012

http://jsfiddle.net/rlemon/Y5ZvA/3/ Вы можете попробовать это .. Я еще не проверял это, т.е.

ul {
    width:60px; height: 60px;
}

ul li{
    float:left;
    width:20px;
    list-style:none;
}
ul, ul li {
    -moz-transform: rotate(-90deg) scaleX(-1);
    -o-transform: rotate(-90deg) scaleX(-1);
    -webkit-transform: rotate(-90deg) scaleX(-1);
    -ms-transform: rotate(-90deg) scaleX(-1);
    transform: rotate(-90deg) scaleX(-1);
   /* IE8+ - must be on one line, unfortunately */ 
   -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=-3.061616997868383e-16, M12=1, M21=1, M22=3.061616997868383e-16, SizingMethod='auto expand')";

   /* IE6 and 7 */ 
   filter: progid:DXImageTransform.Microsoft.Matrix(
            M11=-3.061616997868383e-16,
            M12=1,
            M21=1,
            M22=3.061616997868383e-16,
            SizingMethod='auto expand');
}
​
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...