Come allineare il contenuto di un div in fondo


1164

Supponiamo che io abbia il seguente codice CSS e HTML:

#header {
  height: 150px;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines)
</div>

La sezione dell'intestazione è fissa, ma il contenuto dell'intestazione può cambiare.

Vorrei che il contenuto dell'intestazione fosse allineato verticalmente alla parte inferiore della sezione dell'intestazione, quindi l'ultima riga di testo "si attacca" alla parte inferiore della sezione dell'intestazione.

Quindi se c'è solo una riga di testo, sarebbe come:

-----------------------------
| Titolo dell'intestazione
|
|
|
| contenuto dell'intestazione (risultante in una riga)
-----------------------------

E se ci fossero tre linee:

-----------------------------
| Titolo dell'intestazione
|
| contenuto dell'intestazione (che è così
| molte cose che perfettamente
| si estende su tre righe)
-----------------------------

Come si può fare in CSS?

Risposte:


1323

Il posizionamento relativo + assoluto è la soluzione migliore:

#header {
  position: relative;
  min-height: 150px;
}

#header-content {
  position: absolute;
  bottom: 0;
  left: 0;
}

#header, #header * {
  background: rgba(40, 40, 100, 0.25);
}
<div id="header">
  <h1>Title</h1>
  <div id="header-content">Some content</div>
</div>

Ma potresti riscontrare problemi con questo. Quando l'ho provato ho avuto problemi con i menu a discesa visualizzati sotto il contenuto. Non è carino.

Onestamente, per problemi di centraggio verticale e, beh, qualsiasi problema di allineamento verticale con gli oggetti non è fisso in altezza, è più semplice usare solo le tabelle.

Esempio: puoi fare questo layout HTML senza usare le tabelle?


4
In realtà ho trovato quella soluzione prima di chiedere qui, ma in qualche modo ho dimenticato di aggiungere la posizione: relativo; all'intestazione div e il contenuto continuava ad atterrare nella parte inferiore della pagina. Grazie
kristof il

15
Puoi gestire la tua posizione a discesa con la proprietà z-index per portarla in primo piano. Ricorda che la proprietà z-index funziona con elementi posizionati relativamente o assolutamente. Inoltre, non è corretto semanticamente parlando di utilizzare una tabella per ottenere risultati di layout.
Alejandro García Iglesias,

1
Nel caso del contenuto del testo come descritto nel problema originale, # header-content dovrebbe davvero essere un pelemento, o almeno unspan
Josh Burgess,

2
Non utilizzare le tabelle per dati non tabulari! Utilizzare invece le proprietà di visualizzazione CSS display: table-cell, o table-row, o table. Non è più necessario utilizzare le tabelle per il layout puro.
Jeremy Moritz,

1
La posizione dell'intestazione è relativa a cosa?
stack1

158

Usa posizionamento CSS:

/* Creates a new stacking context on the header */
#header {
  position: relative;
}

/* Positions header-content at the bottom of header's context */
#header-content {
  position: absolute;
  bottom: 0;
}

Come notato da Cletus , è necessario identificare il contenuto dell'intestazione per farlo funzionare.

<span id="header-content">some header content</span>

<div style="height:100%; position:relative;">
    <div style="height:10%; position:absolute; bottom:0px;">bottom</div>
</div>

4
a proposito ... questo ha causato il crollo della sua larghezza del contenuto dell'intestazione, quindi ho dovuto aggiungere un width = '100%'contenuto nel contenuto dell'intestazione
dsdsdsdsd

2
@dsdsdsdsd Puoi anche risolvere il problema aggiungendo display: block a # header-content.
Patrick McElhaney,

1
@dsdsdsdsd Il motivo è perché gli <span>elementi hanno display: inline;per impostazione predefinita, che non occupa l'intera larghezza del contenitore. La soluzione più appropriata sarebbe quella di cambiare lo span in a <div>, che è un elemento a blocchi di default.
BadHorsie,

1
Oppure uno tra <h1> - <h6>, anch'esso bloccato per impostazione predefinita e identifica il testo come intestazione, utile per i motori di ricerca, le tecnologie assistive e le persone che leggono il codice.
Patrick McElhaney,

Non funziona quando il contenuto nella parte inferiore ha un'altezza variabile, ne provoca l'estensione al di fuori dei limiti del contenitore.
Mozfet,

126

