CSS altezza 100% con imbottitura / margine


813

Con HTML / CSS, come posso creare un elemento che abbia una larghezza e / o altezza pari al 100% del suo elemento padre e che abbia ancora un'imbottitura o dei margini adeguati?

Per "corretto" intendo che se il mio elemento genitore è 200pxalto e lo specifico height = 100%con padding = 5pxmi aspetterei che dovrei ottenere un 190pxelemento alto conborder = 5px su tutti i lati, ben centrato nell'elemento genitore.

Ora, so che non è così che il modello di scatola standard specifica che dovrebbe funzionare (anche se mi piacerebbe sapere perché, esattamente ...), quindi la risposta ovvia non funziona:

#myDiv {
    width: 100%
    height: 100%;
    padding: 5px;
}

Ma mi sembra che ci sia ALCUNO modo di produrre questo effetto in modo affidabile per un genitore di dimensioni arbitrarie. Qualcuno sa come realizzare questo (apparentemente semplice) compito?

Oh, e per la cronaca non sono terribilmente interessato alla compatibilità con IE, quindi dovrebbe (si spera) rendere le cose un po 'più facili.

EDIT: da quando è stato richiesto un esempio, ecco il più semplice che mi viene in mente:

<html style="height: 100%">
    <body style="height: 100%">
        <div style="background-color: black; height: 100%; padding: 25px"></div>
    </body>
</html>

La sfida è quindi far apparire la scatola nera con un'imbottitura di 25 pixel su tutti i bordi senza che la pagina diventi abbastanza grande da richiedere barre di scorrimento.


Ho trovato queste due soluzioni le più affidabili: http://www.xs4all.nl/~peterned/examples/csslayout1.html http://themaninblue.com/experiment/footerStickAlt/ Hai qualche HTML specifico che possiamo vedere e giocare con?
Nick Presta,

Risposte:


755

Ho imparato a fare questo genere di cose leggendo " PRO HTML e CSS Design Patterns ". Il display:blockè il valore predefinito per la visualizzazione div, ma mi piace per renderlo esplicito. Il contenitore deve essere del tipo giusto; positionattributo è fixed, relativeo absolute.

.stretchedToMargin {
  display: block;
  position:absolute;
  height:auto;
  bottom:0;
  top:0;
  left:0;
  right:0;
  margin-top:20px;
  margin-bottom:20px;
  margin-right:80px;
  margin-left:80px;
  background-color: green;
}
<div class="stretchedToMargin">
  Hello, world
</div>

Fiddle dal commento di Nooshu


42
Soluzione superba, aggiungerà un segnalibro a questo. L'ho appena aggiunto a jsfiddle.net/Rpdr9 per chiunque desideri una demo live. Spero non ti dispiaccia.
Nooshu,

16
Mentre a @Toji non importava della compatibilità con IE, purtroppo devo farlo. Questa soluzione inizialmente non funzionava con IE6. L'aggiunta di IE9.js di Dean Edwards alla pagina ha reso questo lavoro. Ora devo solo sperare e pregare che il posizionamento relativo / assoluto non si rovini con qualcosa in un elemento figlio ...
Christopher Parker,

24
-1 (anche se sembra che io sia una minoranza qui: P). Ciò presuppone che la scatola possa essere posizionata in modo assoluto; la gente abusa già pos: abs così com'è, non hanno bisogno di queste munizioni. Prendiamo questo esempio: un "pannelli" div con al suo interno più div della classe "panel". "panel" ha {overflow: nascosto; height: 300px;} e "panel" hanno contenuti / altezza-contenuto variabili, con {border: # 000 solido 1px; float: left; margin-right: 10px;}. Rendi tutti i "pannelli" l'altezza dei "pannelli" senza perdere i bordi in nessun punto. I div "panel" non possono essere posati: sono assunti qui. La soluzione di @ Marco funziona per questo scenario, però.
eternicode

8
Oh wow, ho capito. L ' top:0, bottom:0essenzialmente "allunga" l'elemento. Posso solo farlo funzionare con position:absolutese
Matt

7
Non potresti semplicemente fare top:20px;bottom:20px;left:20px;right:20px;invece di usare i margini?
Chowey,

391

C'è una nuova proprietà in CSS3 che puoi usare per cambiare il modo in cui il modello di scatola calcola larghezza / altezza, si chiama dimensionamento delle scatole.

Impostando questa proprietà con il valore "border-box" rende qualunque elemento lo si applica per non allungare quando si aggiunge un riempimento o un bordo. Se definisci qualcosa con una larghezza di 100 px e un'imbottitura di 10 px, sarà comunque largo 100 px.

box-sizing: border-box;

Vedi qui per il supporto del browser . Non funziona per IE7 e versioni precedenti , tuttavia, credo che IE7.js di Dean Edward ne aggiunga il supporto. Godere :)


45
Finalmente! Sto aspettando questa esatta funzione da circa 10 anni. Pity IE7 non lo supporta, ma penso sempre che le persone che stanno ancora utilizzando IE non meritino un bel layout.
cronoklee,

