Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hack Firefox? #8

Closed
jpdevries opened this issue Apr 25, 2015 · 3 comments
Closed

Hack Firefox? #8

jpdevries opened this issue Apr 25, 2015 · 3 comments

Comments

@jpdevries
Copy link
Owner

Firefox still has some flexbox issues, particularly when dealing with flex-direction:column. We are noticing that Firefox will allow children to be as tall as they want, rather than as tall as the flexbox spec tells them they should be. To work around this, I've had to 'hack firefox' to essentially not use the holy grail layout OR manually patch the flexbox bug using JavaScript and a nasty resize listener.

Somebody please tell us we are mistaken and just missing a Firefox prefix or something 🙏

Example

See this page in Firefox 37.0.2 to see how we are working around the flexbox bug by de-activating the holy grail layout.

See this page in Firefox 37.0.2 to see how we are working around the flexbox bug by using JavaScript rather than the above CSS hack.

Sass Hack

html.no-touch {
    .eureka-wrapper.hack-firefox {
        @include media($gtMobile) {
            > .eureka {
                @include firefox-hack() { // #janky
                    @include flex-basis(86%);
                    max-height:86%;
                }
                > .stage {
                    > .eureka-table {
                        @include firefox-hack() {
                            height:auto;
                            @include flex-basis(86%);
                            max-height:86%;
                        }
                    }
                }
            }
            > .proceed {
                @include firefox-hack() {
                    @include flex-grow(1);
                }
            }
        }
    }
}

JavaScript Hack

<script>
/*
  hopefully we are mistaken but we believe we found a use case where firefox 38 deviates from the flexbox spec
  find the patch we came up with below
*/
Modernizr.addTest('firefox', function () {
    return !!navigator.userAgent.match(/firefox/i); // who cut the user agent? shame on us...
});
(function(){
    /*
      checking the userAgent is really gross...
      so let us not and say we did...
    */
    if(!Modernizr.touch && Modernizr.firefox) { // for firefox non-touch browsers
        document.addEventListener('DOMContentLoaded', function(){ // layout the flex children the way firefox should
            /* fix the bug somehow???... */
        });
    }
})();
(function(){ 
    /*
      this is probably a more reliable way than checking the userAgent...
    */
    if(!Modernizr.touch) {
        document.addEventListener('DOMContentLoaded',function(){
            var mediaBrowser = document.getElementById('media-browser_0'); // dangerous but more optimal to not looks these up each resize
            var eurekaWrapper = mediaBrowser.parentNode;
            var eurekaTable = mediaBrowser.querySelector('.eureka-table');

            document.querySelector('.hack-firefox.eureka-wrapper').classList.remove('hack-firefox'); // remove the CSS patch :/

            if(eurekaTable.offsetHeight > eurekaWrapper.offsetHeight) { // eurekaTable might be too tall now
                try {
                    console.log('uh oh, we detect a flexbox bug');
                } catch(e) {}

                function handleResize() {       
                    // i hope i don't get in trouble for doing other browsers homework...
                    var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
                    var dh = (eurekaWrapper.offsetHeight - eurekaWrapper.querySelector('.eureka__topbar').offsetHeight - eurekaWrapper.querySelector('footer.proceed').offsetHeight);
                    dh -= (16*1.5); //1.5ems of margin

                    eurekaTable.style.height = eurekaTable.style.maxHeight = eurekaTable.style.flexBasis  = (w <= 768) ? null : dh + 'px'; 
                }

                window.addEventListener('resize',handleResize, false); // we'll be here all night folks...
                handleResize();
            }

        });
    }
})();
</script>

Chrome 👍


No hacks needed. Correctly laid out.

Firefox 37.0.2 👎


SCSS Hack being used to deactivate holygrail layout.

Firefox 37.0.2 👎


JS Hack being used to manually calculate holygrail layout. This is super lame because the whole point of flexbox is not to have to do things like this 😢

Flexbox Bug

The issue is rather simple. We have div.stage:

with this CSS:

.stage {
  display: flex;
  width: 100%;
  box-orient: vertical;
  flex-direction: column;
  box-lines: single;
  flex-wrap: nowrap;
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 100%;
  -ms-flex-preferred-size: 100%;
}

So it is nice and tall and will lay it's children, div.eureka__topbar and div.eureka-table out vertically. We want .eureka__topbar to take up as much room as it needs to but not grow anymore than is necessary, and then we want .eureka-table to simply take up the remaining space.

We have div.eureka__topbar:

with this CSS:

  flex-basis:4.8rem; /* if we had to pick a certain size */
  flex-shrink:1; /* ok to shrink beyond the basis */
  flex-grow:0; /* do not grow */

Lastly, we have div.eureka-table:

with this CSS:

.eureka-table {
  flex-grow: 1; /* grow */
  flex-basis: 100%; /* be greedy */
  height: auto; 
  -ms-flex-preferred-size: auto;
}

so it will take up the remaining space.

@jpdevries
Copy link
Owner Author

See this commit.
1f8b1ab

I was able achieve a CSS-only workaround but it does require making the body, and basically everything down to the element in question display:flex.
So, The "js hack" could still be usefully for those embedding eureka into systems that you don't have full control over the page layout

@jpdevries
Copy link
Owner Author

I made a codepen to demonstrate this cross browser flexbox issue. In Firefox 37.0.2 Try uncommenting lines 72 and 110 individually and you should notice that either of them will give us the desired effect (by hiding all the subelements the table will stretch to fill the remaining space accordingly and by setting an explicit height the table will scroll appropriately). Problem is, we can't really set an explicit height, and we shouldn't have too accordingly to the flexbox spec...

Screenshot

In the top left we have Safari, which is the only browser shown that lays the elements out correctly. Notice the yellow footer is always visible and the green content area scrolls accordingly.
One the right we see Firefox, nice and tall and in the lower left is Spartan. Both Firefox and Spartan will incorrectly allow .eureka-table > table to grow as tall as it wants, rather than as tall as is needed to take up the remaining space of it's flex parent. It's as if both the box model, which tells elements to grow to accommodate their subelements unless specified otherwise (with something max-height or height), is being respected rather than the flexbox behavior being properly overridden as we see in Webkit.

@jpdevries
Copy link
Owner Author

Also see philipwalton/flexbugs#42

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant