flexboxベースのレイアウトを使用して、ページのスティッキーフッターを取得しようとしています。これはChromeとFirefoxでうまく機能しますが、IE11ではメインコンテンツの直後にフッターが配置されます。言い換えれば、利用可能なスペースをすべて埋めるためにメインコンテンツがストレッチされるわけではありません。
ここの例- http://jsfiddle.net/ritchieallen/3tpuryso/
HTML:
<body>
<header role="banner"><h1> .. </h1></header>
<main role="main">
<p>.....</p>
</main>
<footer>...</footer>
</body>
CSS:
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;
}
IEで-コンテナの高さの単位がvhで測定されている場合、フレックスレイアウトでメイン要素を伸縮させるにはどうすればよいですか?この動作がIEがflexbox仕様を実装する方法のバグの結果であるかどうかを確認しようとしていましたが、他の場所でこの問題について言及することはできませんでした。
問題はvh
単位ではなく、 min-height
CSSのみの半有効なソリューションを見つけました。
min-height: 100vh;
height: 100px;
余分なheight
は、コンテンツの高さが十分でない場合でもIEで画面を垂直に埋めることができます。欠点はIEビューポートよりも長い場合、コンテンツをより長くラップします。
これでは十分ではないため、JSでソリューションを作成しました。
この関数はバグをテストします:true
はバグがあることを意味します。
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;
}
修正は、height
内の要素の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';
}
要素の高さは、コンテンツの高さに正確に設定されます。 height
はセカンダリとして使用されますmin-height
IEで、CSSのみのソリューションで観察された動作を使用します。
これらの2つの関数を定義したら、次のように設定します。
if(hasBug()) {
// fix the element now
fixElementHeight(el);
// update the height on resize
window.addEventListener('resize', function () {
fixElementHeight(el);
});
}
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>
昨日、この同じバグに出くわし、自分でも解決できませんでした。残念ながら、現時点では何もできないようです。なぜなら、それはIEバグであり、ほぼ1年前にマイクロソフトの開発者に報告されているからです。
IE11でスティッキーフッターを機能させるために見つけたトリックは、flex-basis
は100%
あるいは 100vh
。以下の例を参照するか、IE11でテストできる live Codepenの例 をご覧ください。
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>