web-dev-qa-db-fra.com

CSS - pourquoi le pourcentage de hauteur ne fonctionne-t-il pas?

Comment se fait-il qu'une valeur de pourcentage pour height ne fonctionne pas mais qu'une valeur de pourcentage pour width fonctionne?

Par exemple :

<div id="working"></div>
<div id="not-working"></div>
#working{
    width:80%;
    height:140px;
    background:orange;
}
#not-working{
    width:80%;
    height:30%;
    background:green;
}

La largeur de #working finit par représenter 80% de la fenêtre d'affichage, mais la hauteur de #not-working finit par être 0.

217
Web_Designer

La hauteur d'un élément de bloc correspond par défaut à la hauteur du contenu du bloc. Donc, étant donné quelque chose comme ça:

<div id="outer">
    <div id="inner">
        <p>Where is pancakes house?</p>
    </div>
</div>

#inner deviendra suffisamment grand pour contenir le paragraphe et #outer deviendra suffisamment grand pour contenir #inner.

Lorsque vous spécifiez la hauteur ou la largeur sous forme de pourcentage, il s'agit d'un pourcentage par rapport au parent de l'élément. Dans le cas de la largeur, tous les éléments de bloc sont, sauf indication contraire, aussi larges que leur parent, jusqu'à <html>; ainsi, la largeur d'un élément de bloc est indépendante de son contenu et dire width: 50% donne un nombre bien défini de pixels.

Cependant, la hauteur d'un élément de bloc dépend de son conten sauf si vous spécifiez une hauteur spécifique. Il y a donc une rétroaction entre le parent et l'enfant en ce qui concerne la hauteur et dire height: 50% ne produit pas de valeur bien définie, sauf si vous cassez la boucle de rétroaction en donnant à l'élément parent une hauteur spécifique.

325
mu is too short

Une valeur de pourcentage dans une propriété height a quelques complications, et les propriétés width et height se comportent différemment. Laissez-moi vous faire visiter les spécifications.

height propriété:

Regardons ce que la spécification CSS Snapshot 2010 dit à propos de height :

Le pourcentage est calculé par rapport à la hauteur de la boîte générée bloc contenant. Si la hauteur du bloc contenant n'est pas spécifiée explicitement (c'est-à-dire qu'elle dépend de la hauteur du contenu) et que cet élément n'est pas positionné de manière absolue, la valeur est calculée sur 'auto'. Un pourcentage de hauteur sur l'élément racine est relatif au bloc contenant initial. Remarque: Pour les éléments en position absolue dont le bloc conteneur est basé sur un élément de niveau bloc, le pourcentage est calculé par rapport à la hauteur de la zone de remplissage de cet élément.

OK, démontons cela étape par étape:

Le pourcentage est calculé par rapport à la hauteur de la boîte générée bloc contenant.

Qu'est-ce qu'un bloc contenant ? C'est un peu compliqué, mais pour un élément normal dans la position par défaut static, c'est:

la boîte ancêtre du conteneur de bloc la plus proche

ou en anglais, sa boîte parente. (Cela vaut également la peine de savoir ce que ce serait pour les positions fixed et absolute, mais j'ignore cela pour que cette réponse soit brève.)

Alors prenons ces deux exemples:

<div   id="a"  style="width: 100px; height: 200px; background-color: orange">
  <div id="aa" style="width: 100px; height: 50%;   background-color: blue"></div>
</div>
<div   id="b"  style="width: 100px;              background-color: orange">
  <div id="bb" style="width: 100px; height: 50%; background-color: blue"></div>
</div>

Dans cet exemple, le bloc conteneur de #aa est #a, et ainsi de suite pour #b et #bb. Jusqu'ici tout va bien.

La phrase suivante de la spécification pour height est la complication que j'ai mentionnée dans l'introduction de cette réponse:

Si la hauteur du bloc contenant n'est pas spécifiée explicitement (c'est-à-dire que cela dépend de la hauteur du contenu) et que cet élément n'est pas absolument positionné, la valeur se calcule en 'auto' .

