Piè di pagina nella parte inferiore della pagina o del contenuto, a seconda di quale è inferiore


92

Ho la seguente struttura:

<body>
    <div id="main-wrapper">
        <header>
        </header>
        <nav>
        </nav>
        <article>
        </article>
        <footer>
        </footer>
    </div>
</body>

Carico dinamicamente i contenuti <article>utilizzando javascript. Per questo motivo, l'altezza del <article>blocco può cambiare.

Voglio che il <footer>blocco si trovi nella parte inferiore della pagina quando c'è molto contenuto, o nella parte inferiore della finestra del browser quando esistono solo poche righe di contenuto.

Al momento posso fare l'uno o l'altro ... ma non entrambi.

Quindi qualcuno sa come posso farlo: fai <footer>in modo che si attenga alla parte inferiore della pagina / contenuto o alla parte inferiore dello schermo, a seconda di quale è inferiore.


Le persone si preoccuperebbero di commentare perché hanno sconsigliato una domanda vecchia di 2 anni?
Sarà il

Dai, sono passati quasi 6 anni ...
Will il

Risposte:


99

Il piè di pagina appiccicoso di Ryan Fait è molto carino, tuttavia trovo che la sua struttura di base manchi *.


Versione Flexbox

Se sei abbastanza fortunato da poter utilizzare flexbox senza bisogno di supportare browser meno recenti, i piè di pagina appiccicosi diventano banalmente facili e supportano un piè di pagina di dimensioni dinamiche.

Il trucco per far sì che i piè di pagina aderiscano al fondo con flexbox è avere altri elementi nello stesso contenitore che si flettono verticalmente. Tutto ciò che serve è un elemento wrapper a tutta altezza con display: flexe almeno un fratello con un flexvalore maggiore di 0:

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

#main-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

article {
  flex: 1;
}


Se non puoi usare flexbox, la mia struttura di base preferita è:

<div class="page">
  <div class="page__inner">
    <header class="header">
      <div class="header__inner">
      </div>
    </header>
    <nav class="nav">
      <div class="nav__inner">
      </div>
    </nav>
    <main class="wrapper">
      <div class="wrapper__inner">
        <div class="content">
          <div class="content__inner">
          </div>
        </div>
        <div class="sidebar">
          <div class="sidebar__inner">
          </div>
        </div>
      </div>
    </main>
    <footer class="footer">
      <div class="footer__inner">
      </div>
    </footer>
  </div>
</div>

Che non è poi così lontano da:

<div id="main-wrapper">
    <header>
    </header>
    <nav>
    </nav>
    <article>
    </article>
    <footer>
    </footer>
</div>

Il trucco per far sì che il piè di pagina rimanga bloccato è di avere il piè di pagina ancorato al riempimento inferiore del suo elemento contenitore. Ciò richiede che l'altezza del piè di pagina sia statica, ma ho scoperto che i piè di pagina sono in genere di altezza statica.

HTML:
<div id="main-wrapper">
    ...
    <footer>
    </footer>
</div>
CSS:
#main-wrapper {
    padding: 0 0 100px;
    position: relative;
}

footer {
    bottom: 0;
    height: 100px;
    left: 0;
    position: absolute;
    width: 100%;
}

Con il piè di pagina ancorato a #main-wrapper, ora devi #main-wrapperessere almeno all'altezza della pagina, a meno che i suoi figli non siano più lunghi. Questo viene fatto facendo #main-wrapperhanno un min-heightdi 100%. Devi anche ricordare che i suoi genitori htmle bodydevono essere alti quanto la pagina.

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

#main-wrapper {
    min-height: 100%;
    padding: 0 0 100px;
    position: relative;
}

footer {
    bottom: 0;
    height: 100px;
    left: 0;
    position: absolute;
    width: 100%;
}

Ovviamente, dovresti mettere in discussione il mio giudizio, poiché questo codice costringe il piè di pagina a cadere dal fondo della pagina, anche quando non c'è contenuto. L'ultimo trucco è cambiare il modello di scatola usato da in #main-wrappermodo che il min-heightdi 100%includa l' 100pximbottitura.

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

#main-wrapper {
    box-sizing: border-box;
    min-height: 100%;
    padding: 0 0 100px;
    position: relative;
}

footer {
    bottom: 0;
    height: 100px;
    left: 0;
    position: absolute;
    width: 100%;
}

