Faire un div remplir la hauteur de l'espace d'écran restant

1911

Je travaille sur une application web où je souhaite que le contenu remplisse la hauteur de tout l'écran.

La page a un en-tête, qui contient un logo et des informations de compte. Cela pourrait être une hauteur arbitraire. Je veux que la div de contenu remplisse le reste de la page vers le bas.

J'ai un en-tête divet un contenu div. En ce moment j'utilise un tableau pour la mise en page comme ceci:

CSS et HTML

#page {
    height: 100%; width: 100%
}

#tdcontent {
    height: 100%;
}

#content {
    overflow: auto; /* or overflow: hidden; */
}
<table id="page">
    <tr>
        <td id="tdheader">
            <div id="header">...</div>
        </td>
    </tr>
    <tr>
        <td id="tdcontent">
            <div id="content">...</div>
        </td>
    </tr>
</table>

La hauteur entière de la page est remplie et aucun défilement n'est requis.

Pour tout ce qui se trouve à l'intérieur de la division de contenu, le paramètre le top: 0;placera juste sous l'en-tête. Parfois, le contenu sera une vraie table, avec sa hauteur réglée à 100%. Mettre à l' headerintérieur contentne permettra pas que cela fonctionne.

Existe-t-il un moyen d'obtenir le même effet sans utiliser le table?

Mise à jour:

Les éléments à l'intérieur du contenu divauront également des hauteurs définies en pourcentages. Donc, quelque chose à 100% à l'intérieur le divremplira jusqu'au fond. De même que deux éléments à 50%.

Mise à jour 2:

Par exemple, si l'en-tête occupe 20% de la hauteur de l'écran, une table spécifiée à 50% à l'intérieur #contentoccuperait 40% de l'espace d'écran. Jusqu'à présent, envelopper le tout dans une table est la seule chose qui fonctionne.

Vincent McNabb
la source
31
Pour tous ceux qui trébucheront ici à l'avenir, vous pouvez obtenir la disposition de tableau souhaitée dans la plupart des navigateurs, sans le balisage du tableau, en utilisant display:tableles propriétés associées, voir cette réponse à une question très similaire.
AmeliaBR
3
J'ai essayé de recréer votre configuration - jsfiddle.net/ceELs - mais cela ne fonctionne pas, qu'est-ce qui me manque?
Gill Bates
5
@Monsieur. La réponse d'Alien est simple et utile, consultez-la http://stackoverflow.com/a/23323175/188784
Gohan
4
En fait, ce que vous décrivez ne fonctionne pas, même avec des tableaux: si le contenu prend plus d'espace vertical que la hauteur de l'écran, la cellule du tableau et l'ensemble du tableau se développeront au-delà du bas de l'écran. Débordement de votre contenu: auto ne fera pas apparaître de barre de défilement.
Damien
@GillBates cela fonctionnera une fois que vous aurez spécifié la hauteur de l'élément parent regardez sur jsfiddle.net/ceELs/5
Michal Vašut

Réponses:

1117

Mise à jour 2015: l'approche flexbox

Il y a deux autres réponses mentionnant brièvement Flexbox ; cependant, c'était il y a plus de deux ans, et ils ne fournissent aucun exemple. La spécification pour flexbox est définitivement établie.

Remarque: Bien que la spécification de disposition des boîtes flexibles CSS soit au stade de la recommandation du candidat, tous les navigateurs ne l'ont pas implémentée. L'implémentation de WebKit doit être préfixée avec -webkit-; Internet Explorer implémente une ancienne version de la spécification, préfixée avec -ms-; Opera 12.10 implémente la dernière version de la spécification, non préfixée. Consultez le tableau de compatibilité de chaque propriété pour un état de compatibilité à jour.

(extrait de https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes )

Tous les principaux navigateurs et IE11 + prennent en charge Flexbox. Pour IE 10 ou une version antérieure, vous pouvez utiliser la cale FlexieJS.

Pour vérifier le support actuel, vous pouvez également voir ici: http://caniuse.com/#feat=flexbox

Exemple de travail

Avec flexbox, vous pouvez facilement basculer entre n'importe laquelle de vos lignes ou colonnes ayant des dimensions fixes, des dimensions de contenu ou des dimensions d'espace restant. Dans mon exemple, j'ai défini l'en-tête pour qu'il s'aligne sur son contenu (conformément à la question OP), j'ai ajouté un pied de page pour montrer comment ajouter une région à hauteur fixe, puis définir la zone de contenu pour remplir l'espace restant.

html,
body {
  height: 100%;
  margin: 0;
}

.box {
  display: flex;
  flex-flow: column;
  height: 100%;
}

.box .row {
  border: 1px dotted grey;
}

.box .row.header {
  flex: 0 1 auto;
  /* The above is shorthand for:
  flex-grow: 0,
  flex-shrink: 1,
  flex-basis: auto
  */
}

.box .row.content {
  flex: 1 1 auto;
}

.box .row.footer {
  flex: 0 1 40px;
}
<!-- Obviously, you could use HTML5 tags like `header`, `footer` and `section` -->

