Rendering problems using flexbox in Firefox and Chrome 48 [duplicate] - html

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 7 years ago.
On chrome 47 (correct behavior):
On chrome 47, that div with .scroll is scrolling correctly, taking height 100% using flex.
On firefox (wrong behavior):
While on firefox, that div with .scroll is using the content height and not scrolling properly.
What is the cross-browser solution to this problem?
http://jsfiddle.net/d4nkevee/
for (var i = 0; i < 100; i++)
$(".scroll").append("Dynamic content<br>");
body,
html {
margin: 0;
padding: 0;
}
.container {
box-sizing: border-box;
position: absolute;
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}
.content {
background: yellow;
flex: 1;
display: flex;
flex-direction: column;
}
.scroll {
flex: 1 1 auto;
overflow: scroll;
}
<div class="container">
<div class="bar">Small</div>
<div class="content">
<div>Static content</div>
<div class="scroll"></div>
<div>Static content</div>
</div>
<div class="footer">Small</div>
</div>
Question updated to distinguish between Chrome 47 and Chrome 48.

The flexbox specification was updated making the default minimum size of flex items equal to the size of the content: min-width: auto / min-height: auto.
You can override this setting with min-width: 0 / min-height: 0:
.content {
background: yellow;
flex: 1;
display: flex;
flex-direction: column;
min-height: 0; /* NEW */
min-width: 0; /* NEW */
}
http://jsfiddle.net/d4nkevee/1/
Bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=1043520
Here are some details from the spec:
4.5. Implied Minimum Size of Flex
Items
To provide a more reasonable default minimum size for flex items, this
specification introduces a new auto value as the initial value of
the min-width and min-height properties defined in CSS 2.1. (read more)
UPDATE
It appears that Chrome has updated their rendering behavior. Chrome 48 now emulates Firefox in terms of minimum flex sizing.
Based on reports in the following links, the solution above should work in Chrome 48, as well.
Possible Chrome 48 flexbox bug causing layout issues. #6841
Issue 580196: Nested 'flex-direction:column' elements don't shrink properly

Related

Flex items overlapping item in IE11

I have two divs:
top div contains a long text that takes up several lines
lower div has min-height and flex-grow: 1
When I reducing the window to the scroll appeared, then in chrome everything is displayed correctly. But in IE11 top div is reduced to one line, and its text is on top of the bottom div.
I can fix it only with set some width for content of top div (it work with fixed width, or calc width, but not work with percentage width)
How can I fix it without setting width or with percentage width (width:100%)?
body,
html {
height: 99%;
padding: 0;
margin: 0;
}
.flexcontainer {
width: 25%;
display: flex;
flex-direction: column;
height: 100%;
border: 1px solid lime;
}
.allspace {
flex-grow: 1;
min-height: 300px;
background-color: yellow;
}
.longtext {
background-color: red;
}
.textcontainer {
border: 1px solid magenta;
/*IE work correctly only when specified width. by example: width:calc(25vw - 2px);*/
}
<div class="flexcontainer">
<div class="longtext">
section 1 with long name section 1 with long name section 1 with long name
</div>
<div class="allspace">
all space
</div>
</div>
jsfiddle: https://jsfiddle.net/tkuu28gs/14/
Chrome:
IE11:
IE11 is full of flex bugs and inconsistencies with other browsers.
In this case, the source of the problem is flex-shrink.
IE11 is rendering flex items oddly after applying flex-shrink: 1 (a default setting), which causes the lower item to overlap its sibling above. This problem doesn't occur in other major browsers.
The solution is to disable flex-shrink. It fixes the problem in IE11 without changing anything in other browsers.
Add this to your code:
.longtext {
flex-shrink: 0;
}
revised fiddle
You may also want to look into:
setting min-width: auto on flex items, as IE11 has a different minimum size default than newer browsers. See the "Browser Rendering Notes" section in my answer here: Why don't flex items shrink past content size?
setting the container to width: 100%, as IE11 may not do this automatically to block-level flex containers. Text in a flex container doesn't wrap in IE11
The use of flex-shrink: 0; mentioned in the accepted answer works to prevent overlapping. However, I'm using like flex: 0 1 15% as I intend to allow shrinking and this renders nicely in other browsers like MS Edge, Chrome, and Firefox, but not in IE 11.
To apply no shrinking (flex-shrink: 0) only for IE 11, I used the following instead as the -ms- is vendor-specific:
-ms-flex-negative: 0 !important;
problem solved:
body, html {
height: 100vh;
padding:0;
margin:0;
}
.flexcontainer{
width:25%;
display: flex;
height: 100%;
flex-flow: column;
border: 1px solid lime;
}
.allspace{
flex-grow:1;
background-color: yellow;
}
.longtext{
background-color: red;
//EDIT
flex-grow: 0;
min-height: 100px;
}
.textcontainer{
border:1px solid magenta;
/*IE work correctly only when specified width. by example: width:calc(25vw - 2px);*/
}
EDIT (screenshots on IE11)

