cssfooterreactjsjsx

How to make a sticky footer in react?


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?


Solution

  • 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