<div class="box">
  <div class="row header">
    <p><b>header</b>
      <br />
      <br />(sized to content)</p>
  </div>
  <div class="row content">
    <p>
      <b>content</b>
      (fills remaining space)
    </p>
  </div>
  <div class="row footer">
    <p><b>footer</b> (fixed height)</p>
  </div>
</div>

Dans le CSS ci-dessus, la propriété flex raccourcit les propriétés flex-grow , flex-shrink et flex- based pour établir la flexibilité des éléments flex. Mozilla a une bonne introduction au modèle des boîtes flexibles .

Pebbl
la source
9
Pourquoi l' flex: 0 1 30px;attribut box .rowcar il est prioritaire dans chaque div?
Erdal G.15
11
Voici la prise en charge du navigateur pour flexbox - agréable de voir tout ce vert - caniuse.com/#feat=flexbox
Brian Burns
1
Le lien vers Flexie.js est mort. Voici le projet github github.com/doctyper/flexie
ses3ion
52
Certainement c'est une très bonne approche et ça marche presque;) Il y a un petit problème quand un contenu de div.content dépasse une hauteur flex-ed originale. Dans l'implémentation actuelle, le "footer" sera poussé plus bas et ce n'est pas ce que les développeurs attendent;) J'ai donc fait une correction très simple. jsfiddle.net/przemcio/xLhLuzf9/3 J'ai ajouté une flexion supplémentaire sur le conteneur et le défilement de débordement.
przemcio
12
@przemcio beau point, mais je ne pense pas avoir le contenu est ce que tous les scrollable attend des développeurs;) - vous ne devriez avoir besoin d'ajouter overflow-y: autoà .row.contentpour obtenir ce que vous devez cependant.
Pebbl
226

Il n'y a vraiment pas de méthode saine et multi-navigateur pour le faire en CSS. En supposant que votre mise en page est complexe, vous devez utiliser JavaScript pour définir la hauteur de l'élément. L'essence de ce que vous devez faire est:

Element Height = Viewport height - element.offset.top - desired bottom margin

Une fois que vous pouvez obtenir cette valeur et définir la hauteur de l'élément, vous devez attacher des gestionnaires d'événements à la fois à la fenêtre onload et à onresize afin de pouvoir déclencher votre fonction de redimensionnement.

En outre, en supposant que votre contenu soit plus volumineux que la fenêtre d'affichage, vous devrez définir overflow-y pour faire défiler.

NICCAI
la source
2
Voilà ce que je soupçonnais. Cependant, l'application fonctionnera également avec Javascript désactivé, donc je suppose que je continuerai à utiliser le tableau.
Vincent McNabb
6
Vincent, façon de tenir bon. Je cherchais à faire exactement la même chose et cela ne semble pas possible avec CSS? Je ne suis pas sûr, mais indépendamment des autres tonnes de solutions, faites ce que vous avez décrit. Le javascript est le seul qui fonctionne correctement à ce stade.
Travis
5
que faire si la hauteur de la fenêtre change
Techsin
4
Je veux dire ... pourquoi n'utilisons-nous pas calc en 2013?
kamii
4
hauteur: calc (100vh - 400px); est un style CSS valide qui fait exactement le sujet de cet article. Toutes les autres solutions reposent sur une hauteur parentale fixe ou un affichage de bloc.
WilliamX
167

Le message d'origine date de plus de 3 ans. Je suppose que de nombreuses personnes qui viennent à ce poste comme moi recherchent une solution de mise en page similaire à une application, par exemple un en-tête, un pied de page et un contenu pleine hauteur fixes occupant l'écran de repos. Si c'est le cas, ce message peut vous aider, il fonctionne sur IE7 +, etc.

http://blog.stevensanderson.com/2011/10/05/full-height-app-layouts-a-css-trick-to-make-it-easier/

Et voici quelques extraits de ce message:

@media screen { 
  
  /* start of screen rules. */ 
  
  /* Generic pane rules */
  body { margin: 0 }
  .row, .col { overflow: hidden; position: absolute; }
  .row { left: 0; right: 0; }
  .col { top: 0; bottom: 0; }
  .scroll-x { overflow-x: auto; }
  .scroll-y { overflow-y: auto; }

  .header.row { height: 75px; top: 0; }
  .body.row { top: 75px; bottom: 50px; }
  .footer.row { height: 50px; bottom: 0; }
  
  /* end of screen rules. */ 
}
<div class="header row" style="background:yellow;">
    <h2>My header</h2>
</div> 
<div class="body row scroll-y" style="background:lightblue;">
    <p>The body</p>
</div> 
<div class="footer row" style="background:#e9e9e9;">
    My footer
</div>

