philipwalton / flexbugs

A community-curated list of flexbox issues and cross-browser workarounds for them.
MIT License
13.63k stars 495 forks source link

100% height doesn't work within a flex item in a flex-item child (Chrome / Safari) #197

Closed somombo closed 7 years ago

somombo commented 7 years ago

I am posting this issue here because I haven't been able to find a workaround.

In addition, this is a known issue in chrome and safari but appears to not have been listen on the flexbugs list (unless I'm mistaken). For more info, See https://bugs.webkit.org/show_bug.cgi?id=137730

Here is some code to reproduce the problem in Chrom and Safari (taken from http://jsfiddle.net/mLkp7L1j/2/)

<div class="flex">
    <div class="flex-item">
        <div class="element">
            The orange element should be as tall as the blue element
        </div>
    </div>
</div>
.flex {
    height: 100px;
    display: -webkit-flex;
    display: flex;
    -webkit-flex-flow: column;
    flex-flow: column;
}
.flex-item {
    background-color: steelblue;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto;
}
.element {
    height: 100%;
    background-color: orange;
}
philipwalton commented 7 years ago

Do you have a workaround? Flexbugs only lists bugs in the README with known workarounds.

mkurz commented 7 years ago

https://bugs.webkit.org/show_bug.cgi?id=137730 has been marked as fixed now.

Can you share a chrome bug url?

mkurz commented 7 years ago

Also it looks like the jsfiddle is buggy:

Note we do "fail" the jsfiddle but pass the mozilla test now. I think the jsfiddle is wrong, and that our behavior is correct according to the spec. I kind of think the spec is wrong here though. Anyway, we should match Chrome now.

(Taken from the webkit issue)

gsnedders commented 7 years ago

As @mkurz posted, the jsfiddle is wrong. Firefox and Edge break the spec in this case and are actually wrong as they don't implement the following:

If a flex item has a definite flex basis and the flex container has a definite main size, its post-flexing main size is treated as definite (even though it might technically rely on the sizes of indefinite siblings to resolve its flexed main size).

Vitally, the jsfiddle has a flex-basis of auto which isn't definite in this case (as height: auto hence it falls back to behaving like flex-basis: content which is always indefinite). If you change to flex: 1 1 0, it works fine cross-browser (in this admittedly relatively simple case).

somombo commented 7 years ago

@philipwalton, as @gsnedders has mentioned, it appears workaround seems to be to set basis to 0 I have tried this in opera, chrome. However, I dont have a machine with safari though. Perhaps someone can confirm that that works in safari?

ben-styling commented 7 years ago

As previously mentioned, I believe this is the intended behaviour. Changing the flex-basis to 0 will give you your desired outcome in chrome. However, this still does not work in Safari. (Tested in 10.0.3) http://jsfiddle.net/mLkp7L1j/125/

Are there any suggested workarounds for Safari?

mkurz commented 7 years ago

@GoldenRust Safari 10.1 was released yesterday. Can you update and try again?

ben-styling commented 7 years ago

@mkurz I'll try later tonight when I have access to a mac, right now I'm limited to what Browser Stack can provide.

Edit: I can confirm this still doesn't work as expected in Safari 10.1

gsnedders commented 7 years ago

@mkurz No, it doesn't.

mkurz commented 7 years ago

@gsnedders Which test page did you try?

gsnedders commented 7 years ago

@mkurz the one linked by @GoldenRust, which is right per spec and passes in Nightly; the one linked by @somombo in the original post equally fails, but that's expected to fail per spec and similarly does in Nightly.

mkurz commented 7 years ago

With Nightly you mean Safari technology preview? And you did test with Safari 10.1 (released yesterday)?

gsnedders commented 7 years ago

With Nightly I mean Nightly, though yes, it also passes in Technology Preview. And yes, I did test with Safari 10.1.

mkurz commented 7 years ago

@gsnedders Seems we have to wait another couple of months before this hits stable :cry: Thanks for testing!

jonas8 commented 7 years ago

I have this problem, the latest 10.1 safari doesn't fix this. My workaround is : make the flex-item element as flexbox, and remove height 100% from .element

ben-styling commented 7 years ago

@jonas8 I believe this works when the flex direction is set as column, but if it's set as row it doesn't.

jonas8 commented 7 years ago

@GoldenRust It works as well when set as row. flex-direction: row: http://jsfiddle.net/jonas8/ox2d2w4w/2/ flex-direction: column: http://jsfiddle.net/jonas8/w5jwxoL5/3/

ben-styling commented 7 years ago

@jonas8 So it does! I forgot to add the flex attribute to the .element.

Thank you!

philipwalton commented 7 years ago

I don't think there is a generalized workaround for this, and in the interest of not having too many opened issues lingering, I'm going to close this one. If someone discovers a workaround, please feel free to open a new issue.

dongepulango commented 7 years ago

Thanks @jonas8

dgobnto commented 6 years ago

Thank you @jonas8

everdimension commented 6 years ago

If anyone's interested, adding height: 0 to the flex item in the original example makes the child take the 100% height as expected in both chrome and safari: http://jsfiddle.net/qegwrLu6/

.flex-item {
  background-color: steelblue;
  -webkit-flex: 1 1 auto;
  flex: 1 1 auto;
  height: 0; /* <-- this helps */
}
AlexWayfer commented 6 years ago

height: 0 works as position: absolute: the next flex item collapse .flex-item with small .flex (display) size (instead of scroll appearing).

http://jsfiddle.net/qegwrLu6/12/

hk029 commented 6 years ago

change the flex: auto to flex: 1 will solve this problem. In fact, you can set flex-basis to any value except 'auto' , according to CSS2.1 :

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'. A percentage height on the root element is relative to the initial containing block.

AlexWayfer commented 6 years ago

change the flex: auto to flex: 1 will solve this problem.

1 makes the container height equal to item height in the issue-starter example. 0 (flex: 1 1 0;) resolves the problem.

trusktr commented 6 years ago

I wanted to note, that if the .flex-item has no defined height but has flex-grow with a value higher than all other flex-items so that it always grows (for example), then a percent height of 100% will not work on .element.

To make it work, you oddly define the .flex-item to have height: 0px, then flex-grow will override it so that the height is not actually 0, then a percentage height on .element will work!

This is obviously not intuitive at all.

Here's what I mean:

<div class="flex">
    <div class="flex-item">
        <div class="element">
            The orange element should be as tall as the blue element
        </div>
    </div>
</div>

then this does not work:

.flex {
    height: 100px;
    display: flex;
    flex-direction: column;
}
.flex-item {
    background-color: steelblue;
    flex-grow: 1;
}
.element {
    height: 100%;
    background-color: orange;
}

but if you change flex-item to this, then it works:

.flex-item {
    background-color: steelblue;
    flex-grow: 1;
    height: 0px; /* <--- right here! */
}

and now the .element can take the whole height.

Fiddle without height: 0px: https://jsfiddle.net/trusktr/q0cs94hy/2/

Fiddle with height: 0px: https://jsfiddle.net/trusktr/q0cs94hy/3/

This is definitely unintuitive and ugly behavior. There goes the web at it again!

darthrevan commented 5 years ago

@gsnedders thank you man saved my day!

wasimgit commented 5 years ago

.flex-item { background-color: steelblue; flex-grow: 1; height: 0px; / <--- right here! / }

ignatiusreza commented 5 years ago

it still doesn't work when .flex have a min-height instead of a height.. :sob:

coldKey1 commented 5 years ago

.flex-child-item { margin: auto }

lichristopher commented 5 years ago

@ignatiusreza are you still having problem with it? because Im having that problem too

ignatiusreza commented 5 years ago

@lichristopher we end up restructuring the dom to avoid this specific issue..

marcelombc commented 5 years ago

If you are using min-height just add height: 0 to the element with min-height and it should work. Fiddle: http://jsfiddle.net/km8ezqup/

OliverJAsh commented 5 years ago

The test case at the top of this issue can be reduced slightly further to http://jsfiddle.net/OliverJAsh2/rx59Ljbw/2/.

.flex {
    height: 100px;
    display: flex;
    flex-direction: column;
}
.flex-item {
    background-color: steelblue;
    flex-grow: 1;
}
.element {
    height: 100%;
    background-color: orange;
}

Testing on latest browsers today, this works in Firefox and Chrome but fails in Safari.

Specifying flex-basis: 0 or height: 0 on the flex item (as suggested originally in https://github.com/philipwalton/flexbugs/issues/197#issuecomment-283211783) seems to workaround the issue in Safari.

@gsnedders @mkurz Is this still considered a bug in Safari, or is Safari working according to spec? If Safari is working according to spec here, does this imply that other browsers (Firefox/Chrome) are actually the ones with a problem here (i.e. they shouldn't respect height: 100% unless the parent flex item has a 0 height/flex basis, like in Safari)?

Either way, I think we should document this browser discrepancy in flexbugs (outside of this issue).

gsnedders commented 5 years ago

@OliverJAsh The spec changed since I last quoted it in 2017, now saying:

If the flex container has a definite main size, a flex item’s post-flexing main size is treated as definite, even though it can rely on the indefinite sizes of any flex items in the same line.

So the bug is once again Safari's.

That said, this test for all this partly still fails in Edge(HTML) and Firefox because they always treat the flex item main size as definite even when the flex container has an indefinite main size.

OliverJAsh commented 5 years ago

@gsnedders Thanks for clarifying. In that case, do you know if there's a (new) bug filed with Safari, or do we need to open one?

gsnedders commented 5 years ago

Don't know off-hand.

OliverJAsh commented 5 years ago

I filed a bug here: https://bugs.webkit.org/show_bug.cgi?id=198375

alexandar-mitsev commented 4 years ago

@lichristopher we do have the same problem with min-height - https://jsfiddle.net/f1x9428q/5/ Works fine on Firefox, but brakes on Chrome. I could not locate a reported bug about it in Chrome. The workaround with height: 0 does work.

vincent-ly commented 4 years ago

height:0 hack doesn't work on Chrome for iOS.

strarsis commented 4 years ago

Try min-height: inherit; on the child element (works in recent Chrome)! 🚀

bendman commented 4 years ago

@strarsis Putting min-height: inherit on the flex item causes the flex item to be 100% the height of the flex container. This isn't always wanted; for example if it has siblings that also take up space.

Here is a more complete test case: https://jsfiddle.net/wLz0u27y/3/

yfxie commented 4 years ago

Add a flexbox again as a workaround.

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

.flex-item {
  flex: 1;
  display: flex;
  align-items: stretch; // To stretch the child height
}

.element-in-flex-item {
  // This item should be the same height to .flex-item
  // If you have margin: auto in the element, change it to margin: 0 auto;
}
Kuohao-wu commented 3 years ago

Add a flexbox again as a workaround.

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

.flex-item {
  flex: 1;
  display: flex;
  align-items: stretch; // To stretch the child height
}

.element-in-flex-item {
  // This item should be the same height to .flex-item
  // If you have margin: auto in the element, change it to margin: 0 auto;
}

it work! thank you very much!