如何CSS列出两列项目列表?

时间:2009-06-10 08:27:02

标签: html css xslt

我需要根据以下规则显示两列项目列表:

  • 列的容器具有流体宽度
  • 两列的宽度必须相等
  • 动态呈现项目,至少会显示一个
  • 项目排序需要首先向下流动,然后向右流动
  • 项目需要在底部均匀排列,如果是奇数,则额外项目应显示在左栏中

以下是一个例子:

~ Item 1   | ~ Item 6
~ Item 2   | ~ Item 7
~ Item 3   | ~ Item 8
~ Item 4   | ~ Item 9
~ Item 5   |

HTML可以是任何东西,只要它解决了这个问题。我只能使用XSLT将HTML包装在服务器吐出的内容之外。我可以访问两个XSLT参数:一个告诉我当前的项目编号,另一个告诉我有多少项目。

我的CSS技能基本/中级,我不知道从哪里开始。关于这是否可以实现以及如何实现的任何想法?

更新

感谢您的回答。共识似乎是使用A List Apart文章或我更喜欢的表格,因为它更简单。该表的问题是服务器按排序顺序给我项目。使用表意味着要重新排序XSLT技巧,不是吗?

<tr>
    <td>Item 1</td>
    <td>Item 4</td>
</tr>
<tr>
    <td>Item 2</td>
    <td>Item 5</td>
</tr>
<tr>
    <td>Item 3</td>
    <td>&nbsp;</td>
</tr>

8 个答案:

答案 0 :(得分:7)

你只需要CSS,例如 ul {column-count:2; -webkit-column-count:2; -moz-column-count:2}

答案 1 :(得分:6)

有关alistapart的有用文章正是如此,请尝试一下。

编辑后更新:

由于您处于可以访问的所有项目数量和当前项目,我认为两列表可能是您最好的选择。

答案 2 :(得分:3)

我知道人们会忽略基于HTML表格的布局,但是到底是什么。他们工作。如果你是徒劳的,你可以自由地加倍努力,找到一种纯粹的基于CSS的方法。 : - )

所以这是一个XSLT解决方案。

<xml>
  <item id="1">Item 1</item>
  <item id="2">Item 2</item>
  <item id="3">Item 3</item>
  <item id="4">Item 4</item>
  <item id="5">Item 5</item>
  <item id="6">Item 6</item>
  <item id="7">Item 7</item>
  <item id="8">Item 8</item>
  <item id="9">Item 9</item>
</xml>

应用此XSL 1.0模板(列数甚至可配置):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html" indent="yes" omit-xml-declaration="yes" />

  <xsl:template match="/xml">
    <xsl:variable name="vCols"  select="2" />
    <xsl:variable name="vCount" select="count(item)" />
    <xsl:variable name="vRows"  select="ceiling($vCount div $vCols)" />
    <xsl:variable name="vIterC" select="item[position() &lt;= $vCols]" />
    <xsl:variable name="vIterR" select="item[position() &lt;= $vRows]" />
    <xsl:variable name="vSelf"  select="." />

    <table>
      <xsl:for-each select="$vIterR">
        <xsl:variable name="vRowIdx" select="position()" />
        <tr>
          <xsl:for-each select="$vIterC">
            <xsl:variable name="vOffset" select="$vRows * (position() - 1)" />
            <td>
              <xsl:value-of select="$vSelf/item[$vRowIdx + $vOffset]" />
            </td>
          </xsl:for-each>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>

</xsl:stylesheet>

收率:

<table>
  <tr>
    <td>Item 1</td>
    <td>Item 6</td>
  </tr>
  <tr>
    <td>Item 2</td>
    <td>Item 7</td>
  </tr>
  <tr>
    <td>Item 3</td>
    <td>Item 8</td>
  </tr>
  <tr>
    <td>Item 4</td>
    <td>Item 9</td>
  </tr>
  <tr>
    <td>Item 5</td>
    <td></td>
  </tr>
</table>

如果只有一个项目,它会产生:

<table>
  <tr>
    <td>Item 1</td>
  </tr>
</table>

因此在这种情况下没有两列。

在任何情况下,表格总是格式良好(例如没有锯齿状的行)。这个解决方案没有做的一件事就是对输出进行排序。输出将始终按文档顺序排列。您似乎正确地对项目进行了排序,因此这不应该是一个大问题。

答案 3 :(得分:3)

您可以尝试以下方式:

.option:nth-of-type(n+5) {
    position: relative;
    left: 14ex;
    top: -6em;
}

.option:nth-of-type(n+9) {
    color: red;
    left: 28ex;
    top: -12em;
}

...列中有四个项目,其中line-height1.5em,列宽为14ex

但是因为它使用相对定位,你可能不得不减小容器的大小。

另外,根据w3schools,这个属性在IE8或更低版本中不可用。

答案 4 :(得分:1)

CSS无法做到这一点。您需要在服务器上收集列表并将项目分配到两个表列中(您可以使用CSS使两列具有相同的宽度)。

注意:有多列布局的浏览器扩展,但它们不可移植。

[编辑]我知道article on alistapart但我无法看到我的解决方案的不同之处:建议的多列布局为每个项目提供了一个固定的位置(通过为每个项目提供唯一的CSS ID和然后以某种方式定位它)。这意味着您需要生成HTML并对服务器上的项进行排序,然后使用大量技巧来定位它们。

使用具有两列的表并在渲染过程中将项目放入其中会更加简单。

答案 5 :(得分:0)

你的一个标准是阅读列表,所以一个简单的解决方案是一个双列表(@Aaron Digulla),列表的前半部分在第一列,等等。你可以使用任何HTML,对吧?我们已经将这种方法用于我们的一些列表,因为我们不想在每次更改列表时编辑CSS(我们也不想记住编辑HTML中的类)。

ALA文章中的方法1将是第二个最简单的解决方案(从纯粹主义的角度来看更为理想)。由于您知道当前的项目编号以及有多少项目,因此您可以添加一些逻辑以按正确的顺序获取列表项目。

CSS可以轻松设置任一方法的样式。

答案 6 :(得分:0)

如果你可以使用小javascript(我不擅长)来划分列表,那么这应该有效:

<script type="text/javascript">
var i=0;
var n=4;
if (i==0)
  {
document.write("<div id='listFlow'><ul>");
}
for (i=1;i<=15;i++)
{
if (i==n)
  {
document.write("<li>The number is " + i + "</li>" +"</ul><ul>");
var n=n+4;
  continue;
  }
document.write("<li>The number is " + i + "</li>");
}
document.write("</ul></div>");
</script>

<style type="text/css">
#listFlow ul{
float:left;
width:200px;
margin:0 0 0 10px;
padding:0;
}

#listFlow ul li{
list-style-position:inside;
list-style-type:disc;
margin:0;
padding:0;
width:180px;
}
</style>

注意:请查看CSS而不是javascript。这只是为了说明列表如何按照描述流动。

答案 7 :(得分:0)

从我所看到的,与列表分开的问题是,如果将11个项目的列表拆分为2个列,我希望第6个项目位于第一个列表中。 alistapart我认为将第11项改为第二列。

我的解决方法是使用jQuery-Columns Plugin。例如,将带有.mylist类的ul拆分为2列,您将执行

$(document).ready( function () {
  $('.mylist').cols(5);
});

这是live example on jsfiddle