h - n
la source
74
Il n'y a qu'un seul problème: l'en-tête et le pied de page ne sont pas dimensionnés automatiquement. C'est la vraie difficulté, et c'est pourquoi une réponse "ce n'est pas possible" est actuellement au sommet ...
Roman Starkov
J'avais besoin d'un en-tête de 55 pixels et d'un div qui remplit le reste de la hauteur du document. c'est la solution!
Matías Cánepa
Vous êtes la bombe, j'essaye depuis si longtemps et c'est la seule solution que j'ai trouvée. J'avais besoin que mon élément de navigation ait une hauteur de 60 pixels en haut et le reste à 100%, cela l'a résolu.
Adam Waite
Cela fonctionne bien sauf que j'ai un léger problème - si je mets un élément display: tabledans le corps, il semble déborder le corps. Faire ainsi height: 100%ne produit pas la bonne hauteur.
GSTAR
4
.coln'est pas utilisé, n'est-ce pas?
slartidan
143

Au lieu d'utiliser des tables dans le balisage, vous pouvez utiliser des tables CSS.

Marquage

<body>    
    <div>hello </div>
    <div>there</div>
</body>

(Pertinent) CSS

body
{
    display:table;
    width:100%;
}
div
{
    display:table-row;
}
div+ div
{
    height:100%;  
}

FIDDLE1 et FIDDLE2

Certains avantages de cette méthode sont:

1) Moins de majoration

2) Le balisage est plus sémantique que les tableaux, car il ne s'agit pas de données tabulaires.

3) Le support du navigateur est très bon : IE8 +, tous les navigateurs et appareils mobiles modernes ( caniuse )


Juste pour être complet, voici les éléments Html équivalents aux propriétés css du modèle de table CSS

table    { display: table }
tr       { display: table-row }
thead    { display: table-header-group }
tbody    { display: table-row-group }
tfoot    { display: table-footer-group }
col      { display: table-column }
colgroup { display: table-column-group }
td, th   { display: table-cell }
caption  { display: table-caption } 
Danield
la source
3
je viens d'être pointé sur la technique des tables css . Il s'avère que la réponse était déjà dans cette question répondue. C'est la meilleure solution; propre, élégant et en utilisant l'outil exact de la manière exacte pour laquelle il a été conçu. Tables CSS
Ian Boyd
Le code du violon ne correspond pas tout à fait à la réponse ici. L'ajout a html, body { height: 100%, width: 100% }semblé critique dans mes tests.
mlibby
8
Une fonctionnalité ennuyeuse des tableaux CSS est exactement la même que celle des tableaux normaux: si le contenu est trop volumineux, ils développent la cellule pour s'adapter. Cela signifie que vous devrez peut-être encore limiter la taille (hauteur maximale) ou définir la hauteur à partir du code si la page est dynamique. Les grilles Silverlight me manquent vraiment! :(
Fin du codage le
3
Vous pouvez toujours ajouter un conteneur absolument positionné à l'intérieur de l'élément de ligne du tableau, puis définir sa largeur et sa hauteur à 100%. N'oubliez pas de définir également la position relative sur l'élément de ligne de table.
Mike Mellor
1
@MikeMellor ne fonctionne pas dans IE11, car il semble ignorer le relativepositionnement sur l' table-rowélément, il prend donc la hauteur du premier ascendant qui n'est pas un élément de table.
dwelle
96

Approche CSS uniquement (si la hauteur est connue / fixe)

Lorsque vous souhaitez que l'élément du milieu s'étende verticalement sur toute la page, vous pouvez utiliser calc()ce qui est introduit dans CSS3.

En supposant que nous ayons une hauteur header et des footeréléments fixes et que nous voulons que la sectionbalise prenne toute la hauteur verticale disponible ...

Démo

Le balisage supposé et votre CSS doivent être

html,
body {
  height: 100%;
}

header {
  height: 100px;
  background: grey;
}

section {
  height: calc(100% - (100px + 150px));
  /* Adding 100px of header and 150px of footer */
  background: tomato;
}

footer {
  height: 150px;
  background-color: blue;
}
<header>100px</header>
<section>Expand me for remaining space</section>
<footer>150px</footer>

Donc, ici, ce que je fais, c'est additionner la hauteur des éléments et déduire de l' 100%utilisation de la calc()fonction.

Assurez-vous simplement que vous utilisez height: 100%;pour les éléments parents.

Mr. Alien
la source
13
L'OP a déclaré que l'en-tête pouvait être d'une hauteur arbitraire. Donc, si vous ne connaissez pas la hauteur à l'avance, vous ne pourrez pas utiliser calc :(
Danield
1
@Danield C'est pourquoi j'ai mentionné la hauteur fixe :)
M. Alien
3
C'est la solution qui a fonctionné pour moi et ne m'a pas obligé à repenser mes pages existantes autour des flexbox. Si vous utilisez LESS, c'est-à-dire Bootstrap, assurez-vous de lire le message du coderwall sur la façon d'échapper à la fonction calc () afin que LESS ne le gère pas.
jlyonsmith
1
Op a déclaré: «Cela pourrait être une hauteur arbitraire». Moyens arbitraires décidés par le concepteur, ainsi fixés. Cette solution est de loin la meilleure.
jck
57

Utilisé: height: calc(100vh - 110px);

code:

  
.header { height: 60px; top: 0; background-color: green}
.body {
    height: calc(100vh - 110px); /*50+60*/
    background-color: gray;
}
.footer { height: 50px; bottom: 0; }
  
<div class="header">
    <h2>My header</h2>
</div> 
<div class="body">
    <p>The body</p>
</div> 
<div class="footer">
    My footer
</div>

nguyên
la source
1
À mon avis, la solution la plus propre. C'est mieux que d'ajouter du javascript, c'est sûr. (mais la réponse a déjà été publiée en 2015 par quelqu'un d'autre)
bvdb
cela semble beaucoup plus propre.
theprogrammer
45

Une solution simple, utilisant flexbox:

html,
body {
  height: 100%;
}

body {
  display: flex;
  flex-direction: column;
}

.content {
  flex-grow: 1;
}
<body>
  <div>header</div>
  <div class="content"></div>
</body>

Échantillon Codepen

Une solution alternative, avec un div centré dans le contenu div

zok
la source
4
C'est certainement la meilleure réponse. Fonctionne comme un charme pour les pages d'accueil de hero-img, ou un combo de hero-img avec votre barre de navigation
noobcoderiam
jsfiddle.net/31ng75du/5 Testé avec Chrome, FF, Edge, Vivaldi
user2360831
C'est simple et meilleur.
Dev Anand
38

Que diriez-vous d'utiliser simplement vhce qui signifie view heighten CSS ...

Regardez l' extrait de code que j'ai créé pour vous ci-dessous et exécutez-le:

body {
  padding: 0;
  margin: 0;
}

.full-height {
  width: 100px;
  height: 100vh;
  background: red;
}
<div class="full-height">
</div>

Regardez également l'image ci-dessous que j'ai créée pour vous:

Faire un div remplir la hauteur de l'espace d'écran restant

Alireza
la source
10
Ce n'est bon que si vous voulez qu'un div s'étende sur toute la hauteur de la fenêtre. Placez maintenant un div d'en-tête au-dessus avec une hauteur inconnue.
LarryBud
@ LarryBud vous avez raison, cela fait le div wrapper, donc tout devrait aller à l'intérieur de ce div ...
Alireza
34

CSS3 Simple Way

height: calc(100% - 10px); // 10px is height of your first div...

tous les principaux navigateurs les prennent en charge de nos jours, alors allez-y si vous n'avez pas besoin de prendre en charge les navigateurs vintage.

dev.meghraj
la source
4
Cela ne fonctionne pas si vous ne connaissez pas la hauteur des autres éléments (par exemple, s'ils contiennent un nombre variable d'éléments enfants).
Ege Ersoz
vous pouvez également utiliser 100vh, n'importe qui faisant cela: assurez-vous de mettre des espaces entre le moins et les éléments
htafoya
28

Cela pourrait être fait uniquement en CSSutilisant vh:

#page {
    display:block; 
    width:100%; 
    height:95vh !important; 
    overflow:hidden;
}

#tdcontent {
    float:left; 
    width:100%; 
    display:block;
}

#content {      
    float:left; 
    width:100%; 
    height:100%; 
    display:block; 
    overflow:scroll;
}

et le HTML

<div id="page">

   <div id="tdcontent"></div>
   <div id="content"></div>

</div>

Je l' ai vérifié, il fonctionne dans tous les principaux navigateurs: Chrome, IEetFireFox

Ormoz
la source
2
Wow, jamais entendu parler d' unités vhet vwavant. Plus d'infos: snook.ca/archives/html_and_css/vm-vh-units
Steve Bennett
Malheureusement, cela ne prend pas en charge IE8 :(
Scott
2
J'ai essayé cette approche, mais height: 100%on a #contentfait en sorte que sa hauteur corresponde à celle de #page, ignorant #tdcontentcomplètement la hauteur de. Avec beaucoup de contenu, la barre de défilement s'étend au-delà du bas de la page.
Brandon
28

Aucune des solutions publiées ne fonctionne lorsque vous avez besoin que le div inférieur défile lorsque le contenu est trop grand. Voici une solution qui fonctionne dans ce cas:

.table {
  display: table;
}

.table-row {
  display: table-row;
}

.table-cell {
  display: table-cell;
}

.container {
  width: 400px;
  height: 300px;
}

.header {
  background: cyan;
}

.body {
  background: yellow;
  height: 100%;
}

.body-content-outer-wrapper {
  height: 100%;
}

.body-content-inner-wrapper {
  height: 100%;
  position: relative;
  overflow: auto;
}

.body-content {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
<div class="table container">
  <div class="table-row header">
    <div>This is the header whose height is unknown</div>
    <div>This is the header whose height is unknown</div>
    <div>This is the header whose height is unknown</div>
  </div>
  <div class="table-row body">
    <div class="table-cell body-content-outer-wrapper">
      <div class="body-content-inner-wrapper">
        <div class="body-content">
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
        </div>
      </div>
    </div>
  </div>
</div>

Source d'origine: Remplir la hauteur restante d'un conteneur tout en gérant le débordement en CSS

Aperçu en direct de JSFiddle

John Kurlak
la source
Je vous remercie!!! J'ai essayé toutes les réponses non-table, non-flexbox, et c'est la seule qui fonctionnait à 100% correctement. Une question: la source d'origine n'en a qu'un body-content-wrapper, et les choses semblent bien fonctionner sans le double wrapper (sans aucun table-cells). Y a-t-il un problème à le faire de cette façon?
Brandon
1
@BrandonMintern Si vous n'avez pas les cellules du tableau, cela ne fonctionne pas dans IE8 et IE9. (Voir le commentaire dans l'article d'origine.)
John Kurlak
Oui, les cellules sont également requises dans IE10. Malheureusement, dans IE10 et moins, la .bodyhauteur finit par être la même hauteur que celle définie .container. La barre de défilement verticale est toujours au bon endroit, mais les .containerextrémités deviennent plus grandes que nous le souhaitons. Lorsqu'il est en plein écran, .bodyle bas de l'écran est en bas de l'écran.
Brandon
Merci, @JohnKurlak. C'est la seule solution qui a fonctionné dans ma situation (la manière flexbox a été bloquée par un comportement buggy dans une version particulière de Chrome utilisée par mon client)
Maksym Demidas
Saint ****! Je cherche cette réponse depuis si longtemps! Merci beaucoup. Flexbox ne fonctionnait pas ici, mais les cellules de tableau fonctionnaient effectivement. Incroyable.
aabbccsmith
25

J'ai également cherché une réponse à cela. Si vous avez la chance de pouvoir cibler IE8 et versions ultérieures, vous pouvez utiliser display:tableles valeurs associées pour obtenir les règles de rendu des tableaux avec des éléments de niveau bloc, y compris div.

Si vous êtes encore plus chanceux et que vos utilisateurs utilisent des navigateurs de premier plan (par exemple, s'il s'agit d'une application intranet sur des ordinateurs que vous contrôlez, comme mon dernier projet), vous pouvez utiliser la nouvelle disposition de boîte flexible en CSS3!

Chris
la source
22

Ce qui a fonctionné pour moi (avec un div dans un autre div et je suppose dans toutes les autres circonstances) est de régler le rembourrage inférieur à 100%. Autrement dit, ajoutez ceci à votre feuille de style / CSS:

padding-bottom: 100%;
Tonye - True Vine Productions
la source
14
100% de quoi? Si j'essaye, j'obtiens un immense espace vide et le défilement commence à se produire.
mlibby
100% de la taille de la fenêtre peut être @mlibby. Si vous définissez également votre html et votre corps à 100% de hauteur, le div peut aller à 100%. Avec une seule div, le 100% sera relatif au contenu de la div. Je ne l'ai pas essayé avec un div imbriqué.
Jess
1
Cela signifie 100% de la hauteur de l'élément (ajouté comme rembourrage de l'élément), ce qui lui fait doubler la hauteur. Aucune assurance qu'il remplira la page, et certainement pas la réponse à la question. Elle peut déjà, comme déjà notet, remplir plus que la fenêtre d'affichage.
Martin
2
padding-bottom: 100% définit la hauteur + 100% de la largeur du
Romeno
1
from w3school: Spécifie un remplissage inférieur en pourcentage de la largeur de l'élément. w3schools.com/cssref/pr_padding-bottom.asp
mehdi.loa
21

Avertissement: La réponse acceptée donne l'idée de la solution, mais je la trouve un peu gonflée par un wrapper inutile et des règles CSS. Voici une solution avec très peu de règles CSS.

HTML 5

<body>
    <header>Header with an arbitrary height</header>
    <main>
        This container will grow so as to take the remaining height
    </main>
</body>

CSS

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;       /* body takes whole viewport's height */
}

main {
  flex: 1;                 /* this will make the container take the free space */
}

La solution ci-dessus utilise des unités de fenêtre et une boîte flexible , et est donc IE10 +, à condition que vous utilisiez l'ancienne syntaxe pour IE10.

Codepen pour jouer avec: lien vers codepen

Ou celui-ci, pour ceux qui ont besoin que le conteneur principal défile en cas de contenu débordant: lien vers codepen

Michael P. Bazos
la source
principal {hauteur: 10px; flex: 1; débordement: auto}
Naeem Baghi
2
Après avoir perdu des heures et testé plusieurs approches, celle-ci était la meilleure! C'est concis, simple et intelligent.
marciowb
19

Il y a une tonne de réponses maintenant, mais j'ai trouvé utile height: 100vh;de travailler sur l'élément div qui doit remplir tout l'espace vertical disponible.

De cette façon, je n'ai pas besoin de jouer avec l'affichage ou le positionnement. Cela s'est avéré utile lors de l'utilisation de Bootstrap pour créer un tableau de bord dans lequel j'avais une barre latérale et une principale. Je voulais que le principal s'étire et remplisse tout l'espace vertical afin que je puisse appliquer une couleur d'arrière-plan.

div {
    height: 100vh;
}

Prend en charge IE9 et plus: cliquez pour voir le lien

puiu
la source
14
Mais 100vh sonne comme toute la hauteur, pas la hauteur restante. Et si vous avez un en-tête et que vous voulez remplir le reste
Epirocks
14
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<style type="text/css">
body
,html
{
    height: 100%;
    margin: 0;
    padding: 0;
    color: #FFF;
}

#header
{
    float: left;
    width: 100%;
    background: red;
}

#content
{
    height: 100%;
    overflow: auto;
    background: blue;
}

</style>
</head>
<body>

    <div id="content">
        <div id="header">
                Header
                <p>Header stuff</p>
        </div>
            Content
            <p>Content stuff</p>
    </div>

</body>
</html>

Dans tous les navigateurs sensés, vous pouvez placer le div "en-tête" avant le contenu, en tant que frère et sœur, et le même CSS fonctionnera. Cependant, IE7- n'interprète pas correctement la hauteur si le flottant est à 100% dans ce cas, donc l'en-tête doit être dans le contenu, comme ci-dessus. Le débordement: auto entraînera des barres de défilement doubles sur IE (qui a toujours la barre de défilement de la fenêtre visible, mais désactivée), mais sans cela, le contenu se coupera s'il déborde.

Jerph
la source
Proche! Presque ce que je veux, sauf que je vais avoir d'autres choses positionnées dans le div... c'est top: 0;-à- dire mettre quelque chose juste en dessous de l'en-tête. Je vais encore modifier ma question, car vous y avez parfaitement répondu, et toujours pas ce que je veux! Je vais juste cacher le débordement car le contenu doit s'adapter.
Vincent McNabb
-1: Cette réponse crée un div appelé contenu qui couvre tout l'écran, pas le reste de l'écran
Casebash
11

J'ai lutté avec cela pendant un certain temps et je me suis retrouvé avec ce qui suit:

Puisqu'il est facile de faire le contenu DIV de la même hauteur que le parent mais apparemment difficile de le faire la hauteur du parent moins la hauteur de l'en-tête, j'ai décidé de faire le contenu div pleine hauteur mais le positionner absolument dans le coin supérieur gauche et puis définir un rembourrage pour le haut qui a la hauteur de l'en-tête. De cette façon, le contenu s'affiche proprement sous l'en-tête et remplit tout l'espace restant:

body {
    padding: 0;
    margin: 0;
    height: 100%;
    overflow: hidden;
}

#header {
    position: absolute;
    top: 0;
    left: 0;
    height: 50px;
}

#content {
    position: absolute;
    top: 0;
    left: 0;
    padding-top: 50px;
    height: 100%;
}
B_G
la source
15
Et si vous ne connaissez pas la hauteur de l'en-tête?
Yugal Jindle
11

Si vous ne parvenez pas à prendre en charge les anciens navigateurs (c'est-à-dire MSIE 9 ou plus ancien), vous pouvez le faire avec Flexible Box Layout Module qui est déjà W3C CR. Ce module permet également d'autres astuces intéressantes, telles que la réorganisation du contenu.

Malheureusement, MSIE 9 ou moins ne prend pas en charge cela et vous devez utiliser le préfixe du fournisseur pour la propriété CSS pour chaque navigateur autre que Firefox. Espérons que d'autres fournisseurs abandonneront bientôt le préfixe également.

Un autre choix serait la disposition de grille CSS, mais qui a encore moins de support des versions stables des navigateurs. En pratique, seul MSIE 10 le prend en charge.

Mise à jour de l'année 2020 : tous les navigateurs modernes prennent en charge à la fois display: flexet display: grid. Le seul manquant est le support pour subgridlequel n'est pris en charge que par Firefox. Notez que MSIE ne prend pas en charge non plus la spécification, mais si vous êtes prêt à ajouter des hacks CSS spécifiques à MSIE, il peut être fait pour se comporter. Je suggérerais simplement d'ignorer MSIE car même Microsoft dit qu'il ne devrait plus être utilisé.

Mikko Rantalainen
la source
10

Solution de grille CSS

Il suffit de définir les propriétés bodywith display:gridet grid-template-rowsusing autoet frvalue.

* {
  margin: 0;
  padding: 0;
}

html {
  height: 100%;
}

body {
  min-height: 100%;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

header {
  padding: 1em;
  background: pink;
}

main {
  padding: 1em;
  background: lightblue;
}

footer {
  padding: 2em;
  background: lightgreen;
}

main:hover {
  height: 2000px;
  /* demos expansion of center element */
}
<header>HEADER</header>
<main>MAIN</main>
<footer>FOOTER</footer>

Un guide complet des grilles @ CSS-Tricks.com

Paulie_D
la source
9

Pourquoi pas comme ça?

html, body {
    height: 100%;
}

#containerInput {
    background-image: url('../img/edit_bg.jpg');
    height: 40%;
}

#containerControl {
    background-image: url('../img/control_bg.jpg');
    height: 60%;
}

Vous donner une taille html et corps (dans cet ordre) et ensuite juste donner une hauteur à vos éléments?

Travaille pour moi

