Comment faire de la largeur CSS pour remplir le parent?

88

Je suis sûr que ce problème a déjà été posé mais je n'arrive pas à trouver la réponse.

J'ai le balisage suivant:

<div id="foo">
    <div id="bar">
        here be dragons
    </div>
</div>

Mon désir est de faire en sorte que foo ait une largeur de 600px( width: 600px;) et que bar ait les comportements suivants:

padding-left: 2px;
padding-right: 2px;
margin-left: 2px;
margin-right: 2px;
outerWidth: 100%;

En d'autres termes, au lieu de définir la largeur de la barre sur, 592pxje voudrais définir la largeur extérieure de la barre sur 100%afin qu'elle soit calculée 592px. L'importance ici est que je peux changer la largeur de foo en 800pxet la barre calculera lors du rendu au lieu de devoir faire le calcul pour toutes ces instances manuellement.

Est-ce possible en CSS pur?

Un peu plus de plaisir avec:

  • Et qu'est-ce qui se passerait si #bar c'était une table?
  • Et qu'est-ce qui se passerait si #bar c'était une zone de texte?
  • Et si #barc'est une entrée?

  • Et si #fooest une cellule de tableau ( td)? (Cela change-t-il le problème ou le problème est-il identique?)


Jusqu'à présent, le table#bar, input#bara été discuté. Je n'ai pas vu de bonne solution pour textarea # bar. Je pense qu'une zone de texte sans bordure / marge / remplissage avec une divenveloppe pourrait fonctionner avec le divstyle pour fonctionner comme des bordures pour le textarea.

Dmitriy Likhten
la source

Réponses:

39

MODIFIER :

Ces trois éléments différents ont tous des règles de rendu différentes.

Donc pour:

table#barvous devez définir la largeur à 100%, sinon elle ne sera que la largeur qu'elle détermine. Cependant, si la largeur totale des lignes du tableau est supérieure à sa largeur, barelle s'étendra à sa largeur nécessaire. SI je me souviens, vous pouvez contrer cela en réglant display: block !important;bien que cela fasse un certain temps depuis que ive a dû résoudre ce problème. (Im sûr que quelqu'un me corrigera si je me trompe).

textarea#bari beleive est un élément de niveau bloc donc il suivra les mêmes règles que le div. La seule mise en garde ici est que textareaprendre un attribut de colsetrows qui sont mesurés dans des colonnes de caractères. Si cela est spécifié sur l'élément, il remplacera la largeur spécifiée par le css.

input#barest un élément en ligne, donc par défaut vous ne pouvez pas lui attribuer de largeur. Cependant l' attribut similaire à textarea's cols, il a un sizeattribut sur l'élément qui peut déterminer la largeur. Cela dit, vous pouvez toujours spécifier une largeur en utilisant display: block;dans votre css pour cela. Ensuite, il suivra les mêmes règles de rendu que le div.

td#foosera rendu comme un table-cellqui a une certaine folie. L'essentiel ici est que pour vos besoins, il va agir comme div#foopour restreindre la largeur de son contenu. Le seul problème ici va être un texte potentiellement non emballable dans la colonne quelque part, ce qui le ferait ignorer votre paramètre de largeur. De plus, toutes les cellules de la colonne auront la largeur de la cellule la plus large.


C'est le comportement par défaut de l'élément de niveau bloc - ie. si width est auto(la valeur par défaut) alors ce sera 100% de la largeur intérieure de l'élément contenant. donc en substance:

#foo {width: 800px;}
#bar {padding-left: 2px; padding-right: 2px; margin-left: 2px; margin-right: 2px;}

vous donnera exactement ce que vous voulez.

