5

A simplified plunkr to show the problem: https://plnkr.co/edit/mHTHLEumQ04tInFVAz3z?p=preview

If you resize the right viewport until the two containers no longer fit on the same row, right one moves to a new line.

However the parent inline-flex container width does not change, throwing the top "header" element off - the "button" in "header" should be right aligned with the last item in the container below.

The two (or more) items have fixed width but no space between them. Those are the only elements with fixed width or height.

How can I force the flex container width to fit/shrink when items wrap to a new row (without using js, pure HTML/CSS)?

.main-flex {
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-flex-direction: column;
  flex-direction: column;
}

.flex-container {
  flex-grow: 1;
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-flex-direction: row;
  flex-direction: row;
  flex-wrap: wrap;
}
<div style="margin-top: 100px;" class="main-flex">
  <div>
    <span>header</span>
    <span style="float:right">button</span>
  </div>
  <div class="flex-container">
    <div style="height: 400px; width:250px; border: 1px solid black;"></div>
    <div style="height: 400px; width:250px; border: 1px solid black;"></div>
  </div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Agony
  • 845
  • 2
  • 9
  • 23
  • it's very confusing what you are asking. But my guess is that the html is not logical from the beginning . if you want your button to be on the right side of the last box , you should put them together . – Mihai T May 11 '17 at 09:12
  • @MihaiT If you look at the example - it is only aligned to the last box IF it is on the same line - if the last box is moved to the new line due to wrap - the "button" should not move with it. It is a global header for ALL the boxes. – Agony May 11 '17 at 11:29

1 Answers1

2

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.

Put another way, the browser renders the container on the initial cascade. It doesn't reflow the document when a child wraps.

That's why the container doesn't shrink-wrap the narrower layout. It just continues on as if nothing wrapped, as evidenced by the reserved space on the right.

More details here: Make container shrink-to-fit child elements as they wrap


But you don't need the container to shrink for your layout to work. It can be built with a few adjustments to your HTML and CSS.

.main-flex {
  display: inline-flex;
  flex-wrap: wrap;
}

.flex-container {
  display: flex;
  flex-direction: column;
}

.flex-container>div {
  height: 400px;
  width: 250px;
  border: 1px solid black;
}

.flex-container:nth-child(2)>span {
  align-self: flex-end;
}
<div class="main-flex">
  <div class="flex-container">
    <span>header</span>
    <div></div>
  </div>
  <div class="flex-container">
    <span>button</span>
    <div></div>
  </div>
</div>

revised demo

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Unfortunately it does not behave as intended on wrap. The "button" text moves to a new line with the 2nd container - it should stay on top (in the header). – Agony May 12 '17 at 08:02
  • Oh, I misinterpreted that part of the question. Then a media query may help you. Have a look at the link reference for more details. – Michael Benjamin May 12 '17 at 11:53
  • Media queries unfortunately only apply on fixed widths, not counting different screen sizes. Also they are based off window size - not counting for other responsive elements like sidebars etc. – Agony May 15 '17 at 11:24