Thaoms
la source
Le fait est que si un utilisateur utilise un grand écran pour consulter cette page et que la hauteur de votre en-tête est fixée exactement à 100 pixels, ce qui est inférieur à 40% de la hauteur actuelle, il y aura un grand espace vide entre votre en-tête et le contexte du corps.
Saorikido
8

Vous pouvez réellement utiliser display: tablepour diviser la zone en deux éléments (en-tête et contenu), où l'en-tête peut varier en hauteur et le contenu remplit l'espace restant. Cela fonctionne avec la page entière, ainsi que lorsque la zone est simplement le contenu d'un autre élément positionné avec positiondéfini sur relative, absoluteou fixed. Cela fonctionnera tant que l'élément parent aura une hauteur non nulle.

Voir ce violon et aussi le code ci-dessous:

CSS:

body, html {
    height: 100%;
    margin: 0;
    padding: 0;
}

p {
    margin: 0;
    padding: 0;
}

.additional-padding {
    height: 50px;
    background-color: #DE9;
}

.as-table {
    display: table;
    height: 100%;
    width: 100%;
}

.as-table-row {
    display: table-row;
    height: 100%;
}

#content {
    width: 100%;
    height: 100%;
    background-color: #33DD44;
}

HTML:

<div class="as-table">
    <div id="header">
        <p>This header can vary in height, it also doesn't have to be displayed as table-row. It will simply take the necessary space and the rest below will be taken by the second div which is displayed as table-row. Now adding some copy to artificially expand the header.</p>
        <div class="additional-padding"></div>
    </div>
    <div class="as-table-row">
        <div id="content">
            <p>This is the actual content that takes the rest of the available space.</p>
        </div>
    </div>
</div>
Greg
la source
2
Une bonne réponse, que j'ai votée positivement, mais malheureusement, ne fonctionne pas avec IE8, qui sera toujours là pour longtemps.
Vincent McNabb
Des applications comme Gmail utilisent Javascript pour le dimensionnement, ce qui est une meilleure solution que CSS dans la plupart des cas.
Vincent McNabb
Je pense qu'ils utilisent Javascript parce qu'il n'y a pas d'autre bonne solution CSS multi-navigateur, pas parce que c'est mieux.
Greg
1
@VincentMcNabb Fonctionne dans IE8 w3schools.com/cssref/pr_class_display.asp . Nécessite juste une déclaration DOCTYPE. Jamais même connu une valeur de table pour l'attribut d'affichage. Solution cool. +1
Govind Rai
8
 style="height:100vh"

résolu le problème pour moi. Dans mon cas, j'ai appliqué cela à la div requise

Zohab Ali
la source
6

Vincent, je répondrai à nouveau en utilisant vos nouvelles exigences. Comme vous ne vous souciez pas du contenu caché s'il est trop long, vous n'avez pas besoin de faire flotter l'en-tête. Mettez simplement le débordement caché sur les balises html et body, et réglez la #contenthauteur à 100%. Le contenu sera toujours plus long que la fenêtre d'affichage par la hauteur de l'en-tête, mais il sera masqué et ne provoquera pas de barres de défilement.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Test</title>
    <style type="text/css">
    body, html {
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
      color: #FFF;
    }
    p {
      margin: 0;
    }

    #header {
      background: red;
    }

    #content {
      position: relative;
      height: 100%;
      background: blue;
    }

    #content #positioned {
      position: absolute;
      top: 0;
      right: 0;
    }
  </style>
</head>

<body>
  <div id="header">
    Header
    <p>Header stuff</p>
  </div>

  <div id="content">
    Content
    <p>Content stuff</p>
    <div id="positioned">Positioned Content</div>
  </div>

</body>
</html>
Jerph
la source
Déjà pensé à ça. Mais ça ne marche pas non plus. Je vais juste m'en tenir à tableça parce que ça marche. Merci pour la mise à jour.
Vincent McNabb
5

Essaye ça

var sizeFooter = function(){
    $(".webfooter")
        .css("padding-bottom", "0px")
        .css("padding-bottom", $(window).height() - $("body").height())
}
$(window).resize(sizeFooter);
Arun
la source
4

J'ai trouvé une solution assez simple, car pour moi, c'était juste un problème de conception. Je voulais que le reste de la page ne soit pas blanc sous le pied de page rouge. J'ai donc mis la couleur d'arrière-plan des pages en rouge. Et la couleur de fond du contenu au blanc. Avec la hauteur du contenu réglée par ex. 20em ou 50% une page presque vide ne laissera pas la page entière rouge.

htho
la source
4

J'ai eu le même problème mais je n'ai pas pu faire fonctionner la solution avec les flexbox ci-dessus. J'ai donc créé mon propre modèle, qui comprend:

  • un en-tête avec un élément de taille fixe
  • un pied de page
  • une barre latérale avec une barre de défilement qui occupe la hauteur restante
  • contenu

J'ai utilisé des boîtes flexibles mais de manière plus simple, en utilisant uniquement les propriétés display: flex et flex-direction: row | column :

J'utilise angulaire et je veux que la taille de mes composants soit à 100% de leur élément parent.