Se non sei preoccupato per i browser legacy, usa un flexbox.

L'elemento genitore deve impostare il tipo di visualizzazione su flessibile

div.parent {
  display: flex;
  height: 100%;
}

Quindi imposti l'allineamento dell'elemento figlio su flex-end.

span.child {
  display: inline-block;
  align-self: flex-end;
}

Ecco la risorsa che ho usato per imparare: http://css-tricks.com/snippets/css/a-guide-to-flexbox/


@bafromca, due motivi che non funzionano. 1: usa 'align-self' invece di align-items (colpa mia, ho modificato il mio post originale). 2: l'altezza del 100% non funzionerà a meno che il genitore non abbia l'altezza.
Lee Irvine,

Non ha funzionato per me, lo voglio nella parte inferiore del contenitore, non alla fine degli articoli nel contenitore.
Mozfet,

Nel 2020 questa dovrebbe essere la risposta corretta: caniuse.com/#feat=flexbox
tonygatta

119

Uso queste proprietà e funziona!

#header {
  display: table-cell;
  vertical-align: bottom;
}

42
Non è supportato in IE8 e precedenti. È supportato in IE9.
random_user_name

23
@cale_b Secondo caniuse.com esso FA lavoro in IE8.
Zach Lysobey,

5
@ZachL Happenstance - Sto supportando un'app legacy in IE8 per un cliente aziendale e questo in effetti funziona.
Daniel Szabo,

4
@fguillen: testato in Chrome (v31) anche adesso. Funziona anche lì.
Daniel Szabo,

5
table-cellrompe molte cose. Come il sistema a griglia Bootstrap. col-md-12non ti darà più un div ampio al 100%.
Noè, il

65

Dopo aver lottato con questo stesso problema per qualche tempo, ho finalmente capito una soluzione che soddisfa tutti i miei requisiti:

  • Non richiede che conosca l'altezza del contenitore.
  • A differenza delle soluzioni relative + assolute, il contenuto non fluttua nel proprio livello (cioè si incorpora normalmente nel div contenitore).
  • Funziona su tutti i browser (IE8 +).
  • Semplice da implementare.

La soluzione ne prende solo una <div>, che io chiamo "allineatore":

CSS

.bottom_aligner {
    display: inline-block;
    height: 100%;
    vertical-align: bottom;
    width: 0px;
}

html

<div class="bottom_aligner"></div>
... Your content here ...

Questo trucco funziona creando un div alto e magro, che spinge la linea di base del testo verso il fondo del contenitore.

Ecco un esempio completo che realizza ciò che l'OP stava chiedendo. Ho reso il "bottom_aligner" spesso e rosso solo a scopo dimostrativo.

CSS:

.outer-container {
  border: 2px solid black;
  height: 175px;
  width: 300px;
}

.top-section {
  background: lightgreen;
  height: 50%;
}

.bottom-section {
  background: lightblue;
  height: 50%;
  margin: 8px;
}

.bottom-aligner {
  display: inline-block;
  height: 100%;
  vertical-align: bottom;
  width: 3px;
  background: red;
}

.bottom-content {
  display: inline-block;
}

.top-content {
  padding: 8px;
}

HTML:

<body>
  <div class="outer-container">
    <div class="top-section">
      This text
      <br> is on top.
    </div>
    <div class="bottom-section">
      <div class="bottom-aligner"></div>
      <div class="bottom-content">
        I like it here
        <br> at the bottom.
      </div>
    </div>
  </div>
</body>

Allinea il contenuto inferiore


Quasi perfetto :) ma non consente interruzioni di riga automatiche.
Gaston Sanchez,

