Pourquoi mon code fixer les hauteurs fonctionne-t-il mal lorsque la fenêtre du navigateur a été restaurée après avoir été optimisée?

<!DOCTYPE html> <html style = 'height: 100%;'> <head> <title>test manual height calculations</title> </head> <script type = 'text/javascript'> window.onresize = fixHeighs; function endsWith(str, suffix) { if (!str) return false; return str.indexOf(suffix, str.length - suffix.length) !== -1; } function fixHeighs(start_elem) { if (start_elem && start_elem.target) // if this is event, then make var null start_elem = null; var curr_elem = start_elem ? start_elem : document.body; // determine what element we should check now var neededHeight = curr_elem.getAttribute("data-neededHeight"); // get data-neededHeight attribute if (endsWith(neededHeight, "%")) // if this attribute set { curr_elem.height = ((neededHeight.replace("%", "") * curr_elem.parentElement.offsetHeight) / 100) + "px"; // fix heights curr_elem.style.height = ((neededHeight.replace("%", "") * curr_elem.parentElement.offsetHeight) / 100) + "px"; } for (var i = 0; i < curr_elem.children.length; i++) fixHeighs(curr_elem.children[i]); //do the same for children } </script> <body style = 'height: 100%; margin: 0px;' onload = "fixHeighs(null);"> <table border = '1' width = '100%' data-neededHeight = '100%'> <tr> <td colspan = '2' height = '1px'>header</td> </tr> <tr> <td width = '40%' align = 'center' valign = 'middle' bgcolor = 'silver'> <div data-neededHeight = '100%' style = 'width: 90%; border: dashed;'>should be 100% of silver cell</div> <td>text</td> </tr> <tr><td colspan = '2' height = '1px'>bottom panel</td></tr> </table> </body> </html> 

J'ai écrit ce code "génial", qui corrige les éléments de taille pour les navigateurs stupides qui le calculent mal. Il répare bien la taille lorsque le redimensionnement utilisateur du navigateur en tenant ses limites avec la souris ou la fenêtre maximise, mais une fois la fenêtre restaurée, les hauteurs calculées à tort et la barre de défilement apparaît. Je dois savoir pourquoi et comment le réparer.

Très probablement, vous voudrez demander " pourquoi diable je fais ça? "

C'est l'explication du problème:
J'ai vraiment besoin d'avoir une hauteur de page à 100% de la fenêtre du navigateur.

Ce code simple ultime:

 <!DOCTYPE html> <html style = "height: 100%;"> <head> <title>test height</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv = "Content-Type" content = "text/html; charset = windows-1251" /> </head> <body style = "height: 100%; margin: 0px;"> <table border = "1" width = "100%" height = "100%"> <tr> <td colspan = "2" height = "1px">header</td> </tr> <tr> <!-- can add height = '100%' in this TD and then in IE8 - 10, Opera 12.17 inner div height will be 100% OF PAGE, instead of this cell--><td width = "40%" <!--height = '100%'--> align = "center" valign = "middle" bgcolor = 'silver'> <div style = 'width: 90%; height: 100%; border: dashed;'>should be 100% of silver cell</div> </td> <td>text</td> </tr> <tr><td colspan = "2" height = "1px">bottom panel</td></tr> </table> </body> </html> 

Donne des résultats bénis ultimes dans IE8 – IE10 et Opera 12.x La hauteur interne de la division serait " minimale pour correspondre au contenu " ou calculée en fonction de la hauteur de la fenêtre , au lieu de cette TD parentale. Entrez la description de l'image ici

Entrez la description de l'image ici

IE11 est le seul navigateur qui calcule correctement la hauteur de div interne. Entrez la description de l'image ici PS Si vous pouvez résoudre le problème principal pour IE8 – 10, les calculs de hauteur Opera 12.x sans JS, seraient encore meilleurs.

Vous n'avez pas besoin de javascript ou de tableaux pour obtenir la mise en page souhaitée.

box-sizing: border-box; Peut remplacer ce javascript et est compatible avec IE8 +, FF et Chrome. C'est un bon article sur la taille des boîtes.

Nouvel exemple

Prenez cet extrait et collez-le dans un nouveau document HTML. Cela fonctionne dans IE8, bien que nous ayons besoin d'y avoir une hauteur de 99,8% sur html,body utilisant <!--[if IE 8]> .

C'est la solution exacte ici.

HTML et CSS

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> <style type="text/css"> * { margin: 0; padding: 0; box-sizing: border-box; } html,body { height: 100%; } .wrap { height: 100%; } .header { height: 5%; border: solid 1px #000; border-bottom: none; } .table { display: table; height: 90%; width: 100%; border-collapse: collapse; table-layout: fixed; } .cell { display: table-cell; border: solid 1px #000; vertical-align: middle; height: 100%; } .footer { height: 5%; border: solid 1px #000; border-top: none; } .tableTwo { height: 100%; display: table; width: 100%; } .cellTwo { display: table-cell; border: solid 5px #F00; vertical-align: middle; } </style> <!--[if IE 8]> <style type="text/css"> html,body { height: 99.8%; } </style> <![endif]--> </head> <body> <div class="wrap"> <div class="header"> Header </div> <div class="table"> <div class="cell"> <div class="tableTwo"> <div class="cellTwo"> I'm Vertically Centered! </div> </div> </div> <div class="cell"> I'm Vertically Centered! </div> </div> <div class="footer"> Footer </div> </div> </body> </html> 

Exemple original

Voici un exemple simple d' display: table; / display:table-cell; . Il peut être ajusté pour vous donner la disposition exacte que vous recherchez.

Avez-vous un exemple jsBin!

HTML

 <div class="wrap"> <div class="header"> Header </div> <div class="table"> <div class="cell"> I'm Vertically Centered! </div> <div class="cell"> I'm Vertically Centered! </div> </div> <div class="footer"> Footer </div> </div> 

CSS

 * { margin: 0; padding: 0; box-sizing: border-box; } html,body { height: 100%; } .wrap { height: 100%; } .header { height: 5%; border: solid 1px #000; border-bottom: none; } .table { display: table; height: 90%; width: 100%; border-collapse: collapse; table-layout: fixed; } .cell { display: table-cell; border: solid 1px #000; vertical-align: middle; } .footer { height: 5%; border: solid 1px #000; border-top: none; } 

Ok donc après une petite recherche, il semble que ce n'est vraiment pas capable de faire avec JS comme compagnon. Recherche:

  • Comment puis-je faire un div remplir une cellule de table entière?
  • Comment faire <div> remplir <td> hauteur
  • Faire un DIV remplir une cellule de table entière

Ils m'ont amené à cette superbe page de CSS Tricks . (Nécessite jQuery, testé en utilisant 1.9.1 [devrait être IE8 compatible]). Cela aide à laisser les éléments div obtenir une position:absolute; Dans un td et ne pas dériver.

En tant que tel, voici un lien vers un JSFiddle avec votre code comme base. Il était nécessaire de position:absolute certains éléments position:absolute , et d'autres, je l'ai ajouté pour la propreté (autant que possible avec une mise en page basée sur la table ).

Testé sur IE8, IE9, IE10 et fonctionnant comme prévu.

(Si vous cliquez avec le bouton droit sur la sortie et la source de visualisation, vous pouvez voir un fichier html que vous pouvez enregistrer et tester en tant que fichier en dehors de jsfiddle)

J'ai eu exactement le même problème sur un projet. Il s'est avéré que le meilleur truc pour se retrouver avec une solution de navigateur croisé était en fait un positionnement absolu.

 .wrap{background:pink;position:absolute;top:0;left:0;right:0;bottom:0} 

Vous êtes autorisé à être sceptique, mais regardez ce jsfiddle;)

http://jsfiddle.net/evomk0zu/