2

I need to nest two flexboxes like this:

First one has two items: a button and a div, the div filling remaining space.

The div is also a flexbox with 3 items: 2 buttons (a left and a right) and a middle div which is scrollable

https://jsfiddle.net/mLtwmc62/

.flex-container
{
   display: flex;
}

.flex-item-auto
{
     flex: 0 0 auto;  /* grow shrink basis */
}

.flex-item-fill
{
    flex: 1 1 auto;  
}

.middle
{
    overflow-x: scroll; 
}


.big
{
    width: 1000px;
    height: 20px;
    background-color: green;
}
<div class="flex-container">
    <button class="flex-item-auto">View All</button>
    <div class="flex-item-fill flex-container">
        <div class="flex-item-auto">Prev</div>
        <div class="middle flex-item-fill">
            <div class="big"></div>
        </div>
        <div class="flex-item-auto">Next</div>      
    </div>
</div>

On IE11, it works as expected, I can see the right button and I can scroll the div.

But not on latest Chrome and Firefox, here the whole page is scrollable, not just the div.

I also need to make it work on mobile (Safari 8, Android 4.3+)

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Don Box
  • 3,166
  • 3
  • 26
  • 55
  • which container? also, is there any other way, I don't want to use fixed sizes or coordinates (that's the reason I'm using flex-boxes anyway) ? thanks – Don Box Oct 12 '15 at 11:41

3 Answers3

1

Update your css like below. You need to set the width to 0 (see note below) on the fill elements.

And don't forget to prefix the "flex" properties for cross browser compatibility on older browser versions

Flex support: http://caniuse.com/#feat=flexbox

.flex-container
{
   display: -webkit-flex;
   display: flex;
}

.flex-item-auto
{
     -webkit-flex: 0 0 auto;  /* grow shrink basis */
     flex: 0 0 auto;  /* grow shrink basis */
}

.flex-item-fill
{
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto;
    width: 0;
}

.left
{
    align-self:  -webkit-flex-start; /* align top */
    align-self:  flex-start; /* align top */
}

.middle
{
    background-color: green;
    /*white-space: nowrap;*/
    overflow-x: scroll; 
}

.next, .prev
{
    background-color: white;
}

.big
{
    width: 1000px;
    height: 20px;
}
<div class="flex-container">
    <button class="left flex-item-auto">My Button</button>
    <div class="flex-item-fill flex-container">
        <div class="prev flex-item-auto">Prev</div>
        <div class="middle flex-item-fill">
           <div class="big"></div>
        </div>        
        <div class="next flex-item-auto">Next</div>      
    </div>
</div>

Note:

Obviously you would prefer to make a liquid layout rather than use px, but Firefox ignores child widths in percentages (ever wonder why whole page flexbox demos are all px?). Oh crap. The workaround is to use width: 0 and let box-flex dictate things.

Src: http://oli.jp/2011/css3-flexbox/

Asons
  • 84,923
  • 12
  • 110
  • 165
  • thanks. I don't want to use fixed sizes or coordinates (that's the reason I'm using flex-boxes anyway), isn't there really other way? – Don Box Oct 12 '15 at 11:42
  • it doesn't work, the page gets a horizontal scrollbar – Don Box Oct 12 '15 at 11:51
  • usually, 100% isn't necessary as these are block elements which fill the space – Don Box Oct 12 '15 at 11:52
  • looks like if I set .flex-item-fill { flex: 1 1 0; } it works on Chrome and IE but not on Firefox. See https://jsfiddle.net/xLtuo305/ – Don Box Oct 12 '15 at 12:11
  • @MikeFills Updated .. does it work now how you want? – Asons Oct 12 '15 at 12:22
  • thanks. it looks like it's working on desktop browsers but not on Safari on iOS 8 – Don Box Oct 12 '15 at 12:55
  • 1
    @MikeFills Updated my sample ... iOS/Safari and iOS/Chrome need the prefix "-webkit-" for flex to work. – Asons Oct 12 '15 at 13:02
  • Wow. Very nice. I forgot about the prefixes, thought it's not needed anymore in latest web-browsers, even if it's mobile. Can I ask what's the logic behind width: 0 ? I guess it means setting the initial width to 0 pixels? – Don Box Oct 12 '15 at 13:28
  • but it's interesting that the div even with width: 0 is rendered nicely – Don Box Oct 12 '15 at 13:32
  • thanks again. would be great if you could find the article. is it this one https://bugzilla.mozilla.org/show_bug.cgi?id=570036 – Don Box Oct 12 '15 at 13:47
  • 1
    @MikeFills Updated my answer with info and a link about the `width: 0` issue – Asons Oct 12 '15 at 13:56
1

Updated Answer

You simply need to add min-width: 0 to the parent of the scrolling item.

Instead of this:

.flex-item-fill {
    flex: 1 1 auto;  
}

Try this:

.flex-item-fill {
    flex: 1 1 auto;
    min-width: 0;    /* NEW */ 
}

Revised Demo

For an explanation see this answer: https://stackoverflow.com/a/34982902/3597276


Original Answer

This appears to be a bug in Firefox.

If you make a slight adjustment to .flex-item-fill, the layout will work in IE11 and Chrome:

.flex-item-fill
{
   flex: 1; /* changed from `flex: 1 1 auto;` */
}

DEMO: https://jsfiddle.net/mLtwmc62/14/

A similar bug was filed with Mozilla a few years ago. Referring to the link below, if you scroll down to the last comments, you'll see it's a problem that may still exist today, and it offers a hint toward a possible workaround.

https://bugzilla.mozilla.org/show_bug.cgi?id=570036

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

This is due to flex spec update: https://drafts.csswg.org/css-flexbox/#min-size-auto

Basically according to the new spec, min-width of the flex-item-fill is its min content. The work around is explicitly setting min-width of flex-item-fill to 0px. Or setting width to 0px as LGSon did.

Seems like Chrome does not support this new behavior yet.

J.Meng
  • 1