CSS - Étendre la hauteur flottante du DIV enfant à la hauteur du parent

451

J'ai la structure de page comme:

<div class="parent">
    <div class="child-left floatLeft">
    </div>

    <div class="child-right floatLeft">
    </div>
</div>

Maintenant, le child-leftDIV aura plus de contenu, donc la parenthauteur du DIV augmente selon le DIV enfant.

Mais le problème est que la child-righthauteur n'augmente pas. Comment puis-je rendre sa hauteur égale à son parent?

Veera
la source
2
Facile. Facile. Colonnes de hauteur égale avec Flexbox .
Michael Benjamin

Réponses:

459

Pour l' parentélément, ajoutez les propriétés suivantes:

.parent {
    overflow: hidden;
    position: relative;
    width: 100%;
}

alors pour .child-rightceux-ci:

.child-right {
    background:green;
    height: 100%;
    width: 50%;
    position: absolute;
    right: 0;
    top: 0;
}

Trouvez des résultats plus détaillés avec des exemples CSS ici et plus d'informations sur les colonnes de hauteur égale ici .

Sotiris
la source
14
Votre CSS entraîne un comportement indéfini - la taille du parent dépend de la taille des enfants, mais les enfants ont un pourcentage de hauteur défini en termes du parent: cela n'est pas valide et ne fonctionnera probablement pas de manière multi-navigateur.
Eamon Nerbonne,
1
Je vois que vous ne faites pas tout flotter - c'est donc défini au prix de ne pas être mis à l'échelle si jamais la colonne de droite croît plus longtemps que la gauche (ce qui n'est pas le cas dans la question du PO).
Eamon Nerbonne
4
Oui, vous devez ajouter ceci: padding-bottom: 32768px; marge en bas: -32768px; Aux enfants.
Michael
3
Cela fonctionne tant que la colonne de droite est garantie d'avoir moins de contenu que la gauche, sinon elle sera coupée. J'ai également édité la réponse pour omettre les déclarations inutiles.
Christoph
3
@MatthewBlackford: c'est un "hack" en ce sens qu'il empêche l'effondrement des marges. Vous pouvez empêcher l'effondrement de la marge par d'autres moyens, par exemple en utilisant une bordure transparente 1px, mais essentiellement, mais l'important ici est que vous évitiez l'effondrement de la marge. Je n'utiliserais cette solution qu'en dernier recours car elle provoque des erreurs de mise en page étranges et un recadrage inattendu (ou du contenu superposé) lorsque vos hypothèses s'avèrent défectueuses. En bref: vous ne voulez pas faire cela sauf si vous en avez vraiment besoin.
Eamon Nerbonne
206

Une solution courante à ce problème utilise un positionnement absolu ou des flottants recadrés, mais ceux-ci sont délicats car ils nécessitent un réglage approfondi si vos colonnes changent en nombre + taille, et que vous devez vous assurer que votre colonne "principale" est toujours la plus longue. Au lieu de cela, je vous suggère d'utiliser l'une des trois solutions les plus robustes:

  1. display: flex: de loin la solution la plus simple et la meilleure et très flexible - mais non prise en charge par IE9 et les versions antérieures.
  2. tableou display: table: très simple, très compatible (à peu près tous les navigateurs), assez flexible.
  3. display: inline-block; width:50% avec un hack de marge négatif: assez simple, mais les bordures en bas de colonne sont un peu délicates.

1. display:flex

C'est vraiment simple et il est facile de s'adapter à des mises en page plus complexes ou plus détaillées - mais flexbox n'est pris en charge que par IE10 ou version ultérieure (en plus d'autres navigateurs modernes).

Exemple: http://output.jsbin.com/hetunujuma/1

HTML pertinent:

<div class="parent"><div>column 1</div><div>column 2</div></div>

CSS pertinent:

.parent { display: -ms-flex; display: -webkit-flex; display: flex; }
.parent>div { flex:1; }

Flexbox prend en charge beaucoup plus d'options, mais pour avoir simplement un nombre quelconque de colonnes, ce qui précède suffit!

2. <table>oudisplay: table

