Подтвердить что ты не робот

Как отображать обертывание гибких элементов как пробел между последней левой строкой?

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

Однако начало каждого элемента должно быть выровнено с одним над ним, поэтому в ASCII-стиле оно будет выглядеть так (например, добавление 1):

    /----------------------------------\
    |                                  |
    | # One    # Two   # Three  # Four |
    | # Five   # Six                   |
    |                                  |
    \----------------------------------/

Другими словами:

  • Первый элемент каждой строки должен быть выровнен по левому краю
  • Последний элемент каждой строки (кроме последней строки) должен быть выровнен по правому краю.
  • Каждый элемент должен быть выровнен по левому краю над элементом над ним

Я пытаюсь использовать flexbox для этого без успеха.

Это - лучшее, что я до сих пор использовал, используя flex-wrap: wrap для контейнера и flex-grow: 1 для элементов.

Проблема в том, что последняя строка заполняется до края.

justify-content: flex-start; // this does nothing

Если я уберу flow-grow: 1, тогда элементы не будут распределены одинаково. Я также пробовал возиться с last-of-type по элементам, но этого также недостаточно.

Возможно ли это с помощью flexbox, или я не ошибаюсь?

Спасибо...

4b9b3361

Ответ 1

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

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

Как сохранить обернутые гибкие элементы той же ширины, что и элементы предыдущей строки?

http://fourkitchens.com/blog/article/responsive-multi-column-lists-flexbox

Ответ 2

Я знаю, что я немного опаздываю, но я искал решения для этого в прошлый час или около того, и я думаю, что я как-то понял это. Поместите пустой div в конец вашего контейнера и установите для него flex-grow: 1 и ничего больше. Также установите justify-content: space-between на контейнер и не используйте flex-grow для других элементов. Это всегда приведет к выравниванию последней строки, потому что этот div будет растягиваться по всему оставшемуся пространству.

Однако проблема заключается в том, что она ВСЕГДА делает последнюю линию выравниваемой влево - даже если это единственная строка, которая делает это решение непригодным для меня, но оно может быть полезно для тех, кто может ожидать более одной строки позиций.

Ответ 3

Если ширина ваших позиций исправлена, вы можете добавить несколько пустых div в конец списка элементов:

<div class="item">meaningful content</div>
<div class="item">meaningful content</div>
<div class="item">meaningful content</div>

<div class="empty-div"></div>
<div class="empty-div"></div>
<div class="empty-div"></div>

а затем:

.item, .empty-div{ width: 150px; } // make them the same width

Хорошо работает.

Ответ 4

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

Добавьте в контейнер столько пустых div сколько максимальное количество элементов в строке, присвойте им тот же класс, что и элементы строки, но удалите из них все поля или отступы (в основном все, что дает им высоту). Это приведет к тому, что строка будет вести себя так, как ожидалось, потому что после последнего элемента строки всегда будет достаточно невидимых "прокладок" для прокладки строки. Те, которые завернуты в следующую строку, не имеют высоты, поэтому они не должны влиять на остальную часть вашей страницы.

Пример здесь: https://jsfiddle.net/amknwjmj/

.products {
  display:         flex;
  flex-wrap:       wrap;
  justify-content: space-between;
}

.product {
    
  /* set top and bottom margin only, as left and right
     will be handled by space-between */
  margin: 0.25rem 0;

  /* account your desired margin two times and substract
     it from the base width of the row item */
  flex-basis: calc(25% - (0.25rem * 2));
}

.product.spacer {
      
  /* remove all properties increasing the element height 
     from the spacers to avoid them being visible */
  margin:  0;
  padding: 0;
  height:  initial;
}

/* start demo styles (purely eye-candy not required for this to work) */
* {
  box-sizing:  border-box;
  font-family: sans-serif;
}

.products {
  padding: .25rem .5rem;
  background: powderblue;
}

.product {
  height:      75px;
  line-height: 75px;
  padding:     .25rem;
  text-align:  center;
  background:  steelblue;
  color:       #fff;
}  
  
.product.spacer {
  background: none;

  /* of course, spacers should NOT have a border
     but they are helpful to illstrate what going on. */
  border: 1px dashed gray;
}
/* end demo styles */
<div class="products">
  <article id="product-1" class="product">P1</article>
  <article id="product-2" class="product">P2</article>
  <article id="product-3" class="product">P3</article>
  <article id="product-4" class="product">P4</article>

  <article id="product-5" class="product">P5</article>
  <div class="product spacer"></div>
  <div class="product spacer"></div>
  <div class="product spacer"></div>

  <div class="product spacer"></div>
</div>

Ответ 5

Итак, у вас есть контейнер и некоторые вещи внутри?

<div class="container">
  <span>msg1</span>
  <span>msg1</span>
  <span>msg1</span>
  <span>msg1</span>
  <span>msg1</span>
</div>

Вот как это работает, когда вы объявляете display: flex для своего контейнера, все его прямые дочерние элементы тоже будут гибкими, с некоторой конфигурацией по умолчанию (align-items:strech).

Я предполагаю, что у вас это уже есть, поэтому, возможно, вы можете попробовать использовать justify-content: space-between, который выровнят ваши элементы в строке, оставив их равномерными плюс flex-basis: 25% (чтобы удостовериться, что всегда будет 4 элемента в строке, измените de%, как вы хотите), который должен работать для всех ваших линий, кроме последнего. Для последнего вы можете использовать селектор css (например, last-child) и установить его свойство flex-grow: 0/flex-shrink:0 (решение одной из ваших проблем, если вы использовали flex: 1 1 25% вместо flex-basis), а также align-self: flex-start или что вам нравится

Ответ 6

Вы можете попробовать его с помощью фиксированного-псевдо-элемента:

.container {
 display:flex;
 justify-content:space-between;
}
.container:after {
  content: '';
  flex-grow: 0;
  width: 25%;
}
.container .element {
  width: 25%;
}

Ответ 7

Нет простого способа сделать это с помощью flexbox. Но если вы готовы пожертвовать IE, тогда вы можете сделать это с помощью grid css, добавьте это в контейнер:

display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));

И если вы хотите иметь некоторое пространство между элементами, тогда добавьте

grid-gap: 10px;

Ответ 8

Я смог достичь желаемого результата с комбинацией положительных и отрицательных полей.

Если каждый элемент в контейнере определяет границу для создания пробела между ними:

.container .element {
   flex: 1;
   margin: 0px 5px;
}

восстанавливать пиксели с краев каждой строки в контейнере с отрицательным запасом той же суммы:

.container {
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
   margin: 0px -5px;
}

Это должно привести к 10px между каждым элементом в строке с первой и последней из каждой строки на краю контейнера.