Как CSS список столбцов из двух столбцов?

Мне нужно отобразить список элементов из двух столбцов в соответствии со следующими правилами:

  • Контейнер для столбцов имеет ширину жидкости
  • Ширина обоих столбцов должна быть равной
  • Элементы динамически отображаются, и будет отображаться хотя бы один символ
  • Сначала нужно упорядочить порядок заказа товара по левому столбцу, а затем правый
  • Элементы должны выравниваться равномерно по низу или в случае нечетного числа, которое дополнительный элемент должен показывать в левом столбце

Вот пример:

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

HTML может быть любым, если он решает эту проблему. Я ограничусь использованием XSLT, чтобы обернуть HTML вокруг того, что вырывает сервер. У меня есть доступ к двум параметрам XSLT: один, который сообщает мне текущий номер элемента, и тот, который сообщает мне, сколько там элементов.

Мои навыки CSS являются базовыми/промежуточными, и я не знаю, с чего начать. Любые идеи о том, достижимо ли это и как это сделать?

Update:

Спасибо за ответы. Консенсус, похоже, либо использует 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>

Ответ 1

Там есть полезная статья о alistapart, попробуйте взглянуть туда.

Обновление после редактирования:

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

Ответ 2

Вам просто нужен CSS, например. ul {column-count: 2; -webkit-column-count: 2; -moz-column-count: 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>

В этой ситуации нет двух столбцов.

В любом случае таблица всегда будет хорошо сформирована (например, без зубчатых строк). Единственное, что это решение не делает, это сортировка вывода. Выход всегда будет в порядке документа. Кажется, вы правильно отсортировали элементы, поэтому это не должно быть большой проблемой.

Ответ 4

Вы можете попробовать что-то вроде:

.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-height - 1.5em, а ширина столбца будет 14ex.

Но поскольку это использует относительное позиционирование, вам, вероятно, придется уменьшить размер контейнера.

Кроме того, согласно w3schools, это свойство недоступно в IE8 или ниже.

Ответ 5

CSS не может этого сделать. Вам нужно собрать список на сервере и распределить элементы в двух столбцах таблицы (вы можете использовать CSS, чтобы сделать две колонки одинаковой ширины).

Примечание. Существуют расширения браузера для размещения нескольких столбцов, но они не переносимы.

[EDIT] Я знаю статью о файле alistapart, но я не вижу разницы в моем решении: предлагаемый мульти расположение столбца дает каждому элементу фиксированную позицию (путем предоставления каждому элементу уникального идентификатора CSS и последующего его позиционирования). Это означает, что вам нужно сгенерировать HTML и отсортировать элементы на сервере, а затем использовать множество трюков, чтобы разместить их.

Гораздо проще использовать таблицу с двумя столбцами и отбросить элементы в них во время рендеринга.

Ответ 6

Один из ваших критериев - чтение списка вниз, поэтому простым решением является таблица с двумя столбцами (@Aaron Digulla), первая половина вашего списка в первом столбце и т.д. Вы можете использовать любой HTML, правильно? Мы применили этот метод для некоторых наших списков, поскольку мы не хотели редактировать наш CSS каждый раз, когда список был изменен (и мы не хотели запоминать, чтобы редактировать классы в HTML).

Метод 1 в статье ALA будет вторым простейшим решением (и более идеальным с точки зрения пуриста). Поскольку вы знаете текущий номер позиции и количество элементов, вы можете добавить некоторую логику, чтобы получить элементы списка в правильном порядке.

CSS может легко стилизовать любой метод.

Ответ 7

Если вы можете разделить список, используя небольшой 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. Это просто, чтобы показать, как списки могут протекать, как описано.

Ответ 8

Проблема с a-list-apart, из того, что я вижу, заключается в том, что если вы разделите список из 11 элементов на 2 столбца, я бы хотел, чтобы 6-й элемент находился в первом списке. alistapart Я думаю, что вместо 11-го пункта во втором столбце.

Мое исправление заключалось в использовании jQuery-Columns Plugin. Например, чтобы разделить ul с классом .mylist на 2 столбца, вы сделали бы

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

Здесь живой пример на jsfiddle