Нежелательное переполнение столбцов CSS - PullRequest
0 голосов
/ 19 января 2019

Я хотел бы добиться чего-то вроде этого: Desired result

Но в настоящее время я получаю только это:

Actual result

Объяснение (спасибо Андрею Георгиу):

Я хочу отображать элементы в неопределенном количестве встроенных столбцов, правило «не более 2 пунктов в 1 столбце». 3-й пункт создает второй столбец, 5-й создает 3-й, 7-й создает 4-е столбцы и так далее. Каждый столбец или весь список должен вести себя как встроенный блок.

Подведем итог:

  • Цель состоит в том, чтобы в каждом столбце было два элемента списка.
  • Весь список должен быть в середине абзаца - невозможно вставить новые строки до или после.
  • Количество предметов в списке неизвестно.

Вот мой код: https://jsfiddle.net/2uf951km/6/

div {
  font-size: 30px;
  padding: 30px;
}

ul {
  display: inline-block;
  column-width: 35px;
  height: 35px;
  padding: 0;
  list-style: none;
  font-size: 10px;
  vertical-align: middle;
  /* 
    		Setting margin fixes the issue, 
    		but the with of the list is not
    		known.
    	*/
  /* margin-right: 170px; */
}

li {
  background: #9eff80;
  padding: 2px;
  opacity: 0.7;
}
<div>
  I'd like to have a list with several columns
  <ul>
    <li>A list</li>
    <li>like this</li>
    <li>with unknown</li>
    <li>number and items</li>
    <li>or columns.</li>
  </ul>
  in the middle of other text.
</div>

Как изменить мой CSS / HTML, чтобы список <ul> не покрывал текст?

Ответы [ 4 ]

0 голосов
/ 20 января 2019

Обновленный ответ для достижения ваших целей с использованием CSS Grid inline-grid для создания встроенной сетки уровня:

grid-template-rows настроен на повторение максимум двух строк с 1fr в каждой.

grid-template-columns установлено для повторения auto необходимого количества столбцов с шириной 35px.

grid-auto-flow установлен на column, чтобы иметь алгоритм автоматического размещения сетки для заполнения каждого столбца по очереди, добавляя новые столбцы по мере необходимости, сохраняя при этом максимум две строки.

grid-column-gap использовался для добавления отступов между столбцами для отображения тех же результатов, что и для предоставленных изображений.

div {
  font-size: 30px;
  padding: 30px;
}

ul {
  display: inline-grid;
  grid-template-rows: repeat(2, 1fr);
  grid-template-columns: repeat(auto, 35px);
  grid-auto-flow: column;
  grid-column-gap: 10px;
  align-items: center;
  list-style: none;
  font-size: 10px;
  padding: 0;
  margin: 0;
  vertical-align: middle;
}

li {
  background: #9eff80;
  padding: 2px;
  opacity: 0.7;
}
<div>
  I'd like to have a list with several columns
  <ul>
    <li>A list</li>
    <li>like this</li>
    <li>with unknown</li>
    <li>number and items</li>
    <li>or columns.</li>
  </ul>
  in the middle of other text.
</div>

Надеюсь, это решит вашу проблему!


Если ваша цель состоит в том, чтобы максимально 3 счетчика columns, как показано на предоставленных изображениях, я считаю, что свойство, которое вам нужно изменить:

column-width: 35px до columns: auto 3, если вы хотите, чтобы column-width каждого столбца было установлено на auto.

или

column-width: 35px до columns: 35px 3, если вы хотите указать column-width для каждого столбца.

Это объяснение того, что делает свойство columns:

CSS-свойство columns устанавливает ширину столбца и количество столбцов элемента. - MDN - столбцы css

Ниже приведен код, который я использовал для достижения того же результата, что и изображение, которое вы предоставили.

div {
  font-size: 30px;
  padding: 30px;
}

ul {
  display: inline-block;
  columns: auto 3;
  padding: 0;
  list-style: none;
  font-size: 10px;
  vertical-align: middle;
}

li {
  background: #9eff80;
  padding: 2px;
  opacity: 0.7;
}
<div>
  I'd like to have a list with several columns
  <ul>
    <li>A list</li>
    <li>like this</li>
    <li>with unknown</li>
    <li>number and items</li>
    <li>or columns.</li>
  </ul>
  in the middle of other text.
</div>

Надеюсь, это поможет!

0 голосов
/ 19 января 2019

Если вы не против, чтобы каждый <li> находился в отдельной колонке, я думаю, что это может сработать:

ul {
  display: inline;
  ...
}

li {
  display: inline-block;
  ...
}
0 голосов
/ 20 января 2019

Первоначальный ответ (прежде чем я понял, о чем вы спрашиваете):

В зависимости от того, как вы хотите <li> с, вы можете использовать columns ...

div {
  font-size: 30px;
  padding: 30px;
}

