Flex container overflow if previous sibling is floated - html

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>

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.

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?

Related

flex-basis affecting size of sibling item in nested flex container

I have a nested flex layout.
Here is my codepen link https://codepen.io/mendoncafiles/pen/oNoGbPa
There is a flex container, inside which I have list items. Each list item is a flex, with I tag and SPAN tag as flex items. The I tag has flex-basis of 30px.
The text in last list-item is wrapped to next line.
The text is displayed in single line with two options:
remove display: flex from wrapping DIV
Change flex-basis: 30px to width: 30px to I tag.
Expected:
Issue:
It looks like the problem is that the browser is establishing the size of the container before factoring in the full length of the spans.
You can disable flex-shrink or use white-space: nowrap on the spans. But that will cause an overflow.
Consider setting a minimum width on the top level flex container or the ul.

How to wrap text around objects (like floating does) in flexbox?

Let's say I have a display: inline container with some text children, and some inline-block children:
If I give the container the following CSS... (and change inline-block to inline-flex)
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
... then it treats the text element as an entire element of its own and wraps the whole thing, rather than breaking it up.
Is there a "flexbox" way of achieving this, or do I really have to fall back to display inline?
Once you create a flex container (display: flex or display: inline-flex), all in-flow children become flex items.
Flex items are, by definition, "blockified", which means they are block-level boxes (source).
Text elements represent inline-level boxes (source).
Therefore, you cannot make flex items wrap in the same way as text (or floats).

Flex container with overflow-y element

I have flex .wrapper with flex-direction: column.
Then I have 2 flex elements. One of them is .g-main, which also is flex container with element .content inside it.
The troubles with height of .g-main. Why it doesn't stretches automamicly? There is a lot of content inside it.

Why is width handled differently in flexbox?

I've been playing around with display:flex lately as I see it becoming more trending. In a quick test, using flex and non-flex CSS approaches, I realized, my widths, and margins are always respected when using flex. Is this a good approach considering that I will most likely need a gutter between elements anyway? Moreover, where is the margin between spans coming from? This is what I mean:
HTML
<div class="container">
<div class="box">
<span class="inner-box">This gives me a 30px X 60px</span>
<span class="inner-box">This gives me a 30px X 60px</span>
<span class="inner-box">This gives me a 30px X 60px</span>
</div>
<div class="box2">
<span class="inner-box">This gives me a width larger than the specified 30px</span>
<span class="inner-box">This gives me a width larger than the specified 30px</span>
<span class="inner-box">This gives me a width larger than the specified 30px</span>
</div>
</div>
CSS
.box{
background: orange;
display:flex;
flex-direction:row-reverse;
padding:0 10px;
}
.box2{
background: green;
text-align:right;
padding:0 10px;
}
.inner-box{
width:30px;
background:#fff;
margin:0 0px;
}
Notice the widths at runtime
DEMO
You are using <span> elements. They are inline by default. The width is automatically ignored for inline elements.
In the first div section (.box), however, the span's inline display value is overridden by the parent's display: flex, which establishes a flex formatting context. Hence, all children become flex items, which respect width and height.
Flex Items
A flex item establishes a new formatting context for its contents. The
type of this formatting context is determined by its display value,
as usual. However, flex items themselves are flex-level boxes, not
block-level boxes: they participate in their container’s flex
formatting context, not in a block formatting context.
source: https://drafts.csswg.org/css-flexbox-1/#flex-items
In the second div section (.box2), the span elements remain display: inline, as they are not removed from the block-formatting context, and any width and height assignments are ignored.
Try display: inline-block: http://codepen.io/anon/pen/yeggOy
References:
Setting the width of inline elements
How to set width of a inline element?
Does height and width not apply to span?
Inline Elements With Width
Your question is a little unclear but if, as MrLister commented:
If display:flex honors width, where display:inline doesn't? If so, the answer is yes,.
This is because, per the spec,
Flex items paint exactly the same as inline blocks
and so are affected by width statements.

Using 'height: 100%' and 'align-items: stretch' in flexbox [duplicate]

This question already has answers here:
Chrome / Safari not filling 100% height of flex parent
(5 answers)
Closed 5 years ago.
I have a flexbox with a direct child that is declared with align-items: stretch.
Inside this flexbox's direct child, I would like to have a div container that also uses its parent's full height (by setting height: 100%).
However, the div container won't stretch to 100% height of its parent, unless I also set height: 100% on the flexbox's direct child.
Is it kind of bug? Must I set the flexbox's direct child with align-items: stretch AND height: 100% to achieve what I want? It seem redundant to me.
Here is an example:
html,
body {
margin: 0;
height: 100%;
}
.flexbox {
display: flex;
flex-direction: row;
height: 100%;
background-color: green;
}
.flexbox-child {
// height: 100%; uncommenting this will get it to work
align-items: stretch;
background-color: blue;
}
.flexbox-grand-child {
height: 100%;
background-color: red;
}
<div class="flexbox">
<div class="flexbox-child">
<div class="flexbox-grand-child">
I want to be stretched till the bottom
</div>
</div>
</div>
http://plnkr.co/edit/FACkwsC2y65NcbOaceur?p=preview
Thanks!
It's a complicated case.
Your .flexbox-child is only a flex item, but not a flex container. Therefore, align-items: stretch, which only applies to flex containers, is ignored.
Then, .flexbox-grand-child has a percentage height, which behaves like this:
The percentage is calculated with respect to the height of the
generated box's containing block. If the height of the containing
block is not specified explicitly (i.e., it depends on content
height), and this element is not absolutely positioned, the value
computes to 'auto'.
The containing block is the flex item (.flexbox-child), which has no explicit height, and its height seems to depend on the content.
However, this dependency is only due to the new min-height: auto. But before taking min-height into account, the height of the flex item will be (due to the initial align-self: stretch) the height of the container, which is specified explicitly, ignoring the content.
Then, Firefox considers that the height of .flexbox-child does not depend on its contents, so height percentages in its children should work. And then your code works.
However, Chrome doesn't think so.
I'm not sure which one does it right. It doesn't help that height is only defined in the old CSS2.1 and in CSS basic box model, which is an inconsistent draft.
To be safe, better set the height of .flexbox-child explicitly. Or make it a flex container.
When you create a flex container only the child elements become flex items. Descendants beyond the children do not become flex items and flex properties don't apply to them.
Simply apply display: flex to the flex item, which converts it into a flex container, as well. Then default flex properties like align-items: stretch will apply to the children (now flex items).
You wrote:
I would like to have a div container that also uses its parent's full
height...
You don't need to use height: 100% or add align-items: stretch (it's a default rule). Simply add display: flex to .flexbox-child, and .flexbox-grand-child will expand the full available height.
Modified demo: http://plnkr.co/edit/n0Wt3x3CUr1ZfBD2RrGo?p=preview
re: height: 100% possible bug
With regard to the need to specify height: 100% on child elements, I don't see any bug here. Everything seems to conform to the spec. Here's a complete explanation: Working with the CSS height property and percentage values