8

我们网站目前用来将单个列表分成多列的方法是使用多个uls:

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

理想的解决方案只是 CSS,但我愿意使用 jQuery UI 或轻量级 Javascript。

(PS,这是我的 CSS 尝试,有明显的问题。)

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

4

5 回答 5

6

您可以为支持它的浏览器使用列

演示http://jsfiddle.net/kevinPHPkevin/eaewX/33/

这是一个完整的浏览器支持的 jQuery 示例

演示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);
于 2013-08-15T20:19:37.597 回答
3

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

但这只会让你进入 IE10。

我建议走那条路,然后使用 IE shims 和 javascript o 处理 IE9 和 IE8。我忘记了,但是modernizr 可能会提供一个垫片来帮助你。

于 2013-08-15T20:19:54.397 回答
3

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

这是在 jsFiddle 上

基本上,我使用通用的同级选择器(这个符号:~,也适用于 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;
}

我在这里遗漏了什么明显的东西吗?

于 2013-08-15T21:05:24.433 回答
2

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

http://jsfiddle.net/UrH69/

脚本

$.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();
    }
});

用法

$('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; }
于 2013-08-15T20:18:13.107 回答
1

你可以使用 css column-count 因为这个演示只在 chrome 中工作,但你可以让它跨浏览器

http://jsfiddle.net/UuwKC/

ul {-webkit-column-count:2}
于 2013-08-15T20:23:21.570 回答