Come fare in modo che la larghezza CSS riempia il genitore?


88

Sono sicuro che questo problema è stato chiesto prima, ma non riesco a trovare la risposta.

Ho il seguente markup:

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

Il mio desiderio è di fare in modo che foo abbia una larghezza di 600px( width: 600px;) e che la barra abbia i seguenti comportamenti:

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

In altre parole, invece di impostare la larghezza della barra su, 592pxvorrei impostare la larghezza esterna della barra su in 100%modo che venga calcolata 592px. L'importanza qui è che posso cambiare la larghezza di foo in 800pxe bar calcolerà quando renderizzato invece di dover fare manualmente i calcoli per tutte queste istanze.

È possibile in puro CSS?

Un po 'più di divertimento con esso:

  • E se #barfosse un tavolo?
  • E se #barfosse una textarea?
  • E se #barfosse un input?

  • E se #foofosse una cella di tabella ( td)? (Questo cambia il problema o il problema è identico?)


Finora table#bar, input#barè stato discusso. Non ho visto una buona soluzione per textarea # bar. Penso che un'area di testo senza bordo / margine / riempimento con un divavvolgimento potrebbe funzionare con lo divstile per funzionare come bordi per il file textarea.

Risposte:


39

MODIFICA :

Questi tre diversi elementi hanno tutti regole di rendering diverse.

Così per:

table#barè necessario impostare la larghezza al 100% altrimenti sarà larga solo come determina che deve essere. Tuttavia, se la larghezza totale delle righe della tabella è maggiore della larghezza bar, si espanderà fino alla larghezza necessaria. SE ricordo che puoi contrastare questo impostando display: block !important;anche se è passato un po 'di tempo da quando ho dovuto risolverlo. (Sono sicuro che qualcuno mi correggerà se sbaglio).

textarea#barcredo che sia un elemento a livello di blocco, quindi seguirà le regole come il div. L'unico avvertimento qui è che textareaprendi gli attributi di colse rowsche sono misurati in colonne di caratteri. Se questo è specificato sull'elemento, sovrascriverà la larghezza specificata dal css.

input#barè un elemento in linea, quindi per impostazione predefinita non puoi assegnargli larghezza. Tuttavia è simile all'attributo di textareas cols, ha un sizeattributo sull'elemento che può determinare la larghezza. Detto questo, puoi sempre specificare una larghezza utilizzando display: block;nel tuo css per questo. Quindi seguirà le stesse regole di rendering del div.

td#foosarà reso come un table-cellche ha un po 'di follia. La linea di fondo qui è che per i tuoi scopi agirà esattamente come div#foolimitando la larghezza dei suoi contenuti. L'unico problema qui sarà un potenziale testo non interpretabile nella colonna da qualche parte che lo farebbe ignorare l'impostazione della larghezza. Inoltre, tutte le celle della colonna avranno la larghezza della cella più ampia.


Questo è il comportamento predefinito dell'elemento a livello di blocco - ad es. se la larghezza è auto(l'impostazione predefinita), sarà il 100% della larghezza interna dell'elemento contenitore. quindi in sostanza:

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

ti darà esattamente quello che vuoi.


Ehi, grazie. Divertirsi anche con i tavoli che decidono di sanguinare comunque. Presumo che le tabelle abbiano lo stesso comportamento dei div?
Dmitriy Likhten

@ Dimitry: No, hanno regole speciali che li rendono più simili inline-blockdegli blockelementi. Nota però che ho detto più come non come :-) Quello che probabilmente stai sperimentando è che, se non diversamente definito, generalmente si espandono per accogliere tutte le colonne, il che può essere davvero fastidioso se alcune delle intestazioni / celle contengono testo a lungo non interpretabile.
prodigital il

Grazie per l'aiuto :) Consentitemi di aggiornare un po 'la domanda per fornire una panoramica molto più completa dei problemi e si spera che tutte le soluzioni alternative possano essere elencate in una sezione.
Dmitriy Likhten,

Ho sperimentato con div # foo table # bar e impostando la larghezza: 100% su table # bar espanderà effettivamente la tabella, ma i bordi / margini della tabella scorreranno attraverso div # foo. Impostare la tabella da visualizzare: il blocco non è buono poiché rovina altri aspetti del rendering della tabella come la gestione della larghezza della riga. textarea # bar non si espanderà quando la larghezza è impostata su auto o non impostata.
Dmitriy Likhten

1
perché textarea#bardovresti essere in grado di impostarlo display: blockcon pochi effetti negativi. Per quanto riguarda la tabella, so di aver usato una sorta di soluzione / mitigazione per questo in passato, ma non ricordo cosa fosse al momento. Tuttavia dirò che generalmente non imposto i "margini" su una tabella ma piuttosto lo avvolgo in un div con padding / margins ... questo potrebbe essere lo stesso #foo o un altro div usato solo per applicare questo tipo di spaziatura. Inoltre puoi fare per contrastare il problema dei bordi per applicare i bordi solo alla prima / ultima cella di fila / alle celle nella prima / ultima riga
prodigitalon

28

quasi lì, cambia semplicemente outerWidth: 100%;in width: auto;(outerWidth non è una proprietà CSS)

in alternativa, applica i seguenti stili alla barra:

width: auto;
display: block;

4
Ciò non funzionerà se sta impostando un margine di riempimento barperché verrà aggiunto al 100% in modo efficace rendendolo barpiù largo del suo genitore foo.
Prodigital il

sì, ho risposto troppo in fretta; P
Rowan

Aspetta un secondo. Quindi se imposto la proprietà di larghezza su qualcosa, verrà sanguinato? larghezza: auto non è la soluzione, piuttosto non impostare affatto la larghezza è?
Dmitriy Likhten,

2
si, è esatto. Qualsiasi elemento che ha display:block;(noto anche come elemento a livello di blocco) adotterà questo comportamento. un elemento DIV ha width:auto;e display:block;impostato per impostazione predefinita.
Rowan

Vecchio post, ma non poteva semplicemente usare box-sizing: border-box per consentire all'imbottitura di essere all'interno della larghezza dell'elemento.
CHBresser

16

Usa gli stili

left: 0px;

o / e

right: 0px;

o / e

top: 0px;

o / e

bottom: 0px;

Penso che per la maggior parte dei casi questo farà il lavoro


4

Quindi dopo la ricerca si scopre quanto segue:

Per div#barun'impostazione display:block; width: auto;causa l'equivalente diouterWidth:100%;

Per un table#barè necessario racchiuderlo in un div con le regole indicate di seguito. Quindi la tua struttura diventa:

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

In questo modo la tabella occupa il div genitore al 100% e #barWrapviene utilizzata per aggiungere bordi / margini / padding alla #bartabella. Nota che dovrai impostare lo sfondo dell'intera cosa #barWrape fare in modo #barche lo sfondo di sia trasparente o uguale a #barWrap.

Perché textarea#bare input#bardevi fare la stessa cosa di table#bar, il lato negativo è che rimuovendo i bordi interrompi il rendering nativo del widget della input / textarea ei #barWrapbordi di appariranno un po 'diversi da qualsiasi altra cosa, quindi probabilmente dovrai farlo stile tutti i tuoi input in questo modo.


1
box-sizing: border-box;
width: 100%;
padding: 5px;

dimensionamento scatola: scatola bordo; fa in modo che riempimento, margine e bordo siano inclusi nei calcoli della larghezza.

MDN

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.