2011-02-04 9 views
10

Quindi, prima un po 'di carne per impostare la scena:Perché le proprietà della larghezza e dell'altezza CSS non si adattano al riempimento?

HTML

<div id="container"> 
    <div id="inner">test</div> 
</div> 

CSS

#container { 
    width:300px; 
    height:150px; 
    background-color:#d7ebff; 
} 

#inner { 
    width:100%; 
    height:100%; 
    padding:5px; 
    background-color:#4c0015; 
    opacity:.3; 
} 

Questo produrrà qualcosa che assomiglia a questo in tutti i browser moderni:

CSS interior width test showing the inner box exceeding the container

Ora so che questo è il comportamento conforme agli standard (come sapevo prima, ma riconfermata nel this post, e so anche che se includo questo codice nella dichiarazione CSS interno:

box-sizing:border-box; 
-moz-box-sizing:border-box; 
-webkit-box-sizing:border-box 

.. . Adotterò il modello "border-box" e otterrò il comportamento che mi sembra più intuitivo, ma mi sono appena trovato a cercare di giustificare logicamente il ragionamento dietro al perché questo è il modo in cui è e non sono stato in grado di farlo.

Sembra (sulla superficie delle cose) più logico per me che la scatola interna riempia sempre il contenitore esattamente al 100% della larghezza del contenitore, indipendentemente dal riempimento o dal bordo della scatola interna. Mi imbatto in questo problema tutto il tempo in cui sto cercando di impostare la larghezza di una textarea al 100% con un bordo o qualcosa di simile a un padding interno di 4px ... la textarea riempirà sempre il contenitore.

Quindi la mia domanda è ... qual è la logica dietro l'impostazione del comportamento predefinito per ignorare il bordo e il riempimento di un elemento quando si imposta la larghezza?

+0

"in tutti i browser moderni" - tranne IE 8 che produce un quadrato sostanzialmente rosso. – NotMe

+2

IE è l'esploratore del cavernicolo. – JCOC611

+0

@ JCOC611: Anch'io ci pensavo. Tuttavia, ho notato che tutti i browser hanno a volte problemi criptanti. Almeno con un rigoroso doctype, posso almeno fare in modo che IE8, Chrome e Firefox visualizzino almeno tutto in modo identico. Ora, se Firefox risolvesse i loro articoli di stampa e Chrome potesse semplicemente caricare le pagine, mi piacerebbe molto fuggire da IE. – NotMe

risposta

32

Il motivo CSS utilizza il box model come:

+--------------------- 
|  Margin 
| +------------------- 
| |  Border 
| | +----------------- 
| | | Padding 
| | | +--------------- 
| | | | Width x Height 

è perché i CSS è un documento styling lingua. Era (originariamente) progettato con documenti di ricerca e altri documenti formali in mente, non come un modo per creare una grafica carina. In quanto tale, il modello ruota attorno al contenuto , non al contenitore.

CSS non è un linguaggio di programmazione, è un linguaggio di stile. Non indica esplicitamente al documento come dovrebbe essere visualizzato, lo suggerisce alcune linee guida che il browser dovrebbe seguire. Tutti questi possono essere sovrascritti e modificati da un vero linguaggio di programmazione: JavaScript.

Tornando al contenuto-modello di idea, si consideri il seguente CSS:

p 
{ 
    background-color: #EEE; 
    border: 1px solid #CCC; 
    color: #000; 
    margin: 10px; 
    padding: 9px; 
    width: 400px; 
} 

height non è specificato, perché il contenutodefinisce l'altezza, può essere lungo, potrebbe essere breve, ma è sconosciuto e non importante. Il width è impostato su 400px perché è così che il contenuto (testo) deve essere largo.

Il padding è solo un mezzo per estendere il colore di sfondo in modo che il testo possa essere ben leggibile lontano dai bordi, proprio come si lascia uno spazio quando si scrive/stampa su un foglio di carta.

Il border è un mezzo per circondare alcuni contenuti per differenziarlo dagli altri sfondi o per fornire un bordo (vai figura) tra vari elementi.

Il margin indica al paragrafo di lasciare uno spazio tra i bordi e, con il collasso dei margini, ciascun gruppo rimarrà equidistante senza dover specificare un margine diverso per il primo o l'ultimo elemento.

Per mantenere fluidità, width default auto, che significa che la larghezza sarà il più ampio possibile:

  1. senza schiacciando il contenuto irragionevolmente
  2. senza l'imbottitura si estende oltre il suo contenitore

Ovviamente, nei casi limite, l'imbottitura si estenderà oltre il suo contenitore perché il contenuto potrebbe essere schiacciato. Tutto riguarda il contenuto.

+0

Grazie per questa lunga risposta! Sarebbe certamente bello se potessi impostare la textarea su 'display: block' e farlo riempire automaticamente la larghezza del suo contenitore, ma purtroppo non sembra avere questo comportamento. Mi chiedo se, dal momento che l'uso dei CSS è ora (con un margine abbastanza considerevole) utilizzato per la progettazione visiva delle pagine web, essi rivisiteranno questa specifica in futuro. Le aree di testo – treeface

+0

sono leggermente diverse, si suppone che abbiano un numero specificato di righe e colonne. I CSS3 danno loro la possibilità di essere ridimensionati per adattarsi meglio all'utente. – zzzzBov

+2

Non ho avuto tempo di espandermi su textareas prima, ma il trucco per renderli "dinamici" è metterli in un div. rendere il margine dell'area di testo, il bordo, il riempimento tutti uguali a 0 e avere larghezza e altezza al 100%. Quindi aggiungi un po 'di padding e un bordo al div per farlo sembrare * come se fosse la textarea. – zzzzBov

6

Si potrebbe desiderare di rivedere quanto segue al W3C: http://www.w3.org/TR/CSS21/box.html

Il modello di dialogo è tale che l'altezza e la larghezza riguardano l'area del contenuto dell'elemento. L'imbottitura è al di fuori di quella zona ed è per questo che vedi la scatola interna che trabocca quella esterna.

Dopo il riempimento, il bordo, se presente. Quindi il margine si applica al di fuori del confine. Ciò significa che la larghezza effettiva degli elementi è definita come: Larghezza + Riempimento + Bordo + Margine.

In effetti, il css ha definito la casella interna con un'area di 300px per 150px più un 5px aggiuntivo di padding oltre a quello che produce una casella di 310px per 160px.

Personalmente, sono d'accordo che la larghezza dovrebbe includere il padding. Tuttavia, non è quello che dice la specifica.

Come nota a margine, la modalità di quirks include il padding (e il bordo) nella larghezza effettiva. Sfortunatamente, la modalità "Quirks" evita così tante altre cose che di solito è meglio gestire il modello spec3d di w3c piuttosto che provare a creare tutto il css necessario per aggiustare le altre cose "bizzarre".

Un altro sito (che è d'accordo con te e io) è qui: http://www.quirksmode.org/css/box.html

accennano che CSS3 include la dichiarazione box-sizing (come hai trovato) che dovrebbe dare un maggiore controllo su cui box modello da usare. Sembra che quasi tutti (IE8, Chrome, Firefox) supportano ciò che è buono.

+1

Grazie per i collegamenti! Quella voce di quirksmode.org è esattamente il tipo di cosa che stavo cercando. Sono contento di non essere solo nel pensare che il modello dei contenuti sia un po 'controintuitivo. – treeface

1

Per rispondere alla tua domanda, penso che la logica sia che riguarda il contenuto; se specifichi le dimensioni, queste sono le dimensioni che il contenuto sta per ottenere.

Ma alla fine è solo una scelta che è stata fatta ed è quello con cui dobbiamo lavorare.

1

Guardate la seguente immagine: enter image description here

Consideriamo ora cosa succede quando si impostare la larghezza e l'altezza dei valori al 100% - devono il padding e il bordo magicamente scompaiono da questo quadro?Come faresti come uno sviluppatore a gestirlo in modo ragionevole?

width and height is width and height, border and padding is something else - per me non è più logico di così.

D'altra parte

width and height is width and a height, but sometimes when you choose to set them to 100% they are also border and padding - ora che non avrebbe alcun senso per me.

Ma poi, una logica mans può essere un altro mans sciocchezze, quindi non so se questo vi aiuterà;)

+0

Certo, a questo livello ho sicuramente capito perché lo fa. In effetti, ho visto e usato questa scatola molte volte in passato, ma nella maggior parte dei miei casi d'uso, ha più senso impostare la larghezza di un elemento al 100% (o 150px o qualsiasi altra cosa) e impostarne il riempimento su 5px e farli considerare concetti separati. Come è ora, lo sviluppo visuale di una pagina Web di solito significa sommare il "bordo + riempimento + larghezza", che non è molto intuitivo. Questo mi permetterebbe di dire "OK, voglio che sia largo 450px" e poi dire "hm ... ora voglio 5px padding" e non avere la larghezza totale salta fino a 460px. – treeface

+0

@treeface: questo perché per te la larghezza è misurata all'esterno della scatola, dove per quanto riguarda il modello di scatola viene misurato all'interno. Non si tratta di logica, ma di definizione: come misureresti i metri quadri di una casa? all'esterno o all'interno? per me, dentro ha un senso, ma per alcuni al di fuori potrebbe adattarsi meglio ...Penso che dipenda dal tuo stato d'animo :) –

+0

In effetti ... naturalmente è una questione di opinione. Ma chiaramente la mia opinione è corretta ;-) – treeface

1

Anche se questo potrebbe non essere stata l'intenzione originale del box model, un altro vantaggio è se vuoi qualcosa con un'immagine di sfondo sfalsata (ad esempio l'immagine è a sinistra oa destra del testo). Quindi è possibile specificare il riempimento in modo che sia la larghezza dell'immagine di sfondo in modo che il testo non si sovrapponga e specifichi comunque una larghezza per il testo stesso. Per esempio:

.imageDiv{ 
width:200px; 
background-image:url('someimage.png') /*this image is 50 px wide*/ 
background-repeat:no-repeat; 
padding-left:50px; 
} 

Ora qualsiasi testo entrato in un div con la classe imageDiv mostrerà l'immagine a sinistra del testo con qualsiasi sovrapposizione.

Problemi correlati