Largeur Div 100% moins quantité fixe de pixels

316

Comment puis-je obtenir la structure suivante sans utiliser de tables ou JavaScript? Les bordures blanches représentent les bords des divs et ne sont pas pertinentes pour la question.

Structure 1

La taille de la zone au milieu va varier, mais elle aura des valeurs de pixels exactes et toute la structure devrait évoluer en fonction de ces valeurs. Pour le simplifier, j'aurais besoin d'un moyen de définir la largeur "100% - n px" sur les divs en haut au milieu et en bas au milieu.

J'apprécierais une solution cross-browser propre, mais au cas où ce ne serait pas possible, les hacks CSS feront l'affaire.

Voici un bonus. Une autre structure avec laquelle j'ai eu du mal et j'ai fini par utiliser des tables ou JavaScript. C'est légèrement différent, mais introduit de nouveaux problèmes. Je l'ai principalement utilisé dans un système de fenêtrage basé sur jQuery, mais je voudrais garder la mise en page hors du script et contrôler uniquement la taille d'un élément (celui du milieu).

Structure 2

Removed_account
la source
Pour le deuxième élément, vous dites que vous voulez que la hauteur de l'élément très central soit fixe, mais que les autres éléments à proximité soient dynamiques
Casebash

Réponses:

78

Vous pouvez utiliser des éléments imbriqués et un remplissage pour obtenir un bord gauche et droit sur la barre d'outils. La largeur par défaut d'un divélément est auto, ce qui signifie qu'il utilise la largeur disponible. Vous pouvez ensuite ajouter un rembourrage à l'élément et il reste dans la largeur disponible.

Voici un exemple que vous pouvez utiliser pour mettre des images en coins arrondis gauche et droit, et une image centrale qui se répète entre elles.

Le HTML:

<div class="Header">
   <div>
      <div>This is the dynamic center area</div>
   </div>
</div>

Le CSS:

.Header {
   background: url(left.gif) no-repeat;
   padding-left: 30px;
}
.Header div {
   background: url(right.gif) top right no-repeat;
   padding-right: 30px;
}
.Header div div {
   background: url(center.gif) repeat-x;
   padding: 0;
   height: 30px;
}
Guffa
la source
Merci pour ça. J'ai dû le modifier un peu pour ma situation. La première division imbriquée avait besoin d'une marge à droite au lieu d'un remplissage, et la division centrale avait également besoin de la même marge à droite.
Max
3
Excellente solution. juste une petite chose -> cela fonctionne parce que ".Header div div" remplace ".Header div" . Il devrait être ".Header> div" et ".Header> div> div" à la place. En effet, ".Header div" signifie tout enfant div ou sub div enfant tandis que ".Header> div" signifie uniquement les enfants directs de .Header
Charles HETIER
@CharlesHETIER: Oui, cela fonctionne aussi et est plus facile à utiliser car vous n'avez pas à remplacer tous les paramètres de la règle moins spécifique. La réponse a été écrite lorsque le support de l' >opérateur n'était toujours pas assez bon pour être fiable.
Guffa
1
Ceci est obsolète, voir la réponse ci-dessous à propos de la fonction calc sur css.
María Arias de Reyna Domínguez
2
@delawen: Vous devez attendre un moment avant qu'il ne devienne obsolète. Il n'y a pas de support pour calcIE 8 ou les versions actuelles d'Anroid Browser ou d'Opera. caniuse.com/#search=calc
Guffa
760

Nouvelle façon dont je viens de tomber sur: csscalc() :

.calculated-width {
    width: -webkit-calc(100% - 100px);
    width:    -moz-calc(100% - 100px);
    width:         calc(100% - 100px);
}​

Source: largeur css 100% moins 100px

rom_j
la source
86
La meilleure réponse en 2013 à mon humble avis. La réponse acceptée est obsolète.
Danubian Sailor
7
Il est temps que quelqu'un tombe dessus. J'en ai fini avec les hacks maintenant que je le sais. +1 @lechlukasz
preahkumpii
47
Après 10 ans de CSS en difficulté, cette réponse mérite +20000! Je ne peux toujours pas croire mes yeux ...
skobaljic
8
Tout ce que je peux dire c'est ... youtube.com/…
Jazz
5
Plus compatible? -> $ ('# yourEl'). css ('width', '100%'). css ('width', '- = 100px'); (jQuery)
sboy031
7

Bien que la réponse de Guffa fonctionne dans de nombreuses situations, dans certains cas, vous ne souhaiterez peut-être pas que les morceaux de rembourrage gauche et / ou droit soient le parent de la division centrale. Dans ces cas, vous pouvez utiliser un contexte de mise en forme de bloc au centre et faire flotter les divisions de remplissage à gauche et à droite. Voici le code

Le HTML:

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
    <div class="center"></div>
</div>

Le CSS:

.container {
    width: 100px;
    height: 20px;
}

.left, .right {
    width: 20px;
    height: 100%;
    float: left;
    background: black;   
}

.right {
    float: right;
}

.center {
    overflow: auto;
    height: 100%;
    background: blue;
}

Je pense que cette hiérarchie d'éléments est plus naturelle par rapport aux divisions imbriquées imbriquées et représente mieux ce qui est sur la page. Pour cette raison, les bordures, le rembourrage et la marge peuvent être appliqués normalement à tous les éléments (c'est-à-dire que cette «naturalité» va au-delà du style et a des ramifications).