Non funziona se il contenitore esterno può scorrere (overflow-y: auto). :(
ecraig12345,

Immagino che Marin: 8px dovrebbe essere margine: 8px
Graham Perrin

2
Questo funziona anche se inserito in una ::beforeregola, che elimina la necessità di un elemento aggiuntivo. Alla fine abbiamo usato il flex, ma è utile quando non puoi.
Sheepy,

Questa è davvero una bella soluzione. Funziona solo se la heightcasella / contenitore e i relativi genitori sono impostati (su px o% o altro).
BairDev,

38

Il modo moderno per farlo sarebbe usare la flexbox . Vedi l'esempio sotto. Non è nemmeno necessario racchiuderlo Some text...in nessun tag HTML, poiché il testo contenuto direttamente in un contenitore flessibile è racchiuso in un elemento flessibile anonimo.

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>

Se è presente solo del testo e si desidera allineare verticalmente alla parte inferiore del contenitore.

section {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  align-items: flex-end;           /* bottom of the box */
}
<section>Some text aligns to the bottom</section>


2
Avevo bisogno che il mio elemento allineato in basso fosse ancora presente nel flusso del documento, cosa impossibile durante l'utilizzo position:absolute;. Questa soluzione ha funzionato perfettamente per il mio caso!
Swen,

1
All'interno di reagire ai componenti, questa è la soluzione giusta. La soluzione accettata ha esito negativo.
Soleil - Mathieu Prévot,

1
Questa è l'unica soluzione che ha funzionato davvero per me. Forse ha a che fare con React, come ha detto @Soleil ... Non sono un esperto CSS, quindi non ne sono del tutto sicuro.
BK,

Funziona perfettamente con il componente
reattivo

25

Gli elementi di blocco inline o inline possono essere allineati alla parte inferiore degli elementi a livello di blocco se l'altezza della linea dell'elemento parent / block è maggiore di quella dell'elemento inline. *

markup:

<h1 class="alignBtm"><span>I'm at the bottom</span></h1>

css:

h1.alignBtm {
  line-height: 3em;
}
h1.alignBtm span {
  line-height: 1.2em;
  vertical-align: bottom;
}

* assicurati di essere in modalità standard


25
display: flex;
align-items: flex-end;

2
Si noti che flexbox non è ben supportato nei vecchi browser.
Anthony B,

11
@AnthonyB - definisci vecchio? Dobbiamo modificare questo record come sviluppatori. La tecnologia va avanti e il vecchio semplicemente non sopravvive. IE9 e 10 hanno problemi con il flex da quello che posso vedere, ma sono stati rilasciati rispettivamente nel 2011 e 2012 ... è il 2017. Dobbiamo lasciare andare questi browser obsoleti e rotti. Se non per soddisfazione visiva, ma per aggiornamenti di sicurezza e software generali.
Tisch,

3
@Tisch hai assolutamente ragione, come sviluppatori, dobbiamo usare una tecnologia decente e recente. Ma avvertirei semplicemente questo problema di compatibilità, per non essere sorpreso.
AnthonyB,

se il contenuto sotto il <h1>è all'interno di un <p>o <div>vorrei utilizzare justify-content: space-between.
agapitocandemor

11

Puoi semplicemente raggiungere la flessibilità

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>


6

Se disponi di più elementi di altezza dinamica, utilizza i valori di visualizzazione CSS di tabella e cella di tabella:

HTML

<html>
<body>

  <div class="valign bottom">
    <div>

      <div>my bottom aligned div 1</div>
      <div>my bottom aligned div 2</div>
      <div>my bottom aligned div 3</div>

    </div>
  </div>

</body>
</html>

CSS

html,
body {
  width: 100%;
  height: 100%;
}
.valign {
  display: table;
  width: 100%;
  height: 100%;
}
.valign > div {
  display: table-cell;
  width: 100%;
  height: 100%;
}
.valign.bottom > div {
  vertical-align: bottom;
}

Ho creato una demo di JSBin qui: http://jsbin.com/INOnAkuF/2/edit

La demo ha anche un esempio di come allineare verticalmente il centro usando la stessa tecnica.


5

Ecco un'altra soluzione che utilizza flexbox ma senza utilizzare flex-end per l'allineamento inferiore. L'idea è di impostare margin-bottomsu h1 su auto per spingere il contenuto rimanente verso il basso:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header h1 {
 margin-bottom:auto;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines) Header content (one or multiple lines)Header content (one or multiple lines) Header content (one or multiple lines)
</div>

Possiamo anche fare lo stesso con margin-top:autoil testo, ma in questo caso dobbiamo avvolgerlo dentro a divo span:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header span {
 margin-top:auto;
}
<div id="header">
  <h1>Header title</h1>
  <span>Header content (one or multiple lines)</span>
</div>


Perfecto! grazie
Grace Nikole,

4

Non hai bisogno di assoluto + relativo per questo. È molto possibile usare la posizione relativa sia per il contenitore che per i dati. Questo è come lo fai.

Supponi che l'altezza dei tuoi dati sarà x. Il contenitore è relativo e anche il piè di pagina è relativo. Tutto quello che devi fare è aggiungere ai tuoi dati

