152 votes

Faire en sorte que la div (hauteur) occupe la hauteur restante du parent

Considérons l'exemple de code HTML/css suivant :

<div id="container">
    <div id="up">Text<br />Text<br />Text<br /></div>
    <div id="down">Text<br />Text<br />Text<br /></div>
</div>

#container { width: 300px; height: 300px; border:1px solid red;}
#up { background: green; }
#down { background:pink;}

où j'ai un conteneur div avec deux enfants (également ici : http://jsfiddle.net/S8g4E/ ). Le premier enfant a une taille donnée. Comment puis-je faire en sorte que le deuxième enfant occupe l'"espace libre" du conteneur ? div sans donner de hauteur spécifique ?

Dans l'exemple, le rose div doit également occuper l'espace blanc.


Semblable à cette question : Comment faire en sorte que la div occupe la hauteur restante ?

Mais je ne veux pas donner position absolue .

216voto

Quantastical Points 4431

Élargissement de la #down pour remplir l'espace restant de #container peut être réalisée de différentes manières, en fonction de la compatibilité avec le navigateur que vous souhaitez obtenir et de l'existence ou non de l'option #up a une hauteur définie.

Échantillons

.container {
  width: 100px;
  height: 300px;
  border: 1px solid red;
  float: left;
}
.up {
  background: green;
}
.down {
  background: pink;
}
.grid.container {
  display: grid;
  grid-template-rows: 100px;
}
.flexbox.container {
  display: flex;
  flex-direction: column;
}
.flexbox.container .down {
  flex-grow: 1;
}
.calc .up {
  height: 100px;
}
.calc .down {
  height: calc(100% - 100px);
}
.overflow.container {
  overflow: hidden;
}
.overflow .down {
  height: 100%;
}

<div class="grid container">
  <div class="up">grid
    <br />grid
    <br />grid
    <br />
  </div>
  <div class="down">grid
    <br />grid
    <br />grid
    <br />
  </div>
</div>
<div class="flexbox container">
  <div class="up">flexbox
    <br />flexbox
    <br />flexbox
    <br />
  </div>
  <div class="down">flexbox
    <br />flexbox
    <br />flexbox
    <br />
  </div>
</div>
<div class="calc container">
  <div class="up">calc
    <br />calc
    <br />calc
    <br />
  </div>
  <div class="down">calc
    <br />calc
    <br />calc
    <br />
  </div>
</div>
<div class="overflow container">
  <div class="up">overflow
    <br />overflow
    <br />overflow
    <br />
  </div>
  <div class="down">overflow
    <br />overflow
    <br />overflow
    <br />
  </div>
</div>

Grille

CSS's grid offre une autre option, même si elle n'est pas aussi simple que le modèle Flexbox. Cependant, il suffit de styliser l'élément conteneur :

.container { display: grid; grid-template-rows: 100px }

En grid-template-rows définit la première ligne comme étant d'une hauteur fixe de 100px, et les autres lignes s'étireront automatiquement pour remplir l'espace restant.

Je suis presque sûr qu'IE11 nécessite -ms- il faut donc veiller à valider la fonctionnalité dans les navigateurs que l'on souhaite prendre en charge.

Flexbox

CSS3 Module de mise en page de la boîte flexible ( flexbox ) est désormais bien supporté et peut être très facile à mettre en œuvre. Grâce à sa souplesse, il fonctionne même lorsque #up n'a pas de hauteur définie.

#container { display: flex; flex-direction: column; }
#down { flex-grow: 1; }

Il est important de noter que la prise en charge de certaines propriétés flexbox par IE10 et IE11 peut être boguée, et qu'IE9 ou les versions inférieures ne sont pas du tout prises en charge.

Hauteur calculée

Une autre solution simple consiste à utiliser la fonction CSS3 calc unité fonctionnelle, comme le souligne Alvaro dans sa réponse mais il faut que la taille du premier enfant soit une valeur connue :

#up { height: 100px; }
#down { height: calc( 100% - 100px ); }

Il est assez largement pris en charge, les seules exceptions notables étant <= IE8 ou Safari 5 (pas de prise en charge) et IE9 (prise en charge partielle). Parmi les autres problèmes, citons l'utilisation de calc en liaison avec transformer o ombre de la boîte Il convient donc de tester plusieurs navigateurs si cela vous intéresse.

Autres alternatives

Si un support plus ancien est nécessaire, vous pouvez ajouter height:100%; a #down rendra la div rose pleine hauteur, avec une mise en garde. Cela entraînera un débordement du conteneur, parce que #up le pousse vers le bas.