Un moyen simple et extrêmement compatible de le faire est d'utiliser un table- je vous recommande d'essayer d'abord si vous avez besoin d'un support ancien IE . Vous avez affaire à des colonnes; divs + floats ne sont tout simplement pas la meilleure façon de le faire (sans parler du fait que plusieurs niveaux de divs imbriqués juste pour pirater les limitations css ne sont guère plus "sémantiques" que d'utiliser simplement une table simple). Si vous ne souhaitez pas utiliser l' tableélément, pensez à cssdisplay: table (non pris en charge par IE7 et versions antérieures).

Exemple: http://jsfiddle.net/emn13/7FFp3/

HTML pertinent: (mais pensez à utiliser un simple à la<table>place)

<div class="parent"><div>column 1</div><div>column 2</div></div>

CSS pertinent:

.parent { display: table; }
.parent > div {display: table-cell; width:50%; }
/*omit width:50% for auto-scaled column widths*/

Cette approche est beaucoup plus robuste que l'utilisation overflow:hiddenavec des flotteurs. Vous pouvez ajouter à peu près n'importe quel nombre de colonnes; vous pouvez les faire évoluer automatiquement si vous le souhaitez; et vous conservez la compatibilité avec les anciens navigateurs. Contrairement à la solution flottante, vous n'avez pas non plus besoin de savoir à l' avance quelle colonne est la plus longue; les échelles de hauteur très bien.

KISS: n'utilisez pas de hacks flottants sauf si vous en avez spécifiquement besoin. Si IE7 est un problème, je choisirais quand même un tableau simple avec des colonnes sémantiques sur une solution CSS-trick difficile à maintenir et moins flexible.

Soit dit en passant, si vous avez besoin que votre mise en page soit réactive (par exemple, pas de colonnes sur les petits téléphones mobiles), vous pouvez utiliser une @mediarequête pour revenir à la mise en page en blocs simples pour les petites largeurs d'écran - cela fonctionne que vous utilisiez <table>ou tout autre display: tableélément.

3. display:inline blockavec un hack de marge négative.

Une autre alternative est d'utiliser display:inline block.

Exemple: http://jsbin.com/ovuqes/2/edit

HTML pertinent: (l'absence d'espaces entre lesdivbalises est significative!)

<div class="parent"><div><div>column 1</div></div><div><div>column 2</div></div></div>

CSS pertinent:

.parent { 
    position: relative; width: 100%; white-space: nowrap; overflow: hidden; 
}

.parent>div { 
    display:inline-block; width:50%; white-space:normal; vertical-align:top; 
}

.parent>div>div {
    padding-bottom: 32768px; margin-bottom: -32768px; 
}

C'est un peu délicat, et la marge négative signifie que le "vrai" bas des colonnes est obscurci. Cela signifie à son tour que vous ne pouvez rien positionner par rapport au bas de ces colonnes car cela est coupé par overflow: hidden. Notez qu'en plus des blocs en ligne, vous pouvez obtenir un effet similaire avec des flottants.


TL; DR : utilisez flexbox si vous pouvez ignorer IE9 et les versions antérieures; sinon essayez une table (css). Si aucune de ces options ne fonctionne pour vous, il y a des hacks de marge négatifs, mais ceux-ci peuvent provoquer des problèmes d'affichage étranges qui sont faciles à manquer pendant le développement, et il y a des limites de mise en page dont vous devez être conscient.

Eamon Nerbonne
la source
1
Bon, mais il convient de noter que vous ne pouvez pas utiliser de marges entre ces cellules (et le remplissage n'aidera pas si vous souhaitez les styliser).
Wordpressor
3
border-spacing:10px;sur l'élément de table introduira un espacement de type marge. Alternativement, vous pouvez ajouter des colonnes supplémentaires (vides) là où vous voulez de l'espace supplémentaire. Et vous pouvez également ajouter un remplissage à l'intérieur des cellules du tableau; ce rembourrage sera cependant inclus en arrière-plan, donc ce n'est peut-être pas ce que vous voulez. Mais vous avez raison, ce n'est pas aussi flexible qu'une marge normale. Et vous ne pouvez rien positionner par rapport aux colonnes, ce qui peut être un problème.
Eamon Nerbonne
1
Il vaut donc mieux une mise en page sans table ou non?
dynamique
3
Je dois dire: je suis d'accord avec vous que dans ce cas, un simple tableau est plus que suffisant. Le problème est qu'il existe une vue commune pour ignorer chaque mise en page avec table
dynamique
3
Le problème avec le tableau est que lorsque l'écran est redimensionné à une plus petite largeur (conception réactive), les cellules du tableau sont écrasées au lieu de se superposer au-dessus de la suivante. La deuxième méthode avec padding-bottom: 32768px; marge en bas: -32768px; est assez incroyable et fait presque exactement ce dont j'avais besoin ... merci pour celui-là ... le fond de la frontière est un problème cependant ...
Serj Sagan
23

Pour le parent:

display: flex;

Pour les enfants:

align-items: stretch;

Vous devez ajouter des préfixes, vérifiez caniuse.

Aiphee
la source
2
Je ne le recommanderais pas. IE9 est toujours une chose.
Merci pour votre réponse; Ça marche bien! "Vous devriez ajouter des préfixes, vérifiez caniuse." que voulez-vous dire par cette ligne? Pouvez-vous ajouter un peu plus d'informations pour les débutants?
Md Sifatul Islam
@MdSifatulIslam Allez ici: caniuse.com/#feat=flexbox Vous pouvez voir si un navigateur dont vous avez besoin pour prendre en charge a besoin d'un préfixe de fonctionnalité.
Aiphee
18

J'ai trouvé beaucoup de réponses, mais la meilleure solution pour moi est probablement

.parent { 
  overflow: hidden; 
}
.parent .floatLeft {
  # your other styles
  float: left;
  margin-bottom: -99999px;
  padding-bottom: 99999px;
}

Vous pouvez consulter d'autres solutions ici http://css-tricks.com/fluid-width-equal-height-columns/

Dobromir Minchev
la source
Je n'ai aucune idée pourquoi ce travail, mais il résout mon problème comme un charme. Merci
Combinez
Fonctionne aussi pour moi. Même si ce n'est pas la voie propre. Merci!
Mark Anthony Uy
18
hacky comme l'enfer. Je ne le recommande pas pour une application de production
FedericoCapaldo
c'est incroyable haha. Je ne pensais pas que cela fonctionnerait réellement
Tom McDonough
11

Veuillez définir parent div sur overflow: hidden
ensuite dans divs enfant, vous pouvez définir une grande quantité pour padding-bottom. par exemple,
padding-bottom: 5000px
puis margin-bottom: -5000px
et puis tous les divs enfants seront la hauteur du parent.
Bien sûr, cela ne fonctionnera pas si vous essayez de mettre du contenu dans la div parent (en dehors des autres div c'est-à-dire)

.parent{
    border: 1px solid black;
    overflow: hidden;
    height: auto;
}
.child{
    float: left;
    padding-bottom: 1500px;
    margin-bottom: -1500px;
}
.child1{
    background: red;
    padding-right: 10px;    
}
.child2{
    background: green;
    padding-left: 10px;
}
<div class="parent">
    <div class="child1 child">
        One line text in child1
    </div>
    <div class="child2 child">
        Three line text in child2<br />
        Three line text in child2<br />
        Three line text in child2
    </div>
</div>

Exemple: http://jsfiddle.net/Tareqdhk/DAFEC/

Tareq
la source
semble un peu sale, mais a fonctionné pour moi - la seule solution à cette question. J'ai essayé cela en utilisant Twitter bootstrap.
cukabeka
8

Le parent a-t-il une taille? Si vous définissez la hauteur des parents comme ça.

div.parent { height: 300px };

Ensuite, vous pouvez faire s'étirer l'enfant à sa pleine hauteur comme ça.

div.child-right { height: 100% };

ÉDITER

Voici comment vous le feriez en utilisant JavaScript.

Olical
la source
le parent n'a pas de hauteur fixe. Il se dilate selon la hauteur laissée par l'enfant.
Veera
Ah, j'y ai pensé, alors vous allez avoir besoin de JavaScript, je vais l'ajouter dans une seconde.
Olical
Le lien @Olical JSFiddle est rompu. Supprimez-le ou mettez à jour la réponse. Merci!
itsmysterybox
1
Le lien vers js donne maintenant un 404
Chanoch
5

L'affichage des tables CSS est idéal pour cela:

.parent {
  display: table;
  width: 100%;
}
.parent > div {
  display: table-cell;
}
.child-left {
  background: powderblue;
}
.child-right {
  background: papayawhip;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Réponse originale (en supposant que n'importe quelle colonne pourrait être plus grande):

Vous essayez de faire dépendre la taille du parent de la taille des enfants et la taille des enfants de la taille des parents. Ne calcule pas. Les colonnes CSS Faux sont la meilleure solution. Il y a plus d'une façon de procéder. Je préfère ne pas utiliser JavaScript.

Salman A
la source
Bon point. Que diriez-vous si la taille des enfants dépend de la taille du plus grand frère (que cela soit déterminé par la taille du parent ou non), et non du parent? Je suppose que cela ne peut pas être fait en CSS.
mikato
Non, les frères et sœurs ne peuvent pas affecter la hauteur l'un de l'autre. Cependant, la mise en page display: table+ display: table-cellproduira le résultat souhaité.
Salman A
Grande mise à jour! Cependant, j'ai fini par essayer cela et je voulais avoir une séparation des espaces blancs entre les divs / cellules et j'ai fini par devoir faire des divs internes dans les divs de cellules de table pour accomplir cela, puis j'ai bien sûr perdu la capacité de les faire utiliser toute la hauteur parce que les divisions internes n'étaient pas des divisions de cellules de table - exactement le même problème. Des idées pour ça? Un peu d'espacement des cellules manquant maintenant.
mikato
Ah, il y a l'espacement des bordures en CSS! stackoverflow.com/questions/339923/… J'ai réussi à faire fonctionner correctement mes divs de type table avec la séparation des espaces en utilisant l'espacement des bordures. J'ai maintenant la possibilité de faire en sorte que les cellules du tableau (blocs d'arrière-plan colorés) utilisent la pleine hauteur du parent ou non en utilisant intelligemment les divs des cellules du tableau.
mikato
Juste un problème que j'ai rencontré: vous ne pouvez pas l'utiliser avec float: stackoverflow.com/questions/20110217/…
Joshua Pinter
4

J'ai récemment fait cela sur mon site Web en utilisant jQuery. Le code calcule la hauteur du div le plus haut et définit les autres div à la même hauteur. Voici la technique:

http://www.broken-links.com/2009/01/20/very-quick-equal-height-columns-in-jquery/

Je ne pense pas que height:100%cela fonctionnera, donc si vous ne connaissez pas explicitement les hauteurs de div, je ne pense pas qu'il existe une solution CSS pure.

ajcw
la source
1
Vous devez déclencher cela au moins sur prêt, redimensionner, changer d'orientation, redimensionner la police.
netAction
4

Je l'ai utilisé pour une section de commentaires:

.parent {
    display: flex;
    float: left;
    border-top:2px solid black;
    width:635px;
    margin:10px 0px 0px 0px;
    padding:0px 20px 0px 20px;
    background-color: rgba(255,255,255,0.5);
}
    
.child-left {
	align-items: stretch;
	float: left;
	width:135px;
	padding:10px 10px 10px 0px;
	height:inherit;
	border-right:2px solid black;
}

.child-right {
	align-items: stretch;
	float: left;
	width:468px;
	padding:10px;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Vous pouvez faire flotter l'enfant à droite, mais dans ce cas, j'ai calculé les largeurs de chaque div avec précision.

larsgrafik
la source
1
la première chose qui m'est venue à l'esprit était la taille: n'héritez pas de la raison pour laquelle personne n'a voté
Andreas
3

Si vous connaissez le bootstrap, vous pouvez le faire facilement en utilisant la propriété 'flex'. Tout ce que vous avez à faire est de passer sous les propriétés css à div parent

.homepageSection {
  overflow: hidden;
  height: auto;
  display: flex;
  flex-flow: row;
}

.homepageSectionest ma parent div. Ajoutez maintenant le div enfant dans votre html comme

<div class="abc col-md-6">
<div class="abc col-md-6">

où abc est mon enfant div. Vous pouvez vérifier l'égalité de hauteur dans les deux enfants div indépendamment de la frontière juste en donnant la frontière à l'enfant div

Naved Ali
la source
0
<div class="parent" style="height:500px;">
<div class="child-left floatLeft" style="height:100%">
</div>

<div class="child-right floatLeft" style="height:100%">
</div>
</div>

J'ai utilisé le style en ligne juste pour donner une idée.

suketup
la source
-2

J'ai appris cette astuce lors d'un entretien de stage. La question initiale est de savoir comment vous assurer que la hauteur de chaque composant supérieur dans trois colonnes a la même hauteur qui affiche tout le contenu disponible. Fondamentalement, créez un composant enfant invisible qui restitue la hauteur maximale possible.

<div class="parent">
    <div class="assert-height invisible">
        <!-- content -->
    </div>
    <div class="shown">
        <!-- content -->
    </div>
</div>
Joel Lim
la source