ul {
  display: inline-block;
  column-width: 35px;
  padding: 0;
  list-style: none;
  font-size: 10px;
  columns: 2 0px;
}

li {
  background: #9eff80;
  margin: 1px;
  padding: 2px;
  opacity: 0.7;
  width: 100%;
  break-inside: avoid;
}
<div>
  I'd like to have a list with several columns
  <ul>
    <li>A list</li>
    <li>like this</li>
    <li>with unknown</li>
    <li>number and items</li>
    <li>or columns.</li>
  </ul>
  in the middle of other text.
</div>

... или display:inline-flex.Вам нужно установить max-width для детей, установить flex-wrap: wrap для родителя и указать желаемое vertical-align для родителя:

div {
  font-size: 30px;
  padding: 30px;
}

ul {
  display: inline-flex;
  padding: 0;
  list-style: none;
  font-size: 10px;
  flex-wrap: wrap;
  line-height: 5em;
  vertical-align: middle; 
     /* see also -webkit-baseline-middle
                 text-bottom
                 text-top */
}

li {
  line-height: 1em;
  flex: 0 1 auto;
  margin: 1px;
  width: calc(50% - 2px); /*deduct margin*/
  background: #9eff80;
  padding: 2px;
  opacity: 0.7;
  box-sizing: border-box;
}
<div>
  I'd like to have a list with several columns
  <ul>
    <li>A list</li>
    <li>like this</li>
    <li>with unknown</li>
    <li>number and items</li>
    <li>or columns.</li>
  </ul>
  in the middle of other text.
</div>

Вероятно, наиболее важной частью всего этого является удаление height: 35px; из ul.Почему вы все равно жестко закодировали, если «Число элементов в списке неизвестно» ?


Правильный ответ (как этого можно достичь):

Похоже, вы хотите, чтобы ваши элементы отображались в виде неопределенной серии встроенных блоков, каждый из которых содержит 2 элемента или меньше.Вам все еще нужно определить, что должно произойти, когда содержимое ваших 2 элементов превысит желаемую высоту 35px.

Вот как вы можете добиться этого, используя ванильный JavaScript.Если возможно, вы должны сделать это на стороне сервера, хотя:

let uls = document.querySelectorAll('ul');
for(let i = 0; i < uls.length; i++) {
  let count = uls[i].children.length;
  if (count && count > 2) {
    for (j = 0; j < count/2; j++) {
      let parent = uls[i].parentElement,
          newUl = document.createElement('ul');
      for (k = 0; k < 2; k++) {
        li = uls[i].querySelector(':first-child');
        if (li) {
          newUl.appendChild(li);
          parent.insertBefore(newUl, uls[i]);
        }        
      }
    }
  }
}
div {
  font-size: 30px;
  padding: 30px;
}

ul {
  display: inline-block;
  padding: 0;
  list-style: none;
  font-size: 10px;
  vertical-align: middle;
  min-height: 35px;
}

li {
  background: #9eff80;
  padding: 2px;
  margin: 1px;
  opacity: 0.7;
}
<div>
  I'd like to have a list with several columns
  <ul>
    <li>A list</li>
    <li>like this</li>
    <li>with unknown</li>
    <li>number and items</li>
    <li>or columns.</li>
    <li>A list</li>
    <li>like this</li>
    <li>with unknown</li>
    <li>number and items</li>
    <li>or columns.</li>
    <li>A list</li>
  </ul>
  in the middle of other text.   I'd like to have a list with several columns
  <ul>
    <li>A list</li>
    <li>like this</li>
    <li>with unknown</li>
    <li>number and items</li>
    <li>or columns.</li>
    <li>A list</li>
    <li>like this</li>
    <li>with unknown</li>
    <li>number and items</li>
    <li>or columns.</li>
    <li>A list</li>
  </ul>
  in the middle of other text.
</div>

Это один из случаев, когда jQuery будет намного короче:

$('ul').each(function() {
  while($('li', this).length > 2) {
    let newUl = $('<ul/>'), i = 0;
    while(i < 2) {
      $('li', this).eq(0).appendTo(newUl); 
      i++;
    }
    newUl.insertBefore($(this));
  }
})
0 голосов
/ 19 января 2019

Есть несколько исправлений, либо добавьте display: block к ul, как это

 ul {
    display: block;
    column-width: 35px;
    height: 35px;

    padding: 0;
    list-style: none;
    font-size: 10px;

    vertical-align: middle;

    /* 
        Setting margin fixes the issue, 
        but the with of the list is not
        known.
    */
    /* margin-right: 170px; */
}

, либо измените margin-right на% или vw вместо px, как это

  ul {
    display: inline-block;
    column-width: 35px;
    height: 35px;

    padding: 0;
    list-style: none;
    font-size: 10px;

    vertical-align: middle;

    /* 
        Setting margin fixes the issue, 
        but the with of the list is not
        known.
    */
    margin-right: 30%;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...