12

There seems to be a problem with flexbox in chrome which affects columns of variable height. When the contents of these columns change the column should resize, but it doesn't

I have created a JS fiddle here - http://jsfiddle.net/KVQTd/2/

Just hit the 'remove content button' to see what I mean.

This is the simplest example of using flexbox to create columns to demonstrate that nothing else is causing it.

.wrapper{
    display: flex;
    align-items: stretch;
}

.column1{
    flex: 1;
}

.column2{
    flex: 1;
}

I'm pretty sure this is a bug in Chrome because when you go into developer tools and switch flex off and on again it then calculates the height correctly.

I have submitted a bug report here - https://code.google.com/p/chromium/issues/detail?id=369869&thanks=369869&ts=1399226675 -

...but I don't have time to wait for new versions of Chrome to be released so I was hoping somebody might be able to think of a clever solution. Perhaps some kind of javascript which watches the height of the inner content and adjusts forces a recalculation of the flexbox height?

jonhobbs
  • 26,684
  • 35
  • 115
  • 170
  • it is a known bug in chrome and have seen no cure , unless a refresh – G-Cyrillus May 05 '14 at 14:00
  • Thanks, I searched very hard on Google to see if anybody else had noticed before posting the bug report but I obviously wasn't searching for the right thing. If it's a known bug then they're dragging their heels in fixing it. I've known about it for the last couple of versions but have only just got round to trying to find a solution. – jonhobbs May 05 '14 at 15:09
  • Since you already use javaScript, we can tweek a way to force a refresh without reload, more like a reflow of content. see my answer and demo below to check if this works and suits you. – G-Cyrillus May 05 '14 at 16:12
  • Seems to work fine for me now (Chrome 35). – Dan Abramov May 27 '14 at 15:53

4 Answers4

9

This works for me:

var elem = document.getElementById("myFlexbox");
elem.style.display='none';
elem.offsetHeight; // no need to store this anywhere, the reference is enough
elem.style.display='flex';

Also see: How can I force WebKit to redraw/repaint to propagate style changes?

Community
  • 1
  • 1
Lukas Glowania
  • 498
  • 6
  • 12
7

In order to work in Chrome, it needs a refresh or some kind of reflow. DEMO

If you script force the main container to be recalculated, you have something that works. (this looks like some very old bug of Opera)

In order to do that, we can switch from position static to relative and use a pseudo to insert some content.

CLASS wrapper becomes an ID to easily select it via JavaScript

<div id="wrapper">
    <div class="column1">This column Has some content</div>
    <div class="column2">This column also has some content
        <div id="contentToHide">
            <p>Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.</p>
        </div>
    </div>
</div>
<button id="removeButton">Remove Content</button>
<br/>
<button id="addButton">Add Content</button>

javaScript update

document.getElementById('removeButton').addEventListener("click", function (event) {
    document.getElementById('contentToHide').classList.add("hidden");
    document.getElementById('wrapper').classList.add("prelative");
});

document.getElementById('addButton').addEventListener("click", function (event) {
    document.getElementById('contentToHide').classList.remove("hidden");
    document.getElementById('wrapper').classList.remove("prelative");
});

CSS update:

#wrapper {
    display: flex;
    width: 400px;
    margin-bottom: 30px;
}
.column1 {
    padding: 10px;
    background: #DDD;
}
.column2 {
    padding: 10px;
    background: #EEE;
    width:50%;
}
#contentToHide.hidden {
    display: none;
}
.prelative {
    position:relative;
}
div:before {
    content:attr(class);
    left:-9999px;
    position:absolute;
}

Actually, for .hidden and pseudo you can just do :

#contentToHide.hidden ,
div:before {
    content:attr(class);
    left:-9999px;
    position:absolute;
}
isherwood
  • 58,414
  • 16
  • 114
  • 157
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • Thanks, switching between static and relative positioning seems to be the trick. My use case is a tab system so I'll just have to change the position of the column wrapper every time the tab is changed. Shame I have to do that but I'm sure they'll fix it at some point. – jonhobbs May 05 '14 at 18:45
  • nice but i think it is a little bit much of code to just get a reflow... in my case, i just had to make a selector for all my boxes and just give'em "position": "static", and a "position": "relative" again - but be careful, to really trigger a reflow, you must give the second call a little timeout, otherwise webkit thinks he can "optimize" that and he won't make a reflow because the second line would change it back to normal state as default.. – jebbie May 09 '14 at 13:04
  • @jebbie however, whatever works should be fine untill Chrome behavior get fixed :) psoition switch and content is taking very little ressource, javascript should not take much more either. The point is to awake chrome :) – G-Cyrillus May 11 '14 at 18:32
5

Try to set height: 100% for columns

Max P
  • 1,439
  • 3
  • 15
  • 33
  • when one of my flexboxes re-rendered it triggered adjacent flexboxes to re-render with a different width, even thought the contents was the same. When I added height: 100% I could see with Chrome dev tools that changes in these other divs didn't activate a re-render. This error showed up for me after chrome 48 was released. – N D Feb 15 '16 at 23:58
1

I solved this by setting height: max-content on the children of the flex container

Jordan Shurmer
  • 946
  • 7
  • 21