Flexbox max-height interpretation change on Chrome - css

I have some code which currently renders properly on Chrome Stable. I have received reports of the code working incorrectly on Beta and Dev and I am able to reproduce the issue on Canary. I found this PSA which appears related to my issue. So, I am working under the assumption this is a change to more closely follow spec rather than a bug.
My software only targets Google Chrome. So, a robust solution is not necessarily needed although it would be nice to have backwards compatibility.
The setup is:
Parent element has display:flex, flex-direction: column and has max-height applied to it.
A deep descendant of the parent exceeds the max-height
And the behavior change is:
On stable, max-height is enforced and child does not break out.
On canary, max-height is disregarded and child breaks out.
I am able to prevent the child from breaking out by applying max-height to the inner element. However, this is not desirable because I would need to reduce the value for max-height by the height of footer which isn't easily done in a non-contrived example.
The following code snippet highlights my issue:
.outer {
display: flex;
flex-direction: column;
max-height: 410px;
}
.inner {
display: flex;
flex-direction: column;
}
.content {
width: 200px;
height: 500px;
background-color: green;
}
.footer {
height: 20px;
width: 200px;
background-color: red;
}
<div class='outer'>
<div class='inner'>
<div class='content'>
</div>
</div>
<div class='footer'>
</div>
</div>
Here is a screenshot of how this renders on Chrome Canary (left) vs Chrome Stable (right):
Is anyone able to tell me how to adjust this code such that inner + footer respect the max-height value of outer?

I believe I understand the issue, but I will build upon this answer more as I learn more about the solution.
This issue was introduced due to resolution of this bug filed against Chromium. The spec indicates that the default value of a flex container should be min-height: auto where as currently it is min-height: 0.
A specific comment addresses the fact that this is a breaking change against all production websites and references a suggested change:
https://code.google.com/p/chromium/issues/detail?id=426898#c17
The change is:
In case this patch breaks any website or chrome UI, the fix is likely
to add:
min-width: 0;
min-height: 0;
Applying min-height: 0 to .inner resulted in a layout consistent with what I currently see on stable.

Related

CSS flex layout overflow issue - not 100% of nested content can be scrolled

I have a problem with flexlayout and overflow. Here you can see my Problem:
The icons are not 100% scrollable. I have absolutely no clue how to fix this. In theory, I think everything should be correct. I use Angular, Angular FlexLayout, Custom CSS. The Icons are grouped using flexlayout="column" and flexlayoutalign="space-around center" and everything is encapsulated with a div flexlayout="row", flexlayoutalign="space-around center". This row is now not fully recognized by my overflow CSS variable using custom CSS. Here are my classes. First, I set a fixed boundary for the popup (one hierarchy-level over the mat-card), and the latter is added to the mat-content section of the mat-card.
CSS for the Popup:
.max-height:{
max-height: 500px;
}
CSS for mat-content:
:host{
overflow-y: auto;
display: flex;
flex-direction: column;
height: 100%;
}
mat-dialog-content{
max-height: unset !important;
}
.example-card{
height: inherit;
}
.mat-card-content{
max-height: 300px;
overflow-y: auto;
}
.min-width-icons{
min-width: 100%;
}
Any ideas on how to fix this error?
Edit:// here are inspection figures:
Edit:// if I set a fixed height on the icons, e.g., 50px, the icons move out the upper boundary even more:
Edit://
issue persists even if i use png/jpg:
Edit://
Maybe it has something to do that the description class is adding word-break: break-all; But, either I do not how to counter that.
Edit://
Ugh this is some nasty CSS sh... got it working! It has something to do with the overflow-wrap/word-break of the underlying description:
As far as I noticed is that everything got better after i added width/min-widt of 100%. After that, i tried to set the height value to 100% (not worked). But, as far as i add a height in px (every value from 1px to 2000px) everything works as expect, which makes absolutely no sense to me, maybe some CSS mastermind can me pin point the reason. Field height is marked in black and green is the overflow word-break.
But, for now the problem seems to be solved with this css:
.text-area{
word-break: break-all;
min-width: 100%;
width: 100%;
height: 100px;
}