Why is Firefox not honoring flexed div's height, but Chrome is?

This is best illustrated with a simple example.
I have a container with display: flex and flex-direction: column, with a single div inside with height: 300px and flex: 1.
Chrome renders the nested div at 300px tall, but Firefox renders it as a single line. Is this just a nuance between the implementation of flexbox between the two browsers, or is this bad code somehow? If a nuance, what's the best way to mitigate?
.container {
display: flex;
flex-direction: column;
}
.container > div {
background-color: #666;
color: white;
flex: 1;
height: 300px;
}
<div class="container">
<div>Single line in Firefox, but 300px tall in Chrome!</div>
</div>
The flex: 1 shorthand rule breaks down as follows:
flex-grow: 1
flex-shrink: 1
flex-basis: 0
Chrome sees this, but overrides flex-basis with height: 300px.
Firefox sees this, but does not override flex-basis with height: 300px.
The simple cross-browser solution is to get rid of the height rule and just use:
flex: 1 0 300px
In terms of the spec, Firefox has the correct behavior:
7.1. The flex
Shorthand
When a box is a flex item, flex is consulted instead of the main
size property to determine the main size of the box.
The flex item’s main size
property is
either the width or height property.

Make flex item have 100% height and overflow: scroll [duplicate]

This question already has answers here:
Chrome / Safari not filling 100% height of flex parent
(5 answers)
Closed 5 years ago.
I want a flex item to take 100% of remaining height and display the overflow: scroll bar.
It looks like problem comes from my #userList which takes 100% of the window height and not taking the remaining space .
body {
display: flex;
flex-direction: column;
min-height: 100%;
margin:0px;
}
.wrapper {
display: block;
flex: 1 1 auto;
display: flex;
flex-direction: row; /
}
#chatContainer {
background: orange;
width: calc(100% - 350px);
display: flex;
flex-direction: column;
}
#tabs{
background-color: red;
flex: 1 1 0px;
display: flex;
}
#usersContainer {
flex: 1 1 0;
display:flex;
flex-direction:column;
}
#userListWrapper {
background-color:pink;
flex: 1 1 auto;
display:flex;
}
#userList {
-webkit-flex: 1 1 auto;
overflow: auto;
min-height: 0px;
height:100%;
}
.input {
background-color: #49FFFC;
}
<div class="wrapper">
<div id="chatContainer">
<div id="webcamContainer">webcam</div>
<div id="tabs">tabs here</div>
<div id="footer" style="background-color:#A0C8FF;height:50px">footer</div>
</div>
<div id="usersContainer" style="background-color:blue">
<div class="input">searchInput1</div>
<div class="input">searchInput2</div>
<div id="userList">
user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>
user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>
user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>
user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>
</div>
</div>
</div>
https://jsfiddle.net/jpo31gq9/
The main problem you are having is a violation of the rules governing percentage heights in CSS.
Basically, when using percentage heights, you must always specify the height of the parent element. Otherwise, the element with a percentage height has no frame of reference, and the height computes to auto (the height of the content).
From the spec:
CSS height property
percentage Specifies a percentage height. 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 and this element is not absolutely positioned, the value computes to "auto".
auto The height depends on the values of other properties.
source: https://www.w3.org/TR/CSS21/visudet.html#propdef-height
So if you plan to use percentage heights, you need to specify a height on every parent element up to the root element (html) or up to a fixed height declaration (such as height: 250px).
In your CSS, you have body { min-height: 100%; }. However, there is no height specified on the parent (html).
The following parent elements in your code are missing a height declaration:
html
body (min-height doesn't count)
.wrapper
#chatContainer
With the following adjustments your layout works.
html { height: 100%; } /* NEW */
body {
display: flex;
flex-direction: column;
/* min-height: 100%; */
margin: 0px;
height: 100%; /* NEW */
}
.wrapper {
display: block;
flex: 1 1 auto;
display: flex;
flex-direction: row;
height: 100%; /* NEW */
}
#chatContainer {
background: orange;
width: calc(100% - 350px);
display: flex;
flex-direction: column;
height: 100%; /* NEW */
}
Revised Fiddle
It's also worth mentioning some variations among current browsers.
Percentage Heights: Chrome/Safari vs Firefox/IE
Although the traditional implementation of percentage heights uses the value of the height property, recently some browsers have broadened their scope.
As evidenced in the following posts, Firefox and IE are now also using flex heights to resolve the percentage height of child elements.
Chrome / Safari not filling 100% height of flex parent
Height is not correct in flexbox items in Chrome
Flexbox in Chrome--How to limit size of nested elements?
Chrome ignoring flex-basis in column layout
Bottom line: Chrome and Safari resolve percentage heights based on the value of the parent's height property. Firefox and IE11/Edge use the parent's computed flex height.
For now, the simplest cross-browser solution to this problem would be, in my view, using the height property across the board for percentage heights.