2
Questo ha funzionato su iPhone / Safari e sul browser predefinito di Android per me, mentre la soluzione assolutamente posizionata sopra non funzionava.
Spud,

18
Questo è fondamentalmente lo stesso del modello box di modalità strane di IE . Trovo divertente come tutti odiano IE, ma ora border-boxè l'eroe di tutti :)
Matt Greer

14
Cordiali saluti, il prefisso del browser per il ridimensionamento delle caselle ora viene eliminato per tutti tranne -moz. Vedi paulirish.com/2012/box-sizing-border-box-ftw e i commenti per una buona discussione
aponzani

3
Sì! Questa è la risposta esatta! Il 100% di altezza ora ridimensiona le cose correttamente rispetto ai loro genitori, senza rovesciarsi. Darei un milione di +1 se potessi.
Andrew Mao,

65

La soluzione è NON usare affatto altezza e larghezza! Collegare la scatola interna usando in alto, a sinistra, a destra, in basso e quindi aggiungere margine.

.box {margin:8px; position:absolute; top:0; left:0; right:0; bottom:0}
<div class="box" style="background:black">
  <div class="box" style="background:green">
    <div class="box" style="background:lightblue">
      This will show three nested boxes. Try resizing browser to see they remain nested properly.
    </div>
  </div>
</div>


6
Aumenta il voto perché sei tecnicamente corretto, ma è anche sostanzialmente la stessa risposta di Frank (che penso sia un po 'più amichevole con i browser più sciatti là fuori.)
Toji

39

Il modo migliore è con la proprietà calc (). Quindi il tuo caso sarebbe simile a:

#myDiv {
    width: calc(100% - 5px);
    height: calc(100% - 5px);
    padding: 5px;
}

Semplice, pulito, senza soluzioni alternative. Assicurati solo di non dimenticare lo spazio tra i valori e l'operatore (ad esempio, (100%-5px)ciò interromperà la sintassi. Divertiti!


6
Bella soluzione. Ricorda solo di controllare il supporto del browser: posso usare calc ()
Brett Postin il

5
Questo non ti darebbe in realtà la larghezza e l'altezza del 100% per ogni imbottitura PLUS 5px, dal momento che l'imbottitura renderebbe effettivamente l'elemento 10px sempre più largo?

Finalmente una buona soluzione, e non come il resto di loro, puoi mettere in alto, a destra, in basso e a sinistra per essere 0, che funzionerà solo con la posizione: assoluta;
Gil Epshtain,

Penso che il corretto sia: #myDiv {larghezza: calc (100% - 10px); altezza: calc (100% - 10px); imbottitura: 5px; } 5 da sinistra e 5 da destra = 10, 5 dall'alto e 5 dal basso = 10
Chris P

21

Secondo l'altezza della specifica del w3c si riferisce all'altezza dell'area visualizzabile, ad esempio su un monitor con risoluzione di 1280x1024 pixel, altezza del 100% = 1024 pixel.

altezza minima si riferisce all'altezza totale della pagina incluso il contenuto, quindi su una pagina in cui il contenuto è maggiore di 1024px altezza minima: il 100% si allungherà per includere tutto il contenuto.

L'altro problema è quindi che il riempimento e il bordo vengono aggiunti all'altezza e alla larghezza nella maggior parte dei browser moderni, ad eccezione di ie6 (ie6 è in realtà abbastanza logico ma non conforme alle specifiche). Questo è chiamato il modello box. Quindi, se si specifica

min-height: 100%;
padding: 5px; 

In realtà ti darà il 100% + 5px + 5px per l'altezza. Per ovviare a questo è necessario un contenitore wrapper.

<style>
    .FullHeight { 
       height: auto !important; /* ie 6 will ignore this */
       height: 100%;            /* ie 6 will use this instead of min-height */
       min-height: 100%;        /* ie 6 will ignore this */
    }

    .Padded {
       padding: 5px;
    }
</style>

<div class="FullHeight">
   <div class="Padded">
      Hello i am padded.
   </div
</div>

4
@Alex: Ma ciò che rende il div interno (quello imbottito) il 100% dell'altezza del div esterno. La mia esperienza è stata che hai appena avuto un piccolo div in un div più grande a tutta altezza.
Lawrence Dol,

8

1. Altezza completa con padding

body {
  margin: 0;
}
.container {
  min-height: 100vh;
  padding: 50px;
  box-sizing: border-box;
  background: silver;
}
<div class="container">Hello world.</div>

2. Altezza completa con margin

body {
  margin: 0;
}
.container {
  min-height: calc(100vh - 100px);
  margin: 50px;
  background: silver;
}
<div class="container">Hello world.</div>

3. Altezza completa con border

body {
  margin: 0;
}
.container {
  min-height: 100vh;
  border: 50px solid pink;
  box-sizing: border-box;
  background: silver;
}
<div class="container">Hello world.</div>


7

Questa è una delle vere e proprie idiocie dei CSS: devo ancora capire il ragionamento (se qualcuno lo sa, per favore, spiega).

