Are Flexbox and vh height units not compatible in IE11?
Solution 1
The issue isn't vh
units but min-height
I found a semi-working CSS-only solution:
min-height: 100vh;
height: 100px;
The extra height
will enable IE to fill the screen vertically even if the content is not tall enough. The drawback is that IE will no longer wrap the content if it's longer than the viewport.
Since this is not enough I made a solution in JS:
Detection
This function tests the bug: true
means it's buggy.
function hasBug () {
// inner should fill outer
// if inner's height is 0, the browser has the bug
// set up
var outer = document.createElement('div');
var inner = document.createElement('div');
outer.setAttribute('style', 'display:-ms-flexbox; display:flex; min-height:100vh;');
outer.appendChild(inner);
(document.body || document.documentElement).appendChild(outer);
// test
var bug = !inner.offsetHeight;
// remove setup
outer.parentNode.removeChild(outer);
return bug;
}
Fix
The fix consists of manually setting the height
of the element in px
function fixElementHeight (el) {
// reset any previously set height
el.style.height = 'auto';
// get el height (the one set via min-height in vh)
var height = el.offsetHeight;
// manually set it in pixels
el.style.height = height + 'px';
}
The element's height will be set to exactly the height of its content. height
is used as a secondary min-height
in IE, using the behavior observed in the CSS-only solution.
Usage
Once those two functions are defined, set it up this way:
if(hasBug()) {
// fix the element now
fixElementHeight(el);
// update the height on resize
window.addEventListener('resize', function () {
fixElementHeight(el);
});
}
Demo
function hasBug () {
// inner should fill outer
// if inner's height is 0, the browser has the bug
// set up
var outer = document.createElement('div');
var inner = document.createElement('div');
outer.setAttribute('style', 'display:-ms-flexbox; display:flex; min-height:100vh;');
outer.appendChild(inner);
(document.body || document.documentElement).appendChild(outer);
// test
var bug = !inner.offsetHeight;
// remove setup
outer.parentNode.removeChild(outer);
return bug;
}
function fixElementHeight (el) {
// reset any previously set height
el.style.height = 'auto';
// get el height (the one set via min-height in vh)
var height = el.offsetHeight;
// manually set it in pixels
el.style.height = height + 'px';
}
var output = document.getElementById('output');
output.innerHTML = hasBug()?'Browser is buggy':'Browser works correctly';
var el = document.getElementById('flex');
if(hasBug()) {
// fix the element now
fixElementHeight(el);
// update the height on resize
window.addEventListener('resize', function () {
fixElementHeight(el);
});
}
.half-screen {
display:-ms-flexbox;
display: flex;
min-height: 50vh;
padding: 10px;
background: #97cef0;
}
.content {
padding: 10px;
background: #b5daf0;
}
The inner box should fill the outer box vertically, even if the browser is buggy.
<div class="half-screen" id="flex">
<div class="content" id="output">
Text
</div>
</div>
Solution 2
I came across this same bug yesterday and couldn't solve it by myself either. Unfortunately, seems nothing can be done about it, at the moment, because it's IE bug, which have been reported to the Microsoft developers almost a year ago, here:
Solution 3
The trick I've found to getting sticky footers working in IE11 is to make sure flex-basis
is 100%
or even 100vh
. Please see an example below or a live Codepen example that you can test in IE11.
html {
display: flex;
flex-direction: column;
}
body {
display: flex;
flex-direction: column;
flex-grow: 1;
flex-basis: 100%;
min-height: 100vh;
}
header {
padding: 32px;
background-color: seagreen;
}
main {
flex-grow: 1;
padding: 32px;
background-color: rgba(0, 0, 0, 0.05);
}
footer {
padding: 32px;
background-color: coral;
}
<header>
Header
</header>
<main>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not skateboard in the halls.</p>
</main>
<footer>
Footer
</footer>
Admin
Updated on September 26, 2020Comments
-
Admin over 3 years
I'm trying to use a flexbox-based layout to get a sticky footer for my page. This works well in Chrome and Firefox, but in IE11 the footer sits just after my main content. In other words, the main content isn't stretched to fill all of the available space.
body { border: red 1px solid; min-height: 100vh; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-direction: column; -webkit-flex-direction: column; flex-direction: column; } header, footer { background: #dd55dd; } main { background: #87ccfc; -ms-flex: 1 0 auto; -webkit-flex: 1 0 auto; flex: 1 0 auto; }
<body> <header role="banner"><h1> .. </h1></header> <main role="main"> <p>.....</p> </main> <footer>...</footer> </body>
How can I get the main element to stretch in a flex layout when the containers height units are measured in
vh
in IE? I was looking to see if this behaviour is the result of a bug in the way IE implements the flexbox specs, but I couldn't find any mention of this problem elsewhere. -
Vadim Ovchinnikov almost 7 yearsYou didn't understand requirement.
body
should occupy at least whole screen, but can take more. This was the purpose ofmin-height
here which is buggy in IE. -
Blair Allen over 4 yearsThanks for pointing me in the right direction, @souporserious. However, what actually worked for me was just adding the
display: flex
andflex-direction: column
lines to thehtml
CSS element. Addingflex-basis: 100%
to thebody
CSS element didn't make any difference in IE11, or modern browsers, for that matter. -
MomasVII over 4 yearsAs well as
height:100px
I found addingoverflow-y:auto
to mymain
content area worked fine across all browsers.