HTML Formatterhtmlformatteronline.com

Sticky footer

A footer that sits at the bottom of the viewport on short pages and below the content on long ones.

layoutfooterflexboxgridsticky
<div class="page">
  <header>Header</header>

  <main>
    <h1>Short page</h1>
    <p>There is not enough content here to fill the screen, and the footer is still at the bottom.</p>
    <p><button id="more" type="button">Add content</button></p>
  </main>

  <footer>Footer — always at the bottom, never floating over the content</footer>
</div>

How it works

This used to need negative margins, a wrapper div and a hard-coded footer height that broke the moment anyone edited the footer. It is now three lines.

min-height, never height. height: 100dvh caps the page at one screen and the content scrolls inside it or overflows. min-height sets a floor, so the page grows past it when there is more content. This is the whole trick.

flex: 1 on main makes the middle section absorb the leftover space. On a short page that space is real and pushes the footer down; on a long page there is none and the footer simply follows the content.

dvh rather than vh. On mobile browsers 100vh is measured against the viewport with the address bar hidden, so a page sized to it is taller than what you can actually see, and the footer sits just off the bottom of the screen until you scroll. 100dvh tracks the visible area as the bar shows and hides. Browsers without support fall back to treating it as vh, which is the old behaviour rather than a break.

The grid version is equivalent. grid-template-rows: auto 1fr auto does the same job, and is slightly better when you have exactly three regions. Flexbox is easier when the number of sections varies.

This is not position: sticky. The names collide confusingly. position: sticky keeps an element visible while scrolling past it; a "sticky footer" sits at the bottom of the page and does not float over anything.

Accessibility notes

A genuinely fixed footer eats vertical space, which hurts most on a small screen in landscape and for anyone using large text or a screen magnifier. This approach takes no space at all when there is content to fill the page.

The footer is a real <footer> element, so it is exposed as a contentinfo landmark and screen reader users can jump straight to it.

Making it yours

Press the button in the preview to add content and watch the footer stop being pinned. That is the behaviour you want and the reason a fixed footer is the wrong answer.

If you want the footer visible at all times while scrolling, that is position: fixed or position: sticky; bottom: 0 — a different component, and one that costs vertical space on every screen. Worth it for a checkout bar, rarely worth it for a footer.

Related templates

Check your version

Once you have edited this, the HTML validator will catch any tag you left unclosed, and the formatter will tidy the indentation. Both run in your browser.