Wrapping a link around an image destroys flexbox layout and causes browser rendering quirks

Struggling to find the right title that isn't just a mixture of "help" and "what, CSS, why?!" so hopefully a couple of you geniuses will find this...!
I have two columns. Each of them has a full-width div inside it which contains a logo. The images are quite different shapes, one being a square and one being a more panoramic aspect ratio. To achieve a balanced look, the images are set to a max-width of 50% and a max-height of 100%. Flexbox is used to center the images both horizontally and vertically.
They look perfectly fine.
// working before wrapping images with links
section.working {
div.flex {
display: flex;
justify-content: center;
align-items: center;
img {
max-width: 50%;
max-height: 100%;
}
}
}
And then I needed to add links.
https://codepen.io/lenoz/pen/VwZyeOG
This is the problem reduced to its most simple, in that the bottom row was the original code I was using to get the perfect layout, and the top row shows what happens when the images were wrapped in tags to make them links. Some points of note:
colours added just to help distinguish boundaries a little - useful for detecting when the link (red background) is no longer constricted to the size of the image inside it (as it ideally should be)
the two columns are separate in the code and not part of a shared container - i.e. one cannot inform the height of the other (want to fix this with CSS not JS)
I should mention that of course there was no way adding links would just work - the <a> tags come in between the flex container and the flex item, so obviously they will mess with the layout.
Much appreciated if you can help me find a CSS solution.
Still here? Read on if you want some more info on my attempts to fix, with a side portion of Chrome weirdness.
It should also go without saying I've spent ages fiddling with this, so here's another link showing some of my efforts that have gotten close: https://codepen.io/lenoz/pen/pozpjVq
The top row (section.help) is my latest attempt, but is a bit of a mess simply because I stopped half way, having suffered frustration sufficient to lead to me making this post.
The middle row, which I'm calling section.weirdness, actually seemed to be a solution for a hot minute. If you're using Chrome, like I am, when you look at the Codepen link you may see nothing on these blue blocks?
But try removing the display: flex attribute from div.flex and, if your Chrome is like my Chrome, you'll see this:
Now, add that same display: flex attribute back on the same div.flex selector and you'll see that suddenly the blue blocks are not blank:
How strange is that? Browser rendering bug or what?
Now find the max-width or max-height attributes on div.image, toggle one of those off and then on again and you'll see that everything suddenly looks right again:
Somehow, without changing any CSS other than toggling it, we've gone from no links showing up at all, to them showing up and looking perfect. You can see how I'd managed to confuse myself into thinking I had got it working!
Just add style="display: contents" to your anchors
"display: contents" causes an element's children to appear as if they were direct children of the element's parent, ignoring the element itself
<div>
<a style="display: contents" href="#">
<img src="https://via.placeholder.com/1000x300.png" />
</a>
</div>
Here's a simple solution:
I've changed the columns to be flex contexts but retained an inner div to serve as the 50% width constraint. When the imgs are allowed to set their own height explicitly all the other constraints around them flow into place without much fuss, and because the anchors don't have any layout rules, they manage to avoid having any clickable areas outside their image.
With the same max-height on the images, they'll match in the same way as your .working class as long as their containers are the same width.
section {
width: 800px;
display: flex;
}
.column {
background-color: blue;
margin: 5px;
width: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.column > div {
max-width: 50%;
}
img {
display: block; /* get rid of bottom gap */
max-width: 100%;
max-height: 80px;
}
<section>
<div class="column">
<div>
<a href="#">
<img src="https://via.placeholder.com/500x500.png" />
</a>
</div>
</div>
<div class="column">
<div>
<a href="#">
<img src="https://via.placeholder.com/1000x300.png" />
</a>
</div>
</div>
</section>
Try adding this to your Codepen example:
.flex > a {
flex: 0 0 50%;
height: 100%;
display: flex;
}
div.flex a > img {
max-width: 100% !important;
max-height: 100% !important;
margin: auto;
}
Any immediate child of a container with display: flex is flex item. To prevent that item from growing or shrinking we must set flex-grow and flex-shrink properties to 0. In my case I used flex: 0 0 50% shorthand for that. That last value of 50% is from your initial image max-width property. That + height:100% will make sure that <a> behaves like images in your original example.
Now the fun part: use display: flex again on <a> to make the image flex item again. Since <a> is already properly sized we can set max-width and max-height to `00% to fill available space.
Using margin: auto is a neat trick to center both horizontally and vertically flex child inside of flex container (works only when there is one child).
sidenote: I used important to override specificity without changing markup but I would advise against it and put new CSS class on both a and img.
UPDATE
working fork (Chrome only): https://codepen.io/teodragovic/pen/wvwpWbx?editors=1100
section.broken {
.flex {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
a {
max-width: 50%;
max-height: 100%;
}
img {
max-width: 100%;
max-height: 100%;
display: block;
}
}

Display flex Firefox - content not shrinking [duplicate]

This question already has answers here:
How can I get FF 33.x Flexbox behavior in FF 34.x? [duplicate]
(3 answers)
Closed 7 years ago.
I have discovered what I believe to be a bug in Firefox versions 34 and above with regards to the behavior of display: flex.
I can confirm the code has always worked in all modern browsers, and still does, but Firefox 34 and the recent Firefox 35 beta, the behavior is totally inconsistent.
I have created a fiddle that demonstrates the different behavior: http://jsfiddle.net/ntkawu63/
Launch that in Firefox 34+ and it will ignore the max-width: 100% on the image. In any other browser, including Firefox 33, it will apply the max-width to the image and display normally.
<style>
.mediaContainer
{
zoom: 1;
overflow: visible;
position: relative;
}
.mediaCenterContainer
{
display: flex;
justify-content: center;
align-items: center;
}
.imageContainer
{
margin: 0 auto;
}
.imageContainer img
{
margin-bottom: 10px;
max-width: 100%;
}
</style>
<div class="mediaContainer mediaCenterContainer">
<div class="imageContainer">
<img src="http://dummyimage.com/1920x1080/000/fff.png&text=This+is+a+flex+box+test+for+Firefox+340x2B.+In+Chrome,+the+image+will+be+max-width:+1000x25.+In+Firefox+the+image+will+be+centered,+but+not+have+a+constrained+width." class="Image Tag Crop" alt="My Dog" data-realwidth="1000" data-realheight="670" data-scalewidth="944" data-scaleheight="633" />
</div>
</div>
Is there something wrong with this code, or is this something that should be raised as a bug with Mozilla?
Edit—the original answer was not fully correct
The important aspects here are
The "flex item" div.imageContainer needs a positive flex-shrink value
The (display:inline) img child of the flex item needs its own constraint to ensure it doesn't overflow the flex item
In accordance with the W3C flexbox spec*, the flex item needs some kind of definite size constraint, which we can satisfy by delcaring min-width:1px or max-width:100% on .imageContainer; otherwise, in accordance with the spec, the .imageContainer must take its content's size, i.e. the full 1000px intrinsic size of the PNG image
OP's question already satisfied point 2, but not points 1 and 3. Here is the CSS which I used:
.mediaContainer
{
overflow: visible;
width:100%;
}
.mediaCenterContainer
{
display: flex;
}
.imageContainer
{
flex-shrink:1;
min-width:1px;
}
.imageContainer img {
max-width:100%;
}
… and here's a fiddle demonstrating it.
Many thanks to #dma_k for pointing out the error in my original answer.
*I usually hate linking to W3C specs, but this section is actually quite readable; I'd encourage people to read it.
Original answer
Firefox 36 (currently dev preview) gives the behaviour you expect if you constrain the div rather than the img. You can do this using flex-shrink:
.imageContainer {
flex-shrink:1;
}
… or the short-hand flex property:
.imageContainer {
flex: 0 1 auto;
}
… or using the max-width declaration you had placed on the img, but also on the div:
.imageContainer, .imageContainer img {
max-width:100%;
}
So Firefox allows flex elements to overflow their containers. I don't know the flexbox spec that well, but it seems natural that this would be the case; that's why the flex-shrink property exists.

IE display: table-cell child ignores height: 100%

I need to dynamically build a table to hold some data.
I've followed the usual approach of using divs with display: table, display: table-row and display: table-cell:
.tab {
display: table;
height:100%;
width: 200px;
}
.row {
height: 100%;
display: table-row;
}
.elem {
border: 1px solid black;
vertical-align: top;
display: table-cell;
height:100%;
background: blue;
}
.content {
height: 100%;
background: greenyellow;
}
<div class="tab">
<div class="row">
<div class="elem">
<div class="content">
Content
</div>
</div>
<div class="elem">
<div class="content">
Longer content that will need to wrap around eventually you know and don't you hate it when things don't end as you expect them octopus
</div>
</div>
</div>
</div>
Or view on Jsfiddle.
In most browsers I get the expected output:
However, in IE8 (and possibly later versions, I haven't tested later versions), I get the following:
The height: 100% set on the div surrounding "Content" is ignored.
According to CanIUse, IE8 should offer full support for the related display properties.
I've looked through a number of similar questions on SO without finding a working solution: most solutions either rely on Javascript (which I'm looking to avoid), use a fixed height (ibid previous) or don't work on IE8.
Unfortunately, the effect of percentage values for height on display: table-row and display: table-cell elements is undefined according to the spec:
CSS 2.1 does not define how the height of table cells and table rows is calculated when their height is specified using percentage values.
So while a browser may claim to offer full support for table layout, certain aspects such as percentage heights may not be consistently implemented across all browsers because there is no correct behavior. You could try raising an issue on Microsoft Connect in hopes that they will change the behavior to be interoperable, but in the meantime you will need to find a different workaround (and even then you can't guarantee the behavior will remain interoperable, even in other browsers).
To make matters worse, I just tested and this affects all versions of IE up to and including 11, which means an IE-specific hack will fall short here. If you need to use a CSS table layout, as evidenced by the fact that you need to support IE8, then a pure CSS workaround is probably not feasible.
For Internet Explorer 8-10 table-cells with height: 100%; have to be wrapped by table-row with height: 100%;.
Html for IE should be like:
table > table-row > table-cell
While other browsers will work properly with
table > table-row
or
table > table-cell
[edit] I reviewed the question again, and noticed You want to set 100% height not to the table-cells, but on the content inside it.
solution 1: So for Internet Explorer content-height is related to closest element with height set in absolute units, such as pixels, em's, if you want to use % height, you may also need to set 100% height on all parent elements, this will be html and body.
working example
solution 2: Simply add
.content {
padding-bottom: 9999px;
margin-bottom: -9999px;
}
.elem {
overflow: hidden;
}
You don't need to set height on Any of the parent elements in this case.
working example.
Hope this helps.

CSS: Sticky Footer using Flexbox – avoiding the vh unit by setting percentages?

I am experimenting with using Flexbox to implement a sticky footer (footer is at the bottom of the page, even when there is little content).
I found a great example of this on the web:
HTML:
<body class="Site">
<header>...</header>
<main class="Site-content">...</main>
<footer>...</footer>
</body>
CSS:
.Site {
display: flex;
min-height: 100vh;
flex-direction: column;
}
.Site-content {
flex: 1;
}
Fiddle
Note: Won't work in all browsers because of unprefixed declarations, maybe try it in Chrome
While this works I don't like the use of the vh unit because that unit is even less suported than Flexbox. So I tried to use percentages instead of vh:
body {
display: flex;
min-height: 100%;
flex-direction: column;
}
Fiddle
(To keep it short I only post the code that changed, but a full example is in the Fiddle.)
Now the solution is not working anymore because the body's parent – the html element – has no height declared, so min-height has no reference. So I've tried to set
html,
body {
min-height: 100%;
}
but that also did nothing. Probably because that way, also the html element has no reference. As a conclusion, I have to do it like this to get it working again:
html {
height: 100%;
}
body {
display: flex;
min-height: 100%;
flex-direction: column;
}
Fiddle
While this seems to work, I am not sure of the side effects of using height: 100% on the html element. I remember some years back, I once rendered a website unusable by using something similar without the matching overflow declaration.
Are there any downsides of this solution? Are there maybe more robust solutions using percentages?

Resources