web-dev-qa-db-fra.com

Comment puis-je forcer un DIV flottant à correspondre à la hauteur d'un autre DIV flottant?

Mon code HTML divise simplement les pages en deux colonnes, 65% et 35% respectivement.

<div style="float : left; width :65%; height:auto;background-color:#FDD017;">
   <div id="response">
   </div> 
</div>
<div style="float : left; width :35%;height:auto; background-color:#FDD017;">
   <div id="note">
   </div>
</div> 

Dans responsediv, j'ai des données variables; dans la notediv, j'ai des données fixes. Même si les deux divs ont deux ensembles de données différents, je dois les afficher à la même hauteur pour que les couleurs de l’arrière-plan apparaissent pour remplir une zone les contenant. Naturellement, le problème est la responsediv, car sa hauteur varie en fonction de la quantité de données actuellement affichée.

Comment puis-je m'assurer que la hauteur des deux colonnes est toujours égale?

67
venkatachalam

Enveloppez-les dans un div contenant avec la couleur d'arrière-plan qui leur est appliquée, et ayez un div d'effacement après les «colonnes».

<div style="background-color: yellow;">
  <div style="float: left;width: 65%;">column a</div>
  <div style="float: right;width: 35%;">column b</div>
  <div style="clear: both;"></div>
</div>

Mis à jour pour adresser certains commentaires et mes propres pensées:

Cette méthode fonctionne parce que c'est essentiellement une simplification de votre problème. Dans cette méthode quelque peu 'oldskool', je mets deux colonnes suivies d'un élément de compensation vide, le travail de l'élément de compensation étant de dire au parent (avec l'arrière-plan) que c'est ici le comportement flottant se termine, cela permet au parent de rendre essentiellement 0 pixels de hauteur à la position de l’effacement, ce qui sera quel que soit l’élément flottant antérieurement le plus élevé.

La raison en est que l’élément parent est aussi haut que la colonne la plus haute; l’arrière-plan est ensuite défini sur le parent pour donner l’apparence que les deux colonnes ont la même hauteur.

Il convient de noter que cette technique est 'oldskool' car le meilleur choix est de déclencher ce comportement de calcul de hauteur avec quelque chose comme clearfix ou simplement en ayant un dépassement de capacité: masqué sur l'élément parent.

Bien que cela fonctionne dans ce scénario limité, si vous souhaitez que chaque colonne soit visuellement différente ou ait un espace entre elles, la définition d'un arrière-plan sur l'élément parent ne fonctionnera pas, il existe toutefois une astuce pour obtenir cet effet.

L'astuce consiste à ajouter un fond de remplissage à toutes les colonnes, jusqu'à la taille maximale attendue, ce qui pourrait correspondre à la différence entre la colonne la plus courte et la plus grande. Si vous ne pouvez pas résoudre ce problème, choisissez un grand chiffre, puis ajoutez-le. une marge inférieure négative du même nombre.

Vous aurez besoin d'un débordement masqué sur l'objet parent, mais le résultat sera que chaque colonne demandera de rendre cette hauteur supplémentaire suggérée par la marge, mais ne demandera pas réellement de mise en page de cette taille (car la marge négative prend en compte le calcul). 

Cela rendra le parent à la taille de la colonne la plus haute, tout en permettant à toutes les colonnes de rendre à leur hauteur + la taille du remplissage inférieur utilisé, si cette hauteur est supérieure à celle du parent, le reste sera simplement coupé.

<div style="overflow: hidden;">
  <div style="background: blue;float: left;width: 65%;padding-bottom: 500px;margin-bottom: -500px;">column a<br />column a</div>
  <div style="background: red;float: right;width: 35%;padding-bottom: 500px;margin-bottom: -500px;">column b</div>
</div>

Vous pouvez voir un exemple de cette technique sur le site Web bowers and wilkins (voir les quatre images de projecteur horizontales au bas de la page).

100
meandmycode

Si vous essayez de forcer un div flottant à correspondre à un autre pour créer un effet de colonne, voici ce que je fais. J'aime ça parce que c'est simple et propre.

<div style="background-color: #CCC; width:300px; overflow:hidden; ">
    <!-- Padding-Bottom is equal to 100% of the container's size, Margin-bottom hides everything beyond
         the container equal to the container size. This allows the column to grow with the largest
         column. -->
    <div style="float: left;width: 100px; background:yellow; padding-bottom:100%; margin-bottom:-100%;">column a</div>
    <div style="float: left;width: 100px;  background:#09F;">column b<br />Line 2<br />Line 3<br />Line 4<br />Line 5</div>
    <div style="float:left; width:100px; background: yellow; padding-bottom:100%; margin-bottom:-100%;">Column C</div>
    <div style="clear: both;"></div>
</div>

Je pense que cela a du sens. Cela semble bien fonctionner même avec du contenu dynamique.

38
Dyson

Voici un plugin jQuery pour définir les hauteurs de plusieurs divs identiques. Et ci-dessous est le code réel du plugin.

$.fn.equalHeights = function(px) {
$(this).each(function(){
var currentTallest = 0;
$(this).children().each(function(i){
    if ($(this).height() > currentTallest) { currentTallest = $(this).height(); }
        });
    if (!px || !Number.prototype.pxToEm) currentTallest = currentTallest.pxToEm(); //use ems unless px is specified
        // for ie6, set height since min-height isn't supported
    if ($.browser.msie && $.browser.version == 6.0) { $(this).children().css({'height': currentTallest}); }
        $(this).children().css({'min-height': currentTallest}); 
    });
    return this;
};
15
Justin Yost

La solution correcte à ce problème consiste à utiliser display: table-cell