prodigitalson
la source
Hey, merci. S'amuser aussi avec les tables décidant de saigner de toute façon. Je suppose que les tables ont le même comportement que les divs?
Dmitriy Likhten le
@Dimitry: Non, ils ont des règles spéciales qui les rendent plus proches inline-blockque des blockéléments. Notez cependant que j'ai dit plutôt pas la même chose que :-) Ce que vous vivez probablement, c'est que, sauf indication contraire, elles se développeront généralement pour accueillir toutes les colonnes, ce qui peut être vraiment ennuyeux si certains des en-têtes / cellules contiennent un long texte non emballable.
prodigitals le
Merci de votre aide :) Permettez-moi de mettre à jour un peu la question pour donner un aperçu beaucoup plus complet des problèmes et j'espère que toutes les solutions de contournement peuvent être répertoriées dans une section.
Dmitriy Likhten
J'ai expérimenté la barre div # foo table # et la définition de la largeur: 100% sur la barre # table élargira en effet le tableau, mais les bordures / marges du tableau vont saigner à travers div # foo. Définir le tableau pour afficher: bloc n'est pas bon car cela gâche d'autres aspects du rendu du tableau tels que la gestion de la largeur de la ligne. textarea # bar ne se développera pas lorsque la largeur est définie sur auto ou n'est pas définie.
Dmitriy Likhten
1
car textarea#barvous devriez pouvoir régler cela display: blockavec peu d'effet indésirable. En ce qui concerne le tableau, je sais que j'ai utilisé une sorte de solution / atténuation pour cela dans le passé, mais je ne me souviens pas de ce que c'était pour le moment. Cependant, je dirai que je ne mets généralement pas de "marges" sur une table, mais plutôt l'enveloppe dans un div avec padding / margins ... cela pourrait être #foo lui-même ou un autre div utilisé jsut pour appliquer ce type d'espacement. Vous pouvez également faire pour contrer le problème de bordure pour appliquer les bordures uniquement à la première / dernière cellule d'une ligne / aux cellules de la première / dernière ligne
prodigitals le
28

presque là, il suffit de changer outerWidth: 100%;pourwidth: auto; (OutsideWidth n'est pas une propriété CSS)

ou appliquez les styles suivants à la barre:

width: auto;
display: block;
Sorbier des oiseleurs
la source
4
Cela ne fonctionnera pas s'il définit une marge de remplissage, barcar le sera ajouté à 100%, ce qui rendra barplus large que son parent foo.
prodigitals le
ouais, j'ai répondu à celui-là trop vite; P
Rowan
Attends une seconde. Donc, si je définis la propriété width sur quelque chose, cela saignera? width: auto n'est pas la solution, plutôt que de définir la largeur du tout est?
Dmitriy Likhten
2
Oui c'est vrai. Tout élément qui a display:block;(également appelé élément de niveau bloc) adoptera ce comportement. un élément DIV awidth:auto; et display:block;défini par défaut.
Rowan
Ancien message, mais ne pouvait-il pas simplement utiliser box-sizing: border-box pour permettre au rembourrage d'être à l'intérieur de la largeur de l'élément.
CHBresser
16

Utilisez les styles

left: 0px;

ou et

right: 0px;

ou et

top: 0px;

ou et

bottom: 0px;

Je pense que dans la plupart des cas, cela fera l'affaire

Tigsar
la source
4

Ainsi, après recherche, on découvre ce qui suit:

Pour un div#bardécordisplay:block; width: auto; provoque l'équivalent deouterWidth:100%;

Pour un, table#barvous devez l'envelopper dans un div avec les règles énoncées ci-dessous. Ainsi votre structure devient:

<div id="foo">
 <div id="barWrap" style="border....">
  <table id="bar" style="width: 100%; border: 0; padding: 0; margin: 0;">

De cette façon, le tableau occupe le div parent à 100% et #barWrapest utilisé pour ajouter des bordures / marge / remplissage au #bartableau. Notez que vous devrez définir l'arrière-plan de l'ensemble #barWrapet que #barl'arrière-plan de celui-ci soit transparent ou identique à#barWrap .

Pour textarea#baret input#barvous devez faire la même chose que table#bar, l' inconvénient est qu'en supprimant les bordures, vous arrêtez le rendu du widget natif de la zone d'entrée / de texte et les #barWrapbordures de s auront un aspect un peu différent de tout le reste, vous devrez donc probablement stylisez toutes vos entrées de cette façon.

Dmitriy Likhten
la source