IE 11 issue with flexbox item with max-width

In IE 11 when an item items don't properly center if they have maximum width property. This example however works in Chrome and Firefox.
JS Bin
.container {
display: flex;
justify-content: center;
align-items: center;
background-color: blue;
width: 100%;
}
.red {
background-color: red;
flex-grow: 1;
display: flex;
max-width: 200px;
}
<div class="container">
<div class="red">non centered box</div>
</div>
It is a bug. But according to IE Feedback it was supposed to be fixed already.
As a workaround, you can remove flex-grow: 1; if you don't have to use it.
Explicitly set width: calc(100%); so IE knows the box width and center it properly.
I have had this issue as well. In my case I wanted flex-grow but still wanted to limit the max-width. What I do is wrap any css I don't want IE11 to see in #support. IE11 does not support this rule and ignores its contents completely. I will just check for something that has been around forever like text-align so all the other modern browsers can apply the css rule. You can do this for anything, I just discovered this while trying to figure out an answer to this issue.
#supports(text-align:center) {
div {
max-width: 350px;
}
}

div width changes differently in Firefox vs Chrome after resizing viewport

I noticed a small difference after reducing the viewport with a layout based on flexbox containers. The following snippet contains a few links inside two containers (.container and .subcontainer). In Chrome (45 beta), the divs with class element have the same width regardless of the viewport dimension. However, in Firefox (40), the width of each div changes depending on its content.
html,
body {
margin: 0;
padding: 0;
}
.container {
position: relative;
display: flex;
flex-direction: column;
width: 50%;
}
.element {
flex: 1 0 0;
padding: 0.5em;
text-align: center;
position: relative;
background-color: red;
margin-right: 1em;
}
.subcontainer {
flex: 0 1 auto;
display: flex;
}
.element a {
color: black;
}
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="subcontainer">
<div class="element"><a>abc</a>
</div>
<div class="element"><a>abcdef</a>
</div>
<div class="element"><a>abcdef</a>
</div>
</div>
</div>
</body>
</html>
I think the "Run code snippet" functionality doesn't allow to see this change, so I provide a couple of gifs showing the difference:
Chrome:
Firefox:
As you can see, the boxes share the same width in Chrome, but Firefox constrains the first box quite noticeably and the other boxes keep their proportions. What is the reason of this discrepancy and how can I fix it? I'd like to have the same width for each box. That was the purpose of using flex: 1 0 0 in the first place.
Thanks
Try to set min-width to any value you need, or just 0px:
.element
{
...
min-width: 0px;
}
Fiddle
Details
For Firefox flex items has min-width:min-content by default, as pointed here
These implementations where implementing a slightly simpler behavior
for this keyword: it computed to min-content on flex items, and it
computes to 0 on everything else.
So, if we set min-width:-webkit-min-content for Chrome, it will have the same unwanted behaviour - jsfiddle.