bottom: -webkit-calc(-100% + x);

I tuoi dati saranno sempre nella parte inferiore del contenitore. Funziona anche se hai un contenitore con altezza dinamica.

HTML sarà così

<div class="container">
  <div class="data"></div>
</div>

CSS sarà così

.container{
  height:400px;
  width:600px;
  border:1px solid red;
  margin-top:50px;
  margin-left:50px;
  display:block;
}
.data{
  width:100%;
  height:40px;
  position:relative;
   float:left;
  border:1px solid blue;
  bottom: -webkit-calc(-100% + 40px);
   bottom:calc(-100% + 40px);
}

Esempio live qui

Spero che sia di aiuto.


Puoi spiegare cosa bottom: -webkit-calc(-100% + x);sta facendo?
mhatch,

@mhatch mantiene il piè di pagina nella parte inferiore del contenitore.
Aditya Ponkshe,

4

Ecco il modo flessibile per farlo. Naturalmente, non è supportato da IE8, come l'utente aveva bisogno 7 anni fa. A seconda di ciò che è necessario supportare, alcuni di questi possono essere eliminati.

Tuttavia, sarebbe bello se ci fosse un modo per farlo senza un contenitore esterno, basta solo allineare il testo all'interno di se stesso.

#header {
    -webkit-box-align: end;
    -webkit-align-items: flex-end;
    -ms-flex-align: end;
    align-items: flex-end;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    height: 150px;
}

4

una soluzione molto semplice, a una riga, è quella di aggiungere l'altezza della linea al div, tenendo presente che tutto il testo del div andrà in fondo.

CSS:

#layer{width:198px;
       height:48px;
       line-height:72px;
       border:1px #000 solid}
#layer a{text-decoration:none;}

HTML:

<div id="layer">
    <a href="#">text at div's bottom.</a>
</div>

tieni presente che questa è una soluzione pratica e veloce quando vuoi solo che il testo all'interno del div scompaia, se devi combinare immagini e cose, dovrai codificare un CSS un po 'più complesso e reattivo


3

se potessi impostare l'altezza del div wrapping del contenuto (# header-content come mostrato nella risposta degli altri), anziché l'intero #header, forse puoi anche provare questo approccio:

HTML

<div id="header">
    <h1>some title</h1>
    <div id="header-content">
        <span>
            first line of header text<br>
            second line of header text<br>
            third, last line of header text
        </span>
    </div>
</div>

CSS

#header-content{
    height:100px;
}

#header-content::before{
  display:inline-block;
  content:'';
  height:100%;
  vertical-align:bottom;
}

#header-content span{
    display:inline-block;
}

mostra su codepen


3

Sembra funzionare:

HTML: sono in fondo

css:

h1.alignBtm {
  line-height: 3em;
}
h1.alignBtm span {
  line-height: 1.2em;
  vertical-align: bottom;
}

3

Tutte queste risposte e nessuna ha funzionato per me ... Non sono un esperto di flexbox, ma è stato abbastanza facile da capire, è semplice e facile da capire e da usare. Per separare qualcosa dal resto del contenuto, inserisci un div vuoto e lascialo crescere per riempire lo spazio.

https://jsfiddle.net/8sfeLmgd/1/

.myContainer {
  display: flex;
  height: 250px;
  flex-flow: column;
}

.filler {
  flex: 1 1;
}
<div class="myContainer">
  <div>Top</div>
  <div class="filler"></div>
  <div>Bottom</div>
</div>

Ciò reagisce come previsto quando il contenuto inferiore non ha dimensioni fisse anche quando il contenitore non ha dimensioni fisse.


3

Ho escogitato un modo molto più semplice di quello che è stato menzionato.

Imposta l'altezza del div dell'intestazione. Quindi, dai uno stile al H1tag come segue:

float: left;
padding: 90px 10px 11px

Sto lavorando su un sito per un cliente e il design richiede che il testo sia in fondo a un certo div. Ho ottenuto il risultato usando queste due linee e funziona benissimo. Inoltre, se il testo si espande, il riempimento rimarrà lo stesso.


1
Farà fluttuare il contenuto su altri contenuti quando si ridimensionano gli schermi utilizzando layout reattivi.
Mozfet,

2

Ho trovato questa soluzione basata su un modello di avvio bootstrap predefinito

/* HTML */