100% indica il 100% dell'altezza del contenitore, a cui vengono aggiunti margini, bordi e imbottiture. Quindi è effettivamente impossibile ottenere un contenitore che riempia il suo genitore e che abbia un margine, un bordo o un'imbottitura.

Nota anche che l'impostazione dell'altezza è notoriamente incoerente tra i browser.


Un'altra cosa che ho imparato da quando ho pubblicato questo è che la percentuale è relativa alla lunghezza del contenitore , cioè alla sua larghezza, rendendo una percentuale ancora più inutile per l'altezza.

Al giorno d'oggi, le unità di visualizzazione vh e vw sono più utili, ma non sono particolarmente utili per qualcosa di diverso dai contenitori di livello superiore.


Non vi è alcun ragionamento, proprio quello che è successo quando i browser hanno iniziato a convergere verso comportamenti coerenti. Dai un'occhiata al libro menzionato nella mia risposta.
Frank Schwieterman,

Eseguito l'upgrade per l'utilizzo del termine corretto. Tex e qualsiasi gestore del layout che ho visto hanno capito bene, solo i CSS devono essere speciali.
maaartinus,

5

Un'altra soluzione consiste nell'utilizzare display: table che presenta un comportamento del modello box diverso.

È possibile impostare un'altezza e una larghezza per il genitore e aggiungere imbottitura senza espanderla. Il bambino ha il 100% di altezza e larghezza meno le imbottiture.

JSBIN

Un'altra opzione sarebbe quella di utilizzare la proprietà di ridimensionamento delle scatole. L'unico problema con entrambi sarebbe che non funzionano in IE7.


4

Un'altra soluzione: è possibile utilizzare unità percentuali per margini e dimensioni. Per esempio:

.fullWidthPlusMargin {
    width: 98%;
    margin: 1%;
}

Il problema principale qui è che i margini aumenteranno / diminuiranno leggermente con la dimensione dell'elemento genitore. Presumibilmente la funzionalità che preferiresti è che i margini rimangano costanti e che l'elemento figlio cresca / riduca per riempire le modifiche alla spaziatura. Quindi, a seconda di quanto stretto sia necessario il display, ciò potrebbe essere problematico. (Vorrei anche un margine inferiore, come lo 0,3%).


3

Una soluzione con flexbox (funzionante su IE11): ( o vista su jsfiddle )

<html>
  <style>
    html, body {
      height: 100%; /* fix for IE11, not needed for chrome/ff */
      margin: 0; /* CSS-reset for chrome */
    }
  </style>
  <body style="display: flex;">
    <div style="background-color: black; flex: 1; margin: 25px;"></div>
  </body>
</html>

( Ripristino CSS non è necessariamente importante per il problema reale.)

La parte importante è flex: 1(in combinazione con display: flexal genitore). Stranamente, la spiegazione più plausibile che conosco per come funziona la proprietà Flex proviene da una documentazione nativa, quindi mi riferisco comunque ad essa :

(...) flex: 1, che dice a un componente di riempire tutto lo spazio disponibile, condiviso uniformemente tra gli altri componenti con lo stesso genitore


2

L'esempio di Frank mi ha confuso un po '- non ha funzionato nel mio caso perché non ho ancora capito il posizionamento abbastanza bene. È importante notare che l'elemento contenitore padre deve avere una posizione non statica (ha menzionato questo, ma l'ho trascurato, e non era nel suo esempio).

Ecco un esempio in cui il bambino, dato l'imbottitura e un bordo, usa il posizionamento assoluto per riempire il genitore al 100%. Il genitore utilizza il posizionamento relativo per fornire un punto di riferimento per la posizione del bambino rimanendo nel flusso normale: l'elemento successivo "più contenuto" non è interessato:

#box {
    position: relative;
    height: 300px;
    width: 600px;
}

#box p {
    position: absolute;
    border-style: dashed;
    padding: 1em;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
<div id="box">
  <p>100% height and width!</p>
</div>
<div id="more-content">
</div>

Un collegamento utile per l'apprendimento rapido del posizionamento CSS


0

Bordo attorno al div, anziché al margine del corpo della pagina

Un'altra soluzione: volevo solo un semplice bordo attorno al bordo della mia pagina e volevo un'altezza del 100% quando il contenuto era più piccolo di quello.

Border-box non funzionava e il posizionamento fisso sembrava errato per una necessità così semplice.

Ho finito per aggiungere un bordo al mio contenitore, invece di fare affidamento sul margine del corpo della pagina - sembra così:

body, html {
    height: 100%;
    margin: 0;
}

.container {
    width: 100%;
    min-height: 100%;
    border: 8px solid #564333;
}

0

Questo è il comportamento predefinito di display: blockIl modo più veloce per risolverlo nel 2020 è impostare un display: 'flex'elemento genitore e un'imbottitura, ad esempio 20px, quindi tutti i suoi figli avranno un'altezza del 100% rispetto alla sua altezza.


0

Aggiungere -webkit e -moz sarebbe più appropriato

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

-2
  <style type="text/css">
.stretchedToMargin {
    position:absolute;
    width:100%;
    height:100%;

}
</style>
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.