Important: Cette solution n'a pas besoin de float car table-cell transforme déjà la div en un élément s'alignant sur les autres dans le même conteneur. Cela signifie également que vous n'avez pas à vous soucier de nettoyer les flotteurs, les débordements, les brouillages d'arrière-plan et toutes les autres mauvaises surprises que le pirate float apporte à la fête.

CSS:

.container {
  display: table;
}
.column {
  display: table-cell;
  width: 100px;
}

HTML:

<div class="container">
    <div class="column">Column 1.</div>
    <div class="column">Column 2 is a bit longer.</div>
    <div class="column">Column 3 is longer with lots of text in it.</div>
</div>

En relation:

9
Aaron Digulla

Vous devriez les envelopper dans une div sans float.

<div style="float:none;background:#FDD017;" class="clearfix">
    <div id="response" style="float:left; width:65%;">Response with two lines</div>
    <div id="note" style="float:left; width:35%;">single line note</div>
</div>

J'utilise aussi le correctif clearfix ici http://www.webtoolkit.info/css-clearfix.html

6
bendewey

Je ne comprends pas pourquoi ce problème se heurte au sol alors qu’en 30 secondes, vous pouvez coder un tableau à deux colonnes et résoudre le problème.

Ce problème de hauteur de colonne div se pose partout dans une mise en page typique. Pourquoi recourir aux scripts quand une vieille balise HTML simple va le faire? À moins qu'il y ait d'énormes et nombreuses tables sur une mise en page, je n'accepte pas l'argument selon lequel les tables sont nettement plus lentes.

4
Erich Richter

Flex le fait par défaut.

<div id="flex">
 <div id="response">
 </div> 
 <div id="note">
 </div>
</div>   

CSS: 

#flex{display:flex}
#response{width:65%}
#note{width:35%}

https://jsfiddle.net/784pnojq/1/

BONUS: plusieurs lignes

https://jsfiddle.net/784pnojq/2/

1
Nick Manning

Ce code vous donnera un nombre variable de lignes (avec un nombre variable de DIV sur chaque ligne) et fera en sorte que toutes les DIV de chaque ligne correspondent à la hauteur de son voisin le plus haut:

Si nous supposons que toutes les DIV flottantes sont dans un conteneur avec le id "divContainer", vous pouvez utiliser ce qui suit:

$(document).ready(function() {

var currentTallest = 0;
var currentRowStart = 0;
var rowDivs = new Array();

$('div#divContainer div').each(function(index) {

    if(currentRowStart != $(this).position().top) {

        // we just came to a new row.  Set all the heights on the completed row
        for(currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) rowDivs[currentDiv].height(currentTallest);

        // set the variables for the new row
        rowDivs.length = 0; // empty the array
        currentRowStart = $(this).position().top;
        currentTallest = $(this).height();
        rowDivs.Push($(this));

    } else {

        // another div on the current row.  Add it to the list and check if it's taller
        rowDivs.Push($(this));
        currentTallest = (currentTallest < $(this).height()) ? ($(this).height()) : (currentTallest);

    }
    // do the last row
    for(currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) rowDivs[currentDiv].height(currentTallest);

});
});
0
HardlyNoticeable

Vous pouvez toujours utiliser une image de fond pour le faire aussi. J'ai tendance à voter pour cette option 100% du temps car la seule autre solution parfaite est l'option Jquery.

Comme avec l'utilisation de la division externe avec une couleur de fond, le contenu des deux divisions doit atteindre la même hauteur.

0
Drew

Ayant eu le même type de problème, exigeant trois divs côte à côte avec un contenu différent, avec des bordures droites pour les «séparer», la seule solution qui a fonctionné était une version légèrement modifiée de l'option jQuery dans une autre réponse. Rappelez-vous que vous avez également besoin du script trouvé ici .

Ci-dessous, ma version légèrement modifiée du script, qui permet simplement un réglage de hauteur minimum (car j'avais besoin que mes cases soient au moins d'une certaine hauteur).

/*--------------------------------------------------------------------
 * JQuery Plugin: "EqualHeights"
 * by:    Scott Jehl, Todd Parker, Maggie Costello Wachs (http://www.filamentgroup.com)
 *
 * Copyright (c) 2008 Filament Group
 * Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
 *
 * Description:   Compares the heights or widths of the top-level children of a provided element
                  and sets their min-height to the tallest height (or width to widest width). Sets in em units
                  by default if pxToEm() method is available.
 * Dependencies: jQuery library, pxToEm method    (article:
                  http://www.filamentgroup.com/lab/retaining_scalable_interfaces_with_pixel_to_em_conversion/)
 * Usage Example: $(element).equalHeights();
                  Optional: to set min-height in px, pass a true argument: $(element).equalHeights(true);
                  Optional: to specify an actual min-height (in px), pass an integer value, regardless of previous parameter: $(element).equalHeights(false,150);
 * Version: 2.0, 08.01.2008
--------------------------------------------------------------------*/

$.fn.equalHeights = function(px,minheightval) {
    $(this).each(function(){
        if (minheightval != undefined) { 
            var currentTallest = minheightval;    
        } 
        else { 
            var currentTallest = 0;
        }
        $(this).children().each(function(i){
            if ($(this).height() > currentTallest) { 
                currentTallest = $(this).height();
            }
        });
        if (!px || !Number.prototype.pxToEm) 
            currentTallest = currentTallest.pxToEm(); //Use ems unless px is specified.
        // For Internet Explorer 6, set height since min-height isn't supported.
        if ($.browser.msie && $.browser.version == 6.0) { 
            $(this).children().css({'height': currentTallest});
        }
        $(this).children().css({'min-height': currentTallest});
    });
    return this;
};

Cela fonctionne comme un charme et ne ralentit rien :)

0
David

Je vous recommande de les envelopper dans un div externe avec la couleur de fond désirée.

0
chaos