Ed ecco fatto, un piè di pagina appiccicoso con la tua struttura HTML originale. Assicurati solo che footer's heightsia uguale a #main-wrapper' padding-bottomse dovresti essere impostato.


* Il motivo per cui trovo difetti nella struttura di Fait è perché imposta gli elementi .footere .headersu diversi livelli gerarchici aggiungendo un .pushelemento non necessario .


Avevo bisogno di aggiungere #main-wrapper *:first-child { margin-top: 0; }, altrimenti la pagina sarebbe stata troppo lunga dal margine superiore del primo bambino (causando una barra di scorrimento non necessaria su pagine brevi).
Florian Brucker

Grazie, @zzzzBov per questa spiegazione approfondita, e soprattutto per aver menzionato la direzione flessibile (vorrei averlo trovato prima - mi avrebbe risparmiato un paio d'ore! :)
ea0723

La versione Flexbox non funziona per me in IE11, ma l'altro approccio va bene per me! Grazie e +1!
Matt

@ Matt, è necessario utilizzare i prefissi del browser per far funzionare flexbox in IE11. usa uno strumento come l'autoprefixer e non dovrai mai preoccuparti di aggiungerli manualmente.
zzzzBov

2
Il collegamento appiccicoso del piè di pagina sembra essere interrotto perché il suo sito è stato convertito in un avviso In Memoriam per lui. Inoltre, non ci sono versioni memorizzate nella cache a causa delle impostazioni di robots.txt
tzrlk

13

Il piè di pagina appiccicoso di Ryan Fait è una soluzione semplice che ho utilizzato più volte in passato.

HTML di base :

<div class="wrapper">
    <div class="header">
        <h1>CSS Sticky Footer</h1>
    </div>
    <div class="content"></div>
    <div class="push"></div>
</div>
<div class="footer"></div>

CSS :

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
.footer, .push {
    height: 142px; /* .push must be the same height as .footer */
}

/*

Sticky Footer by Ryan Fait
http://ryanfait.com/

*/

Traducendo questo in modo che sia simile a quello che hai già risultati con qualcosa del genere:

HTML :

<body>
    <div class="wrapper">
        <header>
        </header>
        <nav>
        </nav>
        <article>
        </article>
        <div class="push"></div>
    </div>
    <footer>
    </footer>
</body>

CSS:

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
footer, .push {
    height: 142px; /* .push must be the same height as .footer */
}

Non dimenticare di aggiornare il negativo sul margine del wrapper in modo che corrisponda all'altezza del tuo piè di pagina e premi div. In bocca al lupo!


4
Adoro il modo in cui ha messo il commento in fondo, appropriato per una soluzione a piè di pagina: D
Madara's Ghost

Non è necessario modificare il markup per questo particolare stile.
zzzzBov

@zzzzBov Non ho molto tempo per approfondire l'argomento in questo momento, ma cosa intendi esattamente?
Josh Mein

Sono sul mio bancomat mobile quindi non posso scrivere una risposta completa altrimenti l'avrei già fatto. Il commento era più così mi ricordavo di aggiungere una risposta più tardi.
zzzzBov

@ JoshMein, ho aggiunto una risposta che spiega come far aderire il piè di pagina senza interferire con la struttura fornita.
zzzzBov

0

Stavo cercando di risolvere questo problema senza aggiungere alcun markup aggiuntivo, quindi ho finito per utilizzare la seguente soluzione:

article {
  min-height: calc(100vh - 150px); /* deduct the height or margins of any other elements within wrapping container*/
}

footer {
  height: 50px;
}

header {
   height: 50px;
}

nav {
  height: 50px;
}
<body>
  <div id="main-wrapper">
    <header>
    </header>
    <nav>
    </nav>
    <article>
    </article>
    <footer>
    </footer>
  </div>
</body>

Devi conoscere le altezze di intestazione, navigazione e piè di pagina per poter impostare l'altezza minima per l'articolo. In questo modo, se l'articolo ha solo poche righe di contenuto, il piè di pagina si attaccherà alla parte inferiore della finestra del browser, altrimenti andrà sotto tutto il contenuto.

Puoi trovare questa e altre soluzioni pubblicate sopra qui: https://css-tricks.com/couple-takes-sticky-footer/

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.