How to make a sticky footer in react?

105,054

Solution 1

Here's an idea (sandbox example link).

Include a phantom div in your footer component that represents the footer's position that other dom elements will respect (i.e. affecting page flow by not being position: 'fixed';).

var style = {
    backgroundColor: "#F8F8F8",
    borderTop: "1px solid #E7E7E7",
    textAlign: "center",
    padding: "20px",
    position: "fixed",
    left: "0",
    bottom: "0",
    height: "60px",
    width: "100%",
}

var phantom = {
  display: 'block',
  padding: '20px',
  height: '60px',
  width: '100%',
}

function Footer({ children }) {
    return (
        <div>
            <div style={phantom} />
            <div style={style}>
                { children }
            </div>
        </div>
    )
}

export default Footer

Solution 2

Much easier idea (following the trend), i imported both bootstrap and reactstrap, used the bootstrap fixed bottom class and workaround with that like this.

class AppFooter extends Component{
render() {
    return(
        <div className="fixed-bottom">  
            <Navbar color="dark" dark>
                <Container>
                    <NavbarBrand>Footer</NavbarBrand>
                </Container>
            </Navbar>
        </div>
    )
}

Solution 3

There is a much simpler way. I am creating a portfolio site with React, and some of my pages are not very long, so in some devices, like kindle fire hd for example, the footer would not stick to the bottom. And of course to set this up in the traditional fashion with would not work, because the would be wrapped in there. And we don't want that. So this is what I did:

In App.js:

import React, { Component } from 'react';
import {Header} from './components/Header';
import {Main} from './components/Main';
import {Footer} from './components/Footer';

class App extends Component {
    render() {
        return (
            <div className="App Site">
                <div className="Site-content">
                    <div className="App-header">
                        <Header />
                    </div>
                    <div className="main">
                        <Main />
                    </div>
                </div>
                <Footer />
            </div>
        );
    }
}

export default App;

And then in _sticky-footer.css (I use POSTCSS):

:root {
    --space: 1.5em 0;
    --space: 2em 0;
}

.Site {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.Site-content {
    flex: 1 0 auto;
    padding: var(--space) var(--space) 0;
    width: 100%;
}

.Site-content:after {
    content: '\00a0';
    display: block;
    margin-top: var(--space);
    height: 0;
    visibility: hidden;
}

The original solution for this was created by Philip Walton: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/

Solution 4

You can fix this by adding margin-bottom: 60px; to the body of your website. With the 60px being the height of your footer.

Solution 5

.App will be the main component you load to your Root.

Assume that the footer is the last child of .App in the document flow

.App {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

footer {
  margin-top: auto;
}
Share:
105,054
Poliakoff
Author by

Poliakoff

Full-stack developer

Updated on February 04, 2022

Comments

  • Poliakoff
    Poliakoff over 2 years

    I've made a sticky footer higher-level component that wraps other components inside itself:

    Footer.js

    //this is a higher-order component that wraps other components placing them in footer
    
    var style = {
        backgroundColor: "#F8F8F8",
        borderTop: "1px solid #E7E7E7",
        textAlign: "center",
        padding: "20px",
        position: "fixed",
        left: "0",
        bottom: "0",
        height: "60px",
        width: "100%",
    };
    
    const Footer = React.createClass({
        render: function() {
            return (
                <div style={style}>
                    {this.props.children}
                </div>
            );
        }
    });
    
    export default Footer;
    

    Usage:

    <Footer><Button>test</Button></Footer>
    

    But it is hiding the contents of the page:

    hiding contents footer

    This looks like a common problem, so I searched a bit and found this issue, where is FlexBox is recommended for the sticky footer. But at this demo the footer is at the very bottom of the page, while I need the footer to be always displayed on the page and the content being scrolled inside the above area (like in SO chat). In addition to that, there is an advice to change all the other components with custom stylesheet rules. Is it possible to achieve what I need using styling only the footer component so the code will remain modular?