<div class="content_wrapper">
  <div class="content_floating">
    <h2>HIS This is the header<br>
      In Two Rows</h2>
    <p>This is a description at the bottom too</p> 
  </div>
</div>

/* css */

.content_wrapper{
      display: table;
      width: 100%;
      height: 100%; /* For at least Firefox */
      min-height: 100%;
    }

.content_floating{
  display: table-cell;
  vertical-align: bottom;
  padding-bottom:80px;

}

2
#header {
    height: 150px;
    display:flex;
    flex-direction:column;
}

.top{
    flex: 1;
}   

<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>

#header {
    height: 250px;
    display:flex;
    flex-direction:column;
    background-color:yellow;
}

.top{
    flex: 1;
}
<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>


1
Ciò provoca il ridimensionamento del div superiore. Che funziona per i layout di testo di base, ma non funziona quando le cose hanno sfondi, colori e dimensioni da rispettare.
Mozfet,

0

prova con:

div.myclass { margin-top: 100%; }

prova a cambiare% per risolverlo. Esempio: 120% o 90% ... ecc.


Funziona perfettamente con 1 set di contenuti, ma dovrà essere modificato se il contenuto cambia. Se si tratta di contenuti dinamici, non usare questo!
Mike Graf,

0

Il sito che ho appena fatto per un cliente ha richiesto che il testo del piè di pagina fosse un riquadro alto, con il testo in fondo che ho realizzato con un semplice riempimento, dovrebbe funzionare per tutti i browser.

<div id="footer">
  some text here
</div>
#footer {
  padding: 0 30px;
  padding-top: 60px;
  padding-bottom: 8px;
}

1
La tua prima dichiarazione padding: 0 30pxè un po 'ridondante, potresti aver inserito anche padding: 30pxle altre 2 dichiarazioni.
Andrew,

Assolutamente vero, tuttavia sto seguendo le pratiche del mio posto di lavoro.
Nicki L. Hansen,

6
Davvero ?, sembra una cattiva pratica. Basta usare la scorciatoia o essere espliciti ovunque. padding: 60px 30px 8px;, padding: 60px 30px 8px 30px;, Quattro esplicite padding-regole, o addirittura @ suggerimento di TheWaxMann sono tutti superiori - e io sono disposto e in grado di sostenere che uno ;-)
Zach Lysobey

-3

Un perfetto esempio tra browser è probabilmente questo qui:

http://www.csszengarden.com/?cssfile=/213/213.css&page=0

L'idea è sia quella di visualizzare il div in basso, sia di farlo incollare lì. Spesso il semplice approccio farà scorrere il div appiccicoso con il contenuto principale.

Di seguito è riportato un esempio minimo pienamente funzionante. Nota che non è necessario alcun trucco per incorporare div. I numerosi BR servono solo a forzare la visualizzazione di una barra di scorrimento:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #floater {
            background: yellow;
            height: 200px;
            width: 100%;
            position: fixed;
            bottom: 0px;
            z-index: 5;
            border-top: 2px solid gold;
        }

    </style>
</head>


<body>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>


    <div id="floater"></div>
</body>
</html>

Se ti stai chiedendo che il tuo codice potrebbe non funzionare su IE, ricorda di aggiungere il tag DOCTYPE in alto. È fondamentale che questo funzioni su IE. Inoltre, questo dovrebbe essere il primo tag e non dovrebbe apparire nulla al di sopra di esso.


28
Dato che stai dichiarando il tuo documento come XHTML rigoroso, dovresti anche chiudere automaticamente i <br />tag ...
Amos M. Carpenter,

7
@ KarlKildén se ti riferissi al commento di aaamos, sicuramente non è un commento sciocco: pubblicare il documento sopra con la sua intestazione correttacontent-type comporterebbe un errore di analisi XML nel browser che genera.
Rasoio

7
Questa è una brutta pratica! Usa invece CSS!
m93a,

-4

Sembra funzionare:

#content {
    /* or just insert a number with "px" if you're fighting CSS without lesscss.org :) */
    vertical-align: -@header_height + @content_height;

    /* only need it if your content is <div>,
     * if it is inline (e.g., <a>) will work without it */
    display: inline-block;
}

Usare meno rende la risoluzione dei puzzle CSS molto più simile alla codifica che a quella ... Adoro i CSS. È un vero piacere quando puoi cambiare l'intero layout (senza romperlo :) semplicemente cambiando un parametro.


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.