如何在语义上将单个列表分成多个列?

时间:2013-08-15 20:11:23

标签: jquery html css jquery-ui html-lists

我们网站用于将单个列表分成多列的当前方法是使用多个ul s:

<ul>
  <li>one</li>
  <li>two</li>
</ul>
<ul>
  <li>three</li>
  <li>four</li>
</ul>

这对我来说似乎并不理想,因为在语义上,它不是两个列表,而是一个。我已经看到很多不适合多列列表的解决方案。我正在寻找一个解决方案:

  1. 使用以下标记结构

    <ul>
      <li>one</li>
      <li>two</li>
      <li>three</li>
      <li>four</li>
    </ul>
    
  2. 这样组织:

    one    three
    two    four
    

    不是这个:

    one    two
    three  four
    
  3. 如果列表长度发生变化,或者项目包含多行,则无需修改即可使用。

  4. 使用有效的语义HTML。
  5. 适用于IE8。
  6. 理想的解决方案仅限CSS,但我愿意使用jQuery UI或轻量级Javascript。

    (PS,here's my CSS attempt,有明显的问题。)

    编辑:此问题特定于语义列表。另一个所谓的“重复”问题是关于<div>元素,这是一个不同的球赛,因为允许额外的标记。 <ul><li>之间不允许其他标记。这个问题主要关注语义,这意味着强调使用HTML尽可能详细地指出内容的含义。

5 个答案:

答案 0 :(得分:5)

您可以将列用于支持它的浏览器

DEMO http://jsfiddle.net/kevinPHPkevin/eaewX/33/

以下是完整浏览器支持的jQuery示例

DEMO http://jsfiddle.net/kevinPHPkevin/MKL4g/131/

var postsArr = new Array(),
    $postsList = $('ul.posts');

//Create array of all posts in lists
$postsList.find('li').each(function(){
    postsArr.push($(this).html());
})

//Split the array at this point. The original array is altered.
var firstList = postsArr.splice(0, Math.round(postsArr.length / 2)),
    secondList = postsArr,
    ListHTML = '';

function createHTML(list){
    ListHTML = '';
    for (var i = 0; i < list.length; i++) {
        ListHTML += '<li>' + list[i] + '</li>'
    };
}

//Generate HTML for first list
createHTML(firstList);
$postsList.html(ListHTML);

//Generate HTML for second list
createHTML(secondList);
//Create new list after original one
$postsList.after('<ul class="posts"></ul>').next().html(ListHTML);

答案 1 :(得分:3)

执行此操作的“正确”方法是使用CSS3列:

但那只会让你进入IE10。

我建议去那条路线然后使用IE shims和javascript o处理IE9和IE8。我忘记了,但是现代化可能会提供帮助你的垫片。

答案 2 :(得分:2)

CSS Columns是最佳解决方案,但对旧版浏览器不起作用。您可以使用nth-child做一些接近的事情,但是您不会得到拆分列表(您还需要在旧浏览器中使用polyfill)。最简单的解决方案可能是一个javascript - 它将拆分列表,但也保持代码清洁。这是一个将列表转换为任意数量列的函数。

http://jsfiddle.net/UrH69/

<强> SCRIPT

$.fn.extend({
    list2Columns: function(numCols) {
        var listItems = $(this).find('li'); /* get the list data */
        var listHeader = $(this);
        var numListItems = listItems.length;
        var numItemsPerCol = Math.ceil(numListItems / numCols); /* divide by the number of columns requires */
        var currentColNum = 1, currentItemNumber = 1, returnHtml = '', i = 0;

        /* append the columns */
        for (i=1;i<=numCols;i++) {
            $(this).parent().append('<ul class="column list-column-' + i + '"></ul>');
        }

        /* append the items to the columns */
        $.each(listItems, function (i, v)
        {    
            if (currentItemNumber <= numItemsPerCol){
                currentItemNumber ++;
            } else {
                currentItemNumber = 1;
                currentColNum ++;
            }
            $('.list-column-'+currentColNum).append(v);
        });
        $(this).remove();
    }
});

<强> USAGE

$('ul').list2Columns(2); // Change this number to change num of columns

<强> HTML

<ul>
  <li>one</li>
  <li>two</li>
  <li>three</li>
  <li>four</li>
  <li>five</li>
  <li>six</li>
</ul>

<强> CSS

.column { float:left; }

答案 3 :(得分:2)

很抱歉回答我自己的问题,但我认为我只有一个CSS解决方案。

Here it is on jsFiddle

基本上,我使用通用兄弟选择器(此符号:~,也可以使用in IE7!)来突出显示断点之后的所有元素,并将它们上下移动。只要你设置一个行高,似乎可以跨浏览器工作到IE7。

HTML:

<ul>
  <li>one</li>
  <li>two</li>
  <li class="newline">three</li>
  <li>four</li>
</ul>

CSS:

.newrow,
.newrow ~ li {
    margin-left: 120px;
    margin-top: -100px;
    margin-bottom: 100px;
}

我错过了这里明显的一切吗?

答案 4 :(得分:0)

您可以使用css column-count,因为此演示仅适用于chrome,但您可以使其跨浏览器

http://jsfiddle.net/UuwKC/

ul {-webkit-column-count:2}