web-dev-qa-db-fra.com

IE11 - Les unités de hauteur flexbox et vh ne sont pas compatibles?

J'essaie d'utiliser une mise en page basée sur une boîte souple pour obtenir un pied de page collant pour ma page. Cela fonctionne bien dans Chrome et Firefox, mais dans IE11, le pied de page se trouve juste après mon contenu principal. En d'autres termes, le contenu principal n'est pas contraint pour occuper tout l'espace disponible.

Exemple ici - 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;
}

Dans IE - Comment obtenir l’élargissement de l’élément principal dans une structure flexible lorsque les unités de hauteur des conteneurs sont mesurées en vh? Je cherchais à savoir si ce comportement était le résultat d'un bogue dans la façon dont IE implémentait les spécifications de la flexbox, mais je n'ai trouvé aucune mention de ce problème ailleurs.

23
Ritchie Allen

Le problème n'est pas vh unités mais min-height

J'ai trouvé une solution CSS uniquement semi-fonctionnelle:

min-height: 100vh;
height: 100px;

La variable supplémentaire height permettra à IE de remplir l'écran verticalement même si le contenu n'est pas assez haut. L'inconvénient est que IE n'enveloppera plus le contenu s'il est plus long que la fenêtre d'affichage.


Comme cela ne suffisait pas, j'ai fait une solution dans JS:

Détection

Cette fonction teste le bug: true signifie que c'est un 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;
}

Réparer

Le correctif consiste à définir manuellement la height de l'élément dans 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'; 
}

La hauteur de l'élément sera définie sur la hauteur exacte de son contenu. height est utilisé en tant que min-height secondaire dans IE, en utilisant le comportement observé dans la solution CSS uniquement.

Usage

Une fois ces deux fonctions définies, configurez-le comme suit:

if(hasBug()) {
    // fix the element now
    fixElementHeight(el);

    // update the height on resize
    window.addEventListener('resize', function () {
        fixElementHeight(el);
    });
}

Démo

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>

22
bfred.it

Je suis tombé sur le même bug hier et je ne pouvais pas le résoudre moi-même non plus. Malheureusement, rien ne peut être fait pour le moment, car c’est un bogue IE, qui a été signalé aux développeurs Microsoft il y a presque un an, ici: 

https://connect.Microsoft.com/Feedback/details/802625/min-height-and-flexbox-flex-dlex-direction-column-dont-work-to-ether-in-ie-10-11-preview

3
covfefe

Le truc que j'ai trouvé pour faire fonctionner les pieds de page collants dans IE11 est de s'assurer que flex-basis est 100% ou même 100vh. Veuillez consulter un exemple ci-dessous ou un exemple live Codepen que vous pouvez tester dans 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>

0
souporserious