web-dev-qa-db-fra.com

CSS: Définition de la largeur / hauteur en pourcentage moins les pixels

J'essaie de créer des classes CSS réutilisables pour plus de cohérence et moins d'encombrement sur mon site, et je ne peux pas essayer de normaliser une chose que j'utilise fréquemment.

J'ai un conteneur <div> pour lequel je ne souhaite pas définir de hauteur (car il varie en fonction de l'emplacement sur le site), et à l'intérieur de celui-ci se trouve un en-tête <div>, puis un liste non ordonnée d'éléments, tous avec CSS appliqués.

Cela ressemble beaucoup à ceci:

Widget

Je veux que liste non ordonnée occupe la place restante dans le conteneur <div>, sachant que l'en-tête <div> est 18px tall. Je ne sais tout simplement pas comment spécifier la hauteur de la liste comme "le résultat de 100% moins 18px".

J'ai vu cette question posée dans un couple d'autres contextes sur SO, mais j'ai pensé qu'il serait intéressant de demander à nouveau pour mon cas particulier. Quelqu'un at-il des conseils dans cette situation?

445
MegaMatt

Je sais que c’est un vieux billet, mais vu que cela n’a pas été suggéré, il est utile de mentionner que si vous écrivez pour des navigateurs compatibles CSS3, vous pouvez utiliser calc:

height: calc(100% - 18px);

Cela vaut la peine de noter que tous les navigateurs ne supportent pas actuellement la fonction standard CSS3 calc (). Il peut donc être nécessaire d'implémenter les versions spécifiques de navigateur de la fonction, comme suit:

/* Firefox */
height: -moz-calc(100% - 18px);
/* WebKit */
height: -webkit-calc(100% - 18px);
/* Opera */
height: -o-calc(100% - 18px);
/* Standard */
height: calc(100% - 18px);
828
Levi Botelho

Pour une approche légèrement différente, vous pouvez utiliser quelque chose comme ceci sur la liste:

position: absolute;
top: 18px;
bottom: 0px;
width: 100%;

Cela fonctionne tant que le conteneur parent a position: relative;

70
Nicolas Galler

J'utilise Jquery pour cela

function setSizes() {
   var containerHeight = $("#listContainer").height();
   $("#myList").height(containerHeight - 18);
}

puis je lie la fenêtre redimensionner pour la recalculer chaque fois que la fenêtre du navigateur est redimensionnée (si la taille du conteneur a été modifiée avec redimensionnement de la fenêtre)

$(window).resize(function() { setSizes(); });
25
puffpio

Ne définissez pas la hauteur sous forme de pourcentage, définissez simplement top=0 et bottom=0, comme suit:

#div {
   top: 0; bottom: 0;
   position: absolute;
   width: 100%;
}
16
kaleazy

Hauteur d'en-tête de 17px

Liste css:

height: 100%;
padding-top: 17px;

En-tête css:

height: 17px;
float: left;
width: 100%;
8
ghoppe
  1. Utilisez des marges négatives sur l'élément que vous souhaitez minimiser les pixels. (élément souhaité)
  2. Faire overflow:hidden; sur l'élément contenant
  3. Passez à overflow:auto; sur l'élément souhaité.

Cela a fonctionné pour moi!

7
desbest

Essayez la taille de la boîte. Pour la liste:

height: 100%;
/* Presuming 10px header height */
padding-top: 10px;
/* Firefox */
-moz-box-sizing: border-box;
/* WebKit */
-webkit-box-sizing: border-box;
/* Standard */
box-sizing: border-box;

Pour l'en-tête:

position: absolute;
left: 0;
top: 0;
height: 10px;

Bien sûr, le conteneur parent devrait avoir quelque chose comme:

position: relative;
5
Light

J'ai essayé d'autres réponses et aucune d'entre elles n'a fonctionné comme je le voulais. Notre situation était très similaire où nous avions un en-tête de fenêtre et la fenêtre était redimensionnable avec des images dans le corps de la fenêtre. Nous voulions verrouiller les proportions du redimensionnement sans avoir à ajouter de calculs pour tenir compte de la taille fixe de l'en-tête tout en maintenant l'image remplissant le corps de la fenêtre.

Ci-dessous, j'ai créé un extrait très simple qui montre ce que nous avons fini par faire et qui semble bien fonctionner pour notre situation et devrait être compatible avec la plupart des navigateurs.

