6

If a previous sibling is set to float with a width of 100% and the following sibling set to display: flex, the latter overflow the parent container instead of wrap to a new line.

With any other display value but flex (or grid) it wraps, as it should, so how come it won't when set to flex

.float-left {
  float: left;
  width: 100%;
}

.display-flex {
  display: flex;
  background: yellow;
}


/* Demo css */

.container {
  max-width: 80%;
  margin: auto;
  background: white;
}
<div class="container">
  <div class="float-left">I'm floating left, with a width of 100%.</div>
  <div class="display-flex">'Floating left' takes up 100% of the space, but still i don't go onto a new line?</div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
Ubby
  • 119
  • 2
  • 1
    What are you trying to achieve? – Phantom Aug 29 '17 at 11:07
  • 1
    Hmm, interesting. If you make it `inline-flex` it will wrap though. I guess this might be a Flexbox bug you found, but since all browser has the same behavior, it can be by design. Let us know what you want to accomplish and we'll find you a workaround – Asons Aug 29 '17 at 11:13
  • Ubby, I edited your question so it is more clear this has nothing to do with `.display-flex` _not_ being a flex item, it is about it being a flex container. – Asons Aug 29 '17 at 14:36
  • 1
    @LGSon: Not a bug. See my answer. – BoltClock Aug 29 '17 at 18:54

2 Answers2

4

The reason a block box appears to wrap when its previous sibling is a float with 100% width is because it's not actually the box that's wrapping, it's its inline content that's wrapping.

The reason this doesn't happen with a flex container is because floats cannot intrude into flex formatting contexts. In fact, the same thing happens with block formatting contexts — if you apply overflow: auto or overflow: hidden to the following sibling without display: flex the following sibling will seem to disappear altogether. (This implies that the first paragraph is true only when the block box does not establish a block formatting context.)

Since your float is 100% width, the flex container's (auto) width is reduced to 0. Its inline descendants don't wrap underneath the float, because those inline descendants are participating in an inline formatting context that's within an anonymous flex item, which itself doesn't wrap since it's the only flex item in the flex container. This flex item is overflowing the flex container; however the flex container itself doesn't overflow the containing block since its used width is 0, allowing it to sit next to the float.

The reason the flex container will wrap if it is display: inline-flex instead of display: flex is because an inline-level flex container behaves just like any other inline-level content, wrapping around a float. In this case, it's the flex container itself that wraps — its inline content is still formatted as an anonymous flex item, because flex layout is identical regardless of whether the flex container itself is inline-level or block-level.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Can you please explain why, when i add `border: solid` to `display-flex` item, it act as expect? – Duannx Aug 30 '17 at 03:34
  • 2
    @Duannx: Adding a border causes the total width of the flex container to be greater than zero, causing it to shift underneath the float since there is no longer any room for it, as described in [section 9.5 of CSS2](https://www.w3.org/TR/CSS22/visuren.html#floats). – BoltClock Aug 30 '17 at 03:59
  • Nice. Thank you very much – Duannx Aug 30 '17 at 04:03
2

The problem is that the element .display-flex is not a flex item. It is a child element in a standard block container.

Therefore, the flex shorthand property, and its longhand component properties, which apply only to flex items, are having no effect.

However, the width property works on both flex items and containers.

More details here: What are the differences between flex-basis and width?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • I just tested it with various `display` values and it will wrap to any value but `flex` and `grid`. – Kostas Siabanis Aug 29 '17 at 13:47
  • Now we got a great explanation from Boltclock :) – Asons Aug 29 '17 at 19:06
  • Maybe you ought to delete (or correct) this since it doesn't actually answer the question? – Asons Aug 29 '17 at 20:19
  • @LGSon, I posted this answer in response to the original question, where the difference between `flex-basis` and `width` played a prominent role. You then altered the question based on your understanding of the OP's thinking process. But the OP has yet to respond to any of your comments or edits. – Michael Benjamin Aug 29 '17 at 20:26
  • You may be correct that my answer is no longer necessary. But I would like to wait for feedback from the OP before deleting it. – Michael Benjamin Aug 29 '17 at 20:27
  • If to assume the OP missed the fact that the `display: flex` were to be set on the `container` and thought the `.display-flex` was a flex item and should apply the given `flex: 0 0 100%;`, I of course invalidated your answer with my edit. Sorry for that, will be more careful next time, prior to such an edit, and hope I understood OP correct :) – Asons Aug 29 '17 at 20:40
  • 2
    @LGSon, I'm not meaning to imply that you were incorrect or that your edits are not valid. I just think the OP should be given a chance to review everything before we start deleting stuff. – Michael Benjamin Aug 29 '17 at 20:47
  • @BoltClock Thank you very much for notifying me, and the edit made it more clear to understand (for me :) – Asons Aug 30 '17 at 04:38