Notez que cela ne fonctionne que sur les divs et autres éléments qui partagent sa propriété «remplir 100% de la largeur par défaut». Les entrées, les tables et éventuellement d'autres vous obligeront à les envelopper dans un conteneur div et à ajouter un peu plus de CSS pour restaurer cette qualité. Si vous n'avez pas la chance d'être dans cette situation, contactez-moi et je déterrerai le css.

jsfiddle ici: jsfiddle.net/RgdeQ

Prendre plaisir!

Unislash
la source
6

Vous pouvez utiliser la disposition Flexbox . Vous devez définir flex: 1l'élément qui doit avoir une largeur ou une hauteur dynamique pourflex-direction: row and column respectivement.

Largeur dynamique:

HTML

<div class="container">
  <div class="fixed-width">
    1
  </div>
  <div class="flexible-width">
    2
  </div>
  <div class="fixed-width">
    3
  </div>
</div>

CSS

.container {
  display: flex;
}
.fixed-width {
  width: 200px; /* Fixed width or flex-basis: 200px */
}
.flexible-width {
  flex: 1; /* Stretch to occupy remaining width i.e. flex-grow: 1 and flex-shrink: 1*/
}

Production:


Hauteur dynamique:

HTML

<div class="container">
  <div class="fixed-height">
    1
  </div>
  <div class="flexible-height">
    2
  </div>
  <div class="fixed-height">
    3
  </div>
</div>

CSS

.container {
  display: flex;
}
.fixed-height {
  height: 200px; /* Fixed height or flex-basis: 200px */
}
.flexible-height {
  flex: 1; /* Stretch to occupy remaining height i.e. flex-grow: 1 and flex-shrink: 1*/
}

Production:

Manoj Kumar
la source
3

La façon habituelle de le faire est celle décrite par Guffa, éléments imbriqués. C'est un peu triste d'avoir à ajouter du balisage supplémentaire pour obtenir les crochets dont vous avez besoin pour cela, mais dans la pratique, une div wrapper ici ou là ne blessera personne.

Si vous devez le faire sans éléments supplémentaires (par exemple lorsque vous n'avez pas le contrôle du balisage de page), vous pouvez utiliser le dimensionnement de la boîte , qui a un support de navigateur assez décent mais pas complet ou simple. Probablement plus amusant que de devoir compter sur des scripts.

bobince
la source
3

Peut-être que je suis stupide, mais la table n'est-elle pas la solution évidente ici?

<div class="parent">
    <div class="fixed">
    <div class="stretchToFit">
</div>

.parent{ display: table; width 100%; }
.fixed { display: table-cell; width: 150px; }
.stretchToFit{ display: table-cell; vertical-align: top}

Une autre façon dont j'ai compris en chrome est encore plus simple, mais l'homme est-ce un hack!

.fixed{ 
   float: left
}
.stretchToFit{
   display: table-cell;
   width: 1%;
}

Cela seul devrait remplir le reste de la ligne horizontalement, comme le font les cellules de tableau. Cependant, vous rencontrez des problèmes étranges avec le dépassement de 100% de son parent, la définition de la largeur sur une valeur en pourcentage le résout cependant.

Jack Franzen
la source
2

Nous pouvons y parvenir très facilement en utilisant la boîte flexible.

Si nous avons trois éléments comme Header, MiddleContainer et Footer. Et nous voulons donner une hauteur fixe à l'en-tête et au pied de page. alors on peut écrire comme ceci:

Pour React / RN (les valeurs par défaut sont 'display' comme flex et 'flexDirection' comme colonne), dans le CSS Web, nous devrons spécifier le conteneur de corps ou le conteneur les contenant comme affichage: 'flex', flex-direction: 'column' comme ci-dessous:

    container-containing-these-elements: {
     display: flex,
     flex-direction: column
    }
    header: {
     height: 40,
    },
    middle-container: {
     flex: 1, // this will take the rest of the space available.
    },
    footer: {
     height: 100,
    }
jayiitb
la source
1

que se passe-t-il si votre div enveloppant était à 100% et que vous avez utilisé un remplissage pour une quantité de pixels, puis si le remplissage # doit être dynamique, vous pouvez facilement utiliser jQuery pour modifier votre quantité de remplissage lorsque vos événements se déclenchent.

dfasdljkhfaskldjhfasklhf
la source
1

J'ai eu un problème similaire où je voulais une bannière en haut de l'écran qui avait une image à gauche et une image répétitive à droite sur le bord de l'écran. J'ai fini par le résoudre comme ceci:

CSS:

.banner_left {
position: absolute;
top: 0px;
left: 0px;
width: 131px;
height: 150px;
background-image: url("left_image.jpg");
background-repeat: no-repeat;
}

.banner_right {
position: absolute;
top: 0px;
left: 131px;
right: 0px;
height: 150px;
background-image: url("right_repeating_image.jpg");
background-repeat: repeat-x;
background-position: top left;
}

La clé était la bonne étiquette. Je spécifie essentiellement que je veux qu'il se répète de 131 pixels de gauche à 0 pixels de droite.

Mike Carey
la source
0

Dans certains contextes, vous pouvez utiliser les paramètres de marge pour spécifier efficacement "100% de largeur moins N pixels". Voir la réponse acceptée à cette question .

le chaos
la source