Vous pouvez donc ajouter overflow: hidden; au conteneur pour y remédier.

Par ailleurs, si la hauteur de #up est fixe, vous pouvez le positionner absolument dans le conteneur, et ajouter un padding-top à #down .

Une autre option consiste à utiliser un présentoir de table :

#container { width: 300px; height: 300px; border: 1px solid red; display: table;}
#up { background: green; display: table-row; height: 0; }
#down { background: pink; display: table-row;}​

24voto

Alvaro Points 293

Cela fait presque deux ans que j'ai posé cette question. Je viens de trouver css calc() qui résout le problème que j'avais et j'ai pensé qu'il serait bien de l'ajouter au cas où quelqu'un aurait le même problème. (D'ailleurs, j'ai fini par utiliser position absolute).

http://jsfiddle.net/S8g4E/955/

Voici la css

#up { height:80px;}
#down {
    height: calc(100% - 80px);//The upper div needs to have a fixed height, 80px in this case.
}

Pour plus d'informations, cliquez ici : http://css-tricks.com/a-couple-of-use-cases-for-calc/

Support des navigateurs : http://caniuse.com/#feat=calc

20voto

N. Kudryavtsev Points 811

Résumé

Je n'ai pas trouvé de réponse pleinement satisfaisante et j'ai donc dû la trouver moi-même.

Mes exigences :

  • l'élément doit prendre exactement l'espace restant, soit lorsque son taille du contenu es plus petit ou plus grand que les taille de l'espace restant (dans le second cas barre de défilement devrait être montré ) ;
  • la solution devrait fonctionner lorsque le la hauteur du parent est calculée y non spécifié ;
  • calc() ne doit pas être utilisé comme élément restant ne devrait rien savoir sur la taille d'un autre élément ;
  • moderne et technique de mise en page familière tels que flexboxes doit être utilisé.

La solution

  • Transformer en flexboxes tous les parents directs dont la taille a été calculée (le cas échéant) et le parent suivant dont la hauteur est spécifiée ;
  • Préciser flex-grow: 1 a tous les parents directs dont la taille a été calculée (le cas échéant) et l'élément de sorte qu'ils occupent tout l'espace restant lorsque la taille du contenu de l'élément est réduite ;
  • Préciser flex-shrink: 0 a tous les éléments flexibles avec une hauteur fixe afin qu'ils ne deviennent pas plus petits lorsque la taille du contenu de l'élément est supérieure à la taille de l'espace restant ;
  • Préciser overflow: hidden a tous les parents directs dont la taille a été calculée (le cas échéant) pour désactiver le défilement et interdire l'affichage d'un contenu débordant ;
  • Préciser overflow: auto a l'élément pour permettre le défilement à l'intérieur de celui-ci.

JSFiddle (l'élément a des parents directs dont la hauteur est calculée)

JSFiddle (cas simple : pas de parents directs avec hauteur calculée)

5voto

T.W.R.Cole Points 726

Ma réponse n'utilise que du CSS, et n'utilise pas overflow:hidden ou display:table-row. Elle exige que le premier enfant ait réellement une hauteur donnée, mais dans votre question, vous indiquez que seul le deuxième enfant doit avoir une hauteur non spécifiée, donc je pense que vous devriez trouver cela acceptable.

#container {
  width: 300px;
  height: 300px;
  border: 1px solid red;
}

#up {
  background: green;
  height: 63px;
  float: left;
  width: 100%
}

#down {
  background: pink;
  padding-top: 63px;
  height: 100%;
  box-sizing: border-box;
}

<div id="container">
  <div id="up">Text<br />Text<br />Text<br /></div>
  <div id="down">Text<br />Text<br />Text<br /></div>
</div>

2voto

Josh Mein Points 12352

Sauf erreur de ma part, vous pouvez simplement ajouter height: 100%; et overflow:hidden; a #down .

#down { 
    background:pink; 
    height:100%; 
    overflow:hidden;
}​

Démonstration en direct

Edit : Puisque vous ne voulez pas utiliser overflow:hidden; vous pouvez utiliser display: table; pour ce scénario ; cependant, il n'est pas pris en charge avant IE 8. ( display: table; soutien )

#container { 
    width: 300px; 
    height: 300px; 
    border:1px solid red;
    display:table;
}

#up { 
    background: green;
    display:table-row;
    height:0; 
}

#down { 
    background:pink;
    display:table-row;
}​

Démonstration en direct

Note : Vous avez dit que vous vouliez le #down hauteur à être #container hauteur moins #up hauteur. Les display:table; C'est exactement ce que fait la solution et ce jsfiddle le montrera très clairement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X