La clé est de définir la taille (en pourcentage) pour tous les parents afin de limiter leur taille. Dans l'exemple suivant, la hauteur myapp a 100% de la fenêtre d'affichage.

Le composant principal a 90% de la fenêtre, car l'en-tête et le pied de page en ont 5%.

J'ai posté mon modèle ici: https://jsfiddle.net/abreneliere/mrjh6y2e/3

       body{
        margin: 0;
        color: white;
        height: 100%;
    }
    div#myapp
    {
        display: flex;
        flex-direction: column;
        background-color: red; /* <-- painful color for your eyes ! */
        height: 100%; /* <-- if you remove this line, myapp has no limited height */
    }
    div#main /* parent div for sidebar and content */
    {
        display: flex;
        width: 100%;
        height: 90%; 
    }
    div#header {
        background-color: #333;
        height: 5%;
    }
    div#footer {
        background-color: #222;
        height: 5%;
    }
    div#sidebar {
        background-color: #666;
        width: 20%;
        overflow-y: auto;
     }
    div#content {
        background-color: #888;
        width: 80%;
        overflow-y: auto;
    }
    div.fized_size_element {
        background-color: #AAA;
        display: block;
        width: 100px;
        height: 50px;
        margin: 5px;
    }

Html:

<body>
<div id="myapp">
    <div id="header">
        HEADER
        <div class="fized_size_element"></div>

    </div>
    <div id="main">
        <div id="sidebar">
            SIDEBAR
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
        </div>
        <div id="content">
            CONTENT
        </div>
    </div>
    <div id="footer">
        FOOTER
    </div>
</div>
</body>
Anthony Brenelière
la source
4

Pour l'application mobile, j'utilise uniquement VH et VW

<div class="container">
  <div class="title">Title</div>
  <div class="content">Content</div>
  <div class="footer">Footer</div>
</div>

.container {
  width: 100vw;
  height: 100vh;
  font-size: 5vh;
}

.title {
  height: 20vh;
  background-color: red;
}

.content {
  height: 60vh;
  background: blue;
}

.footer {
  height: 20vh;
  background: green;
}

Démo - https://jsfiddle.net/u763ck92/

grinmax
la source
3
Ce n'est pas la bonne solution. vh est incohérent dans les navigateurs mobiles. Voir ici pour plus de détails: stackoverflow.com/questions/37112218/…
HarshMarshmallow
3

Filer l'idée de M. Alien ...

Cela semble une solution plus propre que la boîte de flexion populaire pour les navigateurs compatibles CSS3.

Utilisez simplement min-height (au lieu de height) avec calc () pour le bloc de contenu.

Le calc () commence à 100% et soustrait les hauteurs des en-têtes et pieds de page (doit inclure des valeurs de remplissage)

L'utilisation de "min-height" au lieu de "height" est particulièrement utile pour pouvoir fonctionner avec du contenu rendu javascript et des frameworks JS comme Angular2. Sinon, le calcul ne poussera pas le pied de page vers le bas de la page une fois que le contenu rendu en javascript est visible.

Voici un exemple simple d'en-tête et de pied de page utilisant une hauteur de 50 pixels et un rembourrage de 20 pixels pour les deux.

Html:

<body>
    <header></header>
    <div class="content"></div>
    <footer></footer>
</body>

Css:

.content {
    min-height: calc(100% - (50px + 20px + 20px + 50px + 20px + 20px));
}

Bien sûr, les calculs peuvent être simplifiés mais vous avez l'idée ...

Pat M
la source
3

Dans Bootstrap:

Styles CSS:

html, body {
    height: 100%;
}

1) Remplissez simplement la hauteur de l'espace d'écran restant:

<body class="d-flex flex-column">
  <div class="d-flex flex-column flex-grow-1>

    <header>Header</header>
    <div>Content</div>
    <footer class="mt-auto">Footer</footer>

  </div>
</body>

! [entrez la description de l'image ici


2) remplissez la hauteur de l'espace d'écran restant et alignez le contenu au milieu de l'élément parent:

<body class="d-flex flex-column">
  <div class="d-flex flex-column flex-grow-1">

    <header>Header</header>
    <div class="d-flex flex-column flex-grow-1 justify-content-center">Content</div>
    <footer class="mt-auto">Footer</footer>

  </div>
</body>

! [entrez la description de l'image ici

gadolf
la source
1

Ceci est ma propre version minimale de la solution de Pebbl. Il a fallu une éternité pour trouver l'astuce pour le faire fonctionner dans IE11. (Également testé dans Chrome, Firefox, Edge et Safari.)

<!DOCTYPE html>
<html>
<head>
<style>
html {
    height: 100%;
    }
body {
    height: 100%;
    margin: 0;
    }
section {
    display: flex;
    flex-direction: column;
    height: 100%;
    }
div:first-child {
    background: gold;
    }
div:last-child {
    background: plum;
    flex-grow: 1;
    }
</style>
</head>
<body>
    <section>
      <div>FIT</div>
      <div>GROW</div>
    </section>
</body>
</html>
Michael Schade
la source