Сетка 3 колонки (сверху вниз) с использованием сетки CSS - PullRequest
0 голосов
/ 05 июня 2018

Хорошо, вот ситуация, скажем, у меня есть список с неизвестным количеством элементов, это может быть 10 или 100, и я хочу выложить их в 3 столбца, идущих сверху вниз, а не слева направо.

Прямо сейчас я могу добиться этого, используя columns: 3; и column-gap: 10px; Это все нормально и все.

Мой вопрос заключается в том, как достичь тех же результатов, используя display: grid;, не зная количества элементов.?

Я знаю, что вы можете добиться этого с помощью CSS Grid, если у вас есть фиксированное количество элементов, но возможно ли это с динамическими элементами?без использования JS, конечно.

ul {
  list-style: none;
  columns: 3;
  column-gap: 10px;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
  <li>11</li>
  <li>12</li>
  <li>13</li>
  <li>14</li>
  <li>15</li>
  <li>16</li>
  <li>17</li>
  <li>18</li>
  <li>19</li>
  <li>20</li>
  <li>21</li>
  <li>22</li>
</ul>

Ответы [ 4 ]

0 голосов
/ 05 июня 2018

У меня есть список с неизвестным количеством элементов, это может быть 10 или 100

Как вы уже заметили, Многостолбцовый макет CSS создаетжелаемый макет с чистым CSS - без необходимости заранее знать количество элементов в контейнере.

Это не относится к сеткам CSS - вам нужно знать заранее количество элементов в сетке вЧтобы рассчитать необходимое количество строк - это довольно большое ограничение.

Поэтому я бы предложил вам придерживаться многостолбцовой раскладки для вашей раскладки.


Предполагая, что вышеупомянутое ограничение в порядке - тогда вы можете создать макет с помощью css следующим образом:

(Примечание: @Ander уже ответил на это, но для этого стоит небольшое объяснение)

1) В контейнере сетки измените свойство grid-auto-flow на column - Это размещает элементы сетки вертикально, а не горизонтально (по умолчанию).

2) Когда вы знаете количество элементов, вы можете рассчитать количество строк, необходимое для создания сбалансированной сетки, следующим образом:

#rows =  ceil( #items / #columns )

Таким образом, для 22 элементов - # row =ceil (22/3) = 8

ul {
   display: grid;
   grid-auto-flow: column; /* 1 */
   grid-template-rows: repeat(8, 1fr);  /* 2 */
}

Мы можем немного улучшить это решение с помощью SASS - чтобы получить более общее решение, которое вычисляет количество строк.(SASS имеет функцию ceil)

ul {
  list-style: none;
  padding: 0;
  display:grid;
  $num-items: 22;
  $num-cols: 3;
  $num-rows: ceil($num-items / $num-cols);
  grid-template-columns: repeat($num-cols, 1fr);
  grid-template-rows: repeat($num-rows, 1fr);
  grid-auto-flow: column;
  border: 5px solid gold;
}

Codepen Demo


FWIW: Вот альтернативное решение, которое использует селекторы nth-child без необходимостиизмените свойство grid-auto-flow.К сожалению, оно имеет то же ограничение, что # элементы должны быть известны заранее.

li:nth-child(-n + 24) {
  grid-column: 3;
}

li:nth-child(-n + 16) {
  grid-column: 2;
}

li:nth-child(-n + 8) {
  grid-column: 1;
}

SASS Codepen

0 голосов
/ 05 июня 2018

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

ul {
   display: grid;
   grid-auto-flow: column;
   grid-template-rows: repeat(8, 1fr);
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
  <li>11</li>
  <li>12</li>
  <li>13</li>
  <li>14</li>
  <li>15</li>
  <li>16</li>
  <li>17</li>
  <li>18</li>
  <li>19</li>
  <li>20</li>
  <li>21</li>
  <li>22</li>
</ul>

Но количество строк должно быть определено ранее.

0 голосов
/ 05 июня 2018

Теоретически вы можете добиться этого с помощью CSS Grid, используя «Количество запросов» на основе :nth-* селекторов, например:

ul {
  list-style: none;
  display: grid;
  grid-auto-flow: row dense;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
}

/* by default, items go in first column */
li { grid-column: 1; }

/* if there are 1 to 3 items, the 2nd one goes to 2nd column and the 3rd one goes to 3rd column */
li:first-child:nth-last-child(n + 1):nth-last-child(-n + 3) ~ li:nth-child(n + 2):nth-child(-n + 2) { grid-column: 2; }
li:first-child:nth-last-child(n + 1):nth-last-child(-n + 3) ~ li:nth-child(n + 3) { grid-column: 3; }

/* ... */

/* if there are 19 to 21 items, items 8-14 to 2nd column and items 15+ to 3rd one */
li:first-child:nth-last-child(n + 19):nth-last-child(-n + 21) ~ li:nth-child(n + 8):nth-child(-n + 14) { grid-column: 2; }
li:first-child:nth-last-child(n + 19):nth-last-child(-n + 21) ~ li:nth-child(n + 15) { grid-column: 3; }

/* if there are 22 to 24 items, items 9-16 to 2nd column and items 17+ to 3rd one */
li:first-child:nth-last-child(n + 22):nth-last-child(-n + 24) ~ li:nth-child(n + 9):nth-child(-n + 16) { grid-column: 2; }
li:first-child:nth-last-child(n + 22):nth-last-child(-n + 24) ~ li:nth-child(n + 17) { grid-column: 3; }

/* if there are 25 to 27 items, items 10-18 to 2nd column and items 19+ to 3rd one */
li:first-child:nth-last-child(n + 25):nth-last-child(-n + 27) ~ li:nth-child(n + 10):nth-child(-n + 18) { grid-column: 2; }
li:first-child:nth-last-child(n + 25):nth-last-child(-n + 27) ~ li:nth-child(n + 19) { grid-column: 3; }

/* and so on */
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
  <li>11</li>
  <li>12</li>
  <li>13</li>
  <li>14</li>
  <li>15</li>
  <li>16</li>
  <li>17</li>
  <li>18</li>
  <li>19</li>
  <li>20</li>
  <li>21</li>
  <li>22</li>
</ul>

Однако этот подход не практичен.На мой взгляд, многостолбцовый макет CSS - лучшее решение, чем CSS Grid.

0 голосов
/ 05 июня 2018

Я использовал немного JavaScript здесь. Где lst - это идентификатор UL.Я использовал переменные CSS, чтобы передать значение элементов в UL и в конечном итоге вычислить необходимые столбцы согласно требованию.Единственным недостатком является то, что нам нужно проверить, является ли общее количество элементов нечетным или четным.

<script>
 var list = document.getElementById("lst").childElementCount;
document.getElementById("lst").style.setProperty('--x',list/2);
</script>

<style>
    ul {
          list-style:none;
          display: grid;
          grid-auto-flow:column;
          grid-template-rows:repeat(var(--x),1fr);
         }
</style>
...