Aha! Que la hauteur du bloc contenant ait été spécifiée soit explicite!

  • 50% de height:200px est 100px dans le cas de #aa
  • Mais 50% de height:auto est auto, ce qui correspond à 0px dans le cas de #bb puisqu'il n'y a pas de contenu pour auto à développer

Comme le spécifie la spécification, il importe également de savoir si le bloc conteneur a été positionné de manière absolue ou non, mais passons à width.

width propriété:

Cela fonctionne-t-il de la même manière pour width? Jetons un coup d'oeil à la spécification :

Le pourcentage est calculé par rapport à la largeur du bloc contenant de la boîte générée.

Jetez un oeil à ces exemples familiers, modifiés à partir du précédent pour faire varier width au lieu de height:

<div   id="c"  style="width: 200px; height: 100px; background-color: orange">
  <div id="cc" style="width: 50%;   height: 100px; background-color: blue"></div>
</div>
<div   id="d"  style="            height: 100px; background-color: orange">
  <div id="dd" style="width: 50%; height: 100px; background-color: blue"></div>
</div>
  • 50% de width:200px est 100px dans le cas de #cc
  • 50% de width:auto correspond à 50% de ce que width:auto finit par être, contrairement à height, il n'y a pas de règle spéciale traitant ce cas différemment.

Maintenant, voici le point le plus compliqué: auto signifie différentes choses, en partie selon que cela a été spécifié pour width ou height! Pour height, cela signifiait simplement que la hauteur devait correspondre au contenu *, mais pour width, auto est en réalité plus compliqué. Vous pouvez voir dans l'extrait de code que dans ce cas, il s'agit de la largeur de la fenêtre.

Qu'est-ce que la spécification dit à propos de la valeur automatique de width ?

La largeur dépend des valeurs des autres propriétés. Voir les sections ci-dessous.

Wahey, ce n'est pas utile. Pour vous épargner le problème, je vous ai trouvé la section pertinente de notre cas d'utilisation intitulée "Calcul des largeurs et des marges", sous-titrée "Éléments de niveau bloc non remplacés dans un flux normal" :

Les contraintes suivantes doivent être respectées parmi les valeurs utilisées des autres propriétés:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = largeur du bloc conteneur

OK, donc width plus la marge, les bordures et les bordures de remplissage appropriées doivent toutes s’ajouter à la largeur du bloc conteneur (not ​​descendants comme height fonctionne). Juste une phrase supplémentaire:

Si "width" est réglé sur "auto", toutes les autres valeurs "auto" deviennent "0" et "width" découle de l'égalité résultante.

Aha! Donc dans ce cas, 50% de width:auto représente 50% de la fenêtre d'affichage. Espérons que tout a enfin un sens maintenant!


Notes de bas de page

* Du moins, dans la mesure où cela compte dans ce cas. spec Très bien, tout ce qui a un sens a du sens maintenant.

117
Flimm

Je pense que vous devez simplement lui donner un conteneur parent ... même si la hauteur de ce conteneur est définie en pourcentage. Cela semble fonctionner parfaitement: JSFiddle

html, body { 
    margin: 0; 
    padding: 0; 
    width: 100%; 
    height: 100%;
}
.wrapper { 
    width: 100%; 
    height: 100%; 
}
.container { 
    width: 100%; 
    height: 50%; 
}
10
David Martins

Vous devez lui donner un conteneur avec une hauteur. width utilise la fenêtre comme largeur par défaut

7
swider

Une autre option consiste à ajouter du style à div

<div style="position: absolute; height:somePercentage%; overflow:auto(or other overflow value)">
 //to be scrolled 
</div>

Et cela signifie qu'un élément est positionné par rapport à l'ancêtre le plus proche.

5
Niv Kremer

Sans contenu, la hauteur n'a pas de valeur pour calculer le pourcentage de. La largeur, cependant, prendra le pourcentage du DOM, si aucun parent n'est spécifié. (En utilisant votre exemple) Placer la deuxième div à l'intérieur de la première div aurait rendu un résultat ... exemple ci-dessous ...

<div id="working">
  <div id="not-working"></div>
</div>

La deuxième division représenterait 30% de la hauteur de la première division.

2
the code war