9

I want to have a flex-box with a maximum width that wraps beyond that width, but that also fits the maximum size of any given "row" within the flexbox.

The problem I am facing now is that any element that stretches beyond the maximum width and then wraps causes the flexbox to still take up that maximum width.

Here is a link to a codepen demonstrating the issue:

https://codepen.io/heroes-coding/pen/rNaGYmo

And here is the top container's html / css:

body {
  background: black;
}

.holder {
  width: 650px;
  background: gray;
  margin-top: 50px;
}

.flexbox {
  display: flex;
  background: blue;
  max-width: 500px;
  width: fit-content;
  flex-wrap: wrap;
}

.item {
  width: 100px;
  height: 50px;
  background: red;
  border-bottom: 1px dotted white;
  border-top: 1px dotted white;
  border-right: 1px dotted white;
}

.item.wide {
  width: 200px;
}
<div class="holder">
  <div class="flexbox">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
</div>

I'd like to have the flexbox still wrap at 500px but shrink to fit the content after the wrapping occurs.

j08691
  • 204,283
  • 31
  • 260
  • 272
Jeremy Schutte
  • 352
  • 1
  • 3
  • 13
  • This isn't a duplicate of that other question. This question is about the flex container's intrinsic width when the flex container has multiple lines and max-width. That other question is about the contents of flex items wrapping and not about multiple lines or intrinsic widths or max-width. – dgrogan Dec 31 '19 at 21:03
  • It's not the question that matters. It's the answer. Notice what the duplicate notification says: *"This question already has answers here:"* – Michael Benjamin Jan 01 '20 at 18:07
  • @Michael_B, which answer in that question do you think applies to this question? I don't see that any do. – dgrogan Jan 01 '20 at 18:10
  • From your question: *"The problem I am facing now is that any element that stretches beyond the maximum width and then wraps causes the flexbox to still take up that maximum width."* Please refer to the first line in my answer. – Michael Benjamin Jan 01 '20 at 18:14
  • Further, this question is about how the used width of a flex container is calculated when its specified width is an intrinsic and how the specified max-width property (apparently!) influences that. Your answer does not address these. – dgrogan Jan 01 '20 at 18:54
  • This is a slight modification of your fiddle that demonstrates the different issue being raised here: https://jsfiddle.net/dgrogan/gbtaucd7/ . The only modification is I added the last two properties of the ul style block. – dgrogan Jan 01 '20 at 18:59
  • @dgrogan the first sentence in the duplicate answer is The answer : *In CSS, the parent container doesn't know when its children wrap. Hence, it continues scaling its size oblivious to what's going on inside.* --> note the **doesn't know**. If you understand this you understand all the cases including this question and your example. I hav also added another duplicate explaining the same – Temani Afif Jan 01 '20 at 19:15
  • @TemaniAfif That is not accurate for flex containers wrapping their items into lines; the flex container itself decides when its children wrap, as defined in w3.org/TR/css-flexbox-1/#algo-line-break Though, thanks for the linked question, it and linked questions have good analysis – dgrogan Jan 01 '20 at 19:42
  • 1
    @dgrogan the link you used confimrs what I am trying to say. in the step (4) we have "Determine the main size of the flex container " and then in the step (5) we have "Collect flex items into flex lines:" --> so we define the size of the container THEN we place the items (not the opposite and we don't get back to calculate the main size again). You can also read: *collect consecutive items one by one until the first time that the next collected item would not fit into the flex container’s inner main size* --> note the **would not fit**. – Temani Afif Jan 01 '20 at 19:51
  • @dgrogan That's why the parent container *doens't know* when its children wrap because it happens *after* calculating the main size not before – Temani Afif Jan 01 '20 at 19:52

1 Answers1

0

You can't achieve exactly what you're asking with CSS alone. What you can do it set the max number of items you want to show per row, and then calculate a max-width that you pass to your flexbox container:

:root{
   --item-width: 100px;
   --max-per-row: 4;
   --max-width: calc( var(--max-per-row) * ( var(--item-width) + 1px)  );
}

With this code you can set your container's width to whatever you want, say 500px, and then make sure the max width is n * a flexbox item's width (plus 1 for border), where n is the number of items you want per row. Just make sure the flexbox width is greater than the max-width.

:root{
   --item-width: 100px;
   --max-per-row: 4;
   --max-width: calc( var(--max-per-row) * ( var(--item-width) + 1px)  );
}

body {
  background: black;
}

.holder {
  width: 650px;
  background: gray;
  margin-top: 50px;
}

.flexbox {
  display: flex;
  background: blue;
  width: 500px;
  max-width: var(--max-width);
  flex-wrap: wrap;
}

.item {
  width: var(--item-width);
  height: 50px;
  background: red;
  border: 1px dotted white;
  border-left: none;
}
.item.wide {
  width: 200px;
}
<div class="holder">
  <div class="flexbox">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
</div>
symlink
  • 11,984
  • 7
  • 29
  • 50
  • I know the example case makes it seem like this is not the case, but in my actual usage the items don't have fixed widths. Otherwise it would be trivial to set the max width equal to the number of items per "row" times the items width, don't need a separate formula to do so – Jeremy Schutte Jan 01 '20 at 17:14