Sur notre élément de fenêtre, nous avons ajouté une marge de 20 pixels qui contribue au positionnement par rapport aux autres éléments de l'écran, mais ne contribue pas à la "taille" de la fenêtre. L'en-tête de fenêtre est alors positionné de manière absolue (ce qui le supprime du flux des autres éléments, afin de ne pas déplacer d'autres éléments tels que la liste non ordonnée) et son sommet est positionné à -20px, ce qui place l'en-tête à l'intérieur de la marge. de la fenêtre. Enfin, notre élément ul est ajouté à la fenêtre et la hauteur peut être réglée à 100%, ce qui l'amènera à remplir le corps de la fenêtre (à l'exclusion de la marge).

*,*:before,*:after
{
  box-sizing: border-box;
}

.window
{
  position: relative;
  top: 20px;
  left: 50px;
  margin-top: 20px;
  width: 150px;
  height: 150px;
}

.window-header
{
  position: absolute;
  top: -20px;
  height: 20px;
  border: 2px solid black;
  width: 100%;
}

ul
{
  border: 5px dashed gray;
  height: 100%;
}
<div class="window">
  <div class="window-header">Hey this is a header</div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
  </ul>
</div>
2
TJ Rockefeller

Merci, j'ai résolu le mien avec votre aide, le peaufinant un peu puisque je veux un div 100% largeur 100% hauteur (moins de hauteur d'une barre inférieure) et pas de défilement sur le corps (sans barres de défilement hack/cache).

Pour CSS:

 html{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 body{
  position:relative;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 div.adjusted{
  position:absolute;width:auto;height:auto;left:0px;right:0px;top:0px;bottom:36px;margin:0px;border:0px;padding:0px;
 }
 div.the_bottom_bar{
  width:100%;height:31px;margin:0px;border:0px;padding:0px;
}

Pour HTML:

<body>
<div class="adjusted">
 // My elements that go on dynamic size area
 <div class="the_bottom_bar">
  // My elements that goes on bottom bar (fixed heigh of 31 pixels)
 </div>  
</div>  

Oh oui, j’ai mis une valeur légèrement supérieure sur div.adaptée pour le bas que pour la hauteur de la barre inférieure, sinon la barre de défilement verticale apparaît, j’ai ajusté pour être la valeur la plus proche.

Cette différence est due au fait que l’un des éléments de la zone dynamique ajoute un fond supplémentaire que je ne sais pas comment me débarrasser. C’est une balise video (HTML5). Notez que j’ai mis cette balise video avec ce css ( donc il n'y a aucune raison pour que cela fasse un trou au fond, mais ça le fait):

 video{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

L'objectif: avoir une vidéo prenant à 100% le ventilateur (et redimensionnant dynamiquement lorsque le navigateur est redimensionné, mais sans modifier le rapport hauteur/largeur) moins un espace au bas que j'utilise pour une div avec des textes, des boutons, etc. (et des validateurs w3c & css bien sur).

EDIT: J'ai trouvé la raison, la balise video est comme du texte, pas un élément de bloc, donc je l'ai corrigé avec ce css:

 video{
  display:block;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

Notez le display:block; sur la balise video.

1
Claudio

Une autre façon d'atteindre le même objectif: flex box . Faites du conteneur une boîte Flex de colonne, puis vous aurez toute liberté pour permettre à certains éléments d’avoir une taille fixe (comportement par défaut) ou de se remplir/se rétrécir dans l’espace du conteneur (avec flex-grow: 1 et flex- rétrécir: 1).

#wrap {        
  display:flex;
  flex-direction:column;
}
.extendOrShrink {
  flex-shrink:1;
  flex-grow:1;
  overflow:auto;
}

Voir https://jsfiddle.net/2Lmodwxk/ (essayez d'étendre ou de réduire la fenêtre pour remarquer l'effet)

Remarque: vous pouvez également utiliser la propriété abrégée:

   flex:1 1 auto;
1
tarulen

Je ne sais pas si cela fonctionne dans votre situation particulière, mais j'ai constaté que le remplissage de la div interne pousserait le contenu à l'intérieur d'une div si la div qui la contenait avait une taille fixe. Vous auriez à faire flotter ou à positionner absolument votre élément d’entête, mais sinon, je n’ai pas essayé cela pour les div de taille variable.

0
dclowd9901