2

At the end of my post I provide the layout for the question.

I have a layout that has two columns, sort of, a navigation sidebar that is not always open (col0) and a main area (col1) that is always open. The main area displays content. Finally, I have a footer that sits right below the highest level of the page.

Inside the main or content area there is a transition component that presents the next routed component using CSS transitions.

What I need to do is to get the footer to be a footer, that is, to be strictly at the bottom of the scroll position of the screen and the containing div. That doesn't mean fixed because you can scroll.

I would like to do this in CSS but I cannot get it to go and I am feeling a bit tempted to have it read the height and update before the component is mounted etc. Is there a better way?

Here is a react Component render() function with plenty of stuff deleted for your convenience:

  <div style={prepareStyles(styles.heightHundred)}>
    <ChromeHelmet />
      <AppBar ... yada .../>
      <div style={prepareStyles(styles.root)}>
        <div style={prepareStyles(styles.content)}>
          <EasyTransition
            path={this.props.location.pathname}
            initialStyle={{opacity: 0, transform: 'translateY(-100%)'}}
            transition="opacity 0.2s ease-in, transform 0.3s ease-in-out 0.3s"
            finalStyle={{opacity: 1, transform: 'translateY(0%)'}}
            leaveStyle={{opacity: 0.9, transform: 'translateY(500%'}}
          >
          { this.props.children }
          </EasyTransition>
        </div>
      </div>
      <AppNavDrawer />
    <Footer
      style={prepareStyles(styles.footer)} />
  </div>

Edit

When I try to use flex I can tell it is close but it has no effect because the sidebar is displayed with position: fixed; and some fancy CSS stuff inside the React component that I'm afraid to touch. But when I undo that position: fixed, the footer is where it needs to be but the sidebar is wonky obviously...

tacos_tacos_tacos
  • 10,277
  • 11
  • 73
  • 126
  • you should use flex-box layout. `display: flex; flex-flow: column: no-wrap;` on the outermost div would solve your issue – John Ruddell Jul 11 '16 at 04:03
  • doh! I am not used to it yet... I mean I haven't yet gotten to thinking, of course,flexboxc – tacos_tacos_tacos Jul 11 '16 at 04:10
  • @JohnRuddell didn't work. I mean, I didnt do it right. Read my edit – tacos_tacos_tacos Jul 11 '16 at 04:20
  • no problem! thats what stack overflow is for :D flexbox is amazing. you should read up on what you can do with it, no more need to use floats and stuff. it also has benefits of where you want to lay the content out. so for instance in this case.. `height: 100%; display: flex; flex-flow: column no-wrap; justify-content: space-between;` is what you want – John Ruddell Jul 11 '16 at 04:21
  • thats just because you didn't specify which way you wanted to justify the content.. see my other comment – John Ruddell Jul 11 '16 at 04:22
  • if you cant figure it out i can do a screenshare voice chat to get it working :) – John Ruddell Jul 11 '16 at 04:27
  • @JohnRuddell checking it out now – tacos_tacos_tacos Jul 11 '16 at 04:42
  • @JohnRuddell you were close - or I was close to describing to you the right situation - it was flex-end That i needed not between but whatever it works! – tacos_tacos_tacos Jul 11 '16 at 04:52
  • nice! space-between works when there are two elements puts the first at the top and the second at the bottom. but i misread you have three elements there so yea. I can write it up as an answer if you want. – John Ruddell Jul 11 '16 at 04:54

2 Answers2

1

What you’re looking for is the CSS Sticky Footer.

The HTML:

<div id="wrap">
  <div id="main">
  </div>
</div>

<div id="footer">
</div>

The CSS:

* {margin:0;padding:0;} 
html, body {height: 100%;}
#wrap {min-height: 100%;}

#main {
  overflow:auto;
  padding-bottom: 180px; /* must be same height as the footer */
}

#footer {
  position: relative;
  margin-top: -180px; /* negative value of footer height */
  height: 180px;
  clear:both;
} 

/*Opera Fix thanks to Maleika (Kohoutec)*/
body:before {
  content:"";
  height:100%;
  float:left;
  width:0;
  margin-top:-32767px;/* thank you Erik J - negate effect of float*/
}
Jez
  • 201
  • 6
  • 18
1

I would recommend using flex-box layout. it is supported by most browsers (IE 10 and up, Edge, Firefox, Chrome, Safari, Opera, iOS Safari, Opera Mini, Android Browser, Chrome for Android).

just add these styles to the parent div

display: flex; 
flex-flow: column no-wrap; 
justify-content: space-between;

on the footer add

align-self: flex-end;

here is a GREAT explanation of flex and how it works. lots of really useful information here

John Ruddell
  • 25,283
  • 6
  • 57
  • 86
  • FYI I did something slightly different without using align at all from http://transmission.vehikl.com/sticky-footer-with-flexbox/ because I think my case was simpler even – tacos_tacos_tacos Jul 11 '16 at 05:00
  • @tacos_tacos_tacos Ok I see what you are saying. I honestly dont really like that solution only because with that you are relying on a specific height for the footer. so on a mobile resolution you need to change the styles for the heights and everything. Flexbox doesn't need specific heights for spacing elements which is why its so nice and easy to use. if you are ok with that solution then awesome :) I can try and help you get it without specifying a height if you'd like :) – John Ruddell Jul 11 '16 at 05:04
  • I just saw this. I'll try your solution now on a new page – tacos_tacos_tacos Jul 21 '16 at 06:35