Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make scrollable div take up remaining height

I'm trying to make a page with a very simple layout: a header that stays in one place, and content that scrolls under it. The header div will be an unknown height that shows all of its content. I want the content div to take up all of the space between the bottom of the header and the bottom of the page AND to be able to scroll.

I have a couple of constraints on this:

  • I don't want to use fixed or absolute positioning to keep the header in place, but rather have a div of the perfect height display the content, and have only that div be scrollable
  • I don't want to set max-height, or any other property that requires knowledge of the height of the header div

The two methods that I have explored to achieve this are using a table layout and using a flex box. I have not managed to get scrolling working with either of these two methods. Below is the code for both attempts. I am using React. Any pointers would be greatly appreciated. Thanks!!

EDIT: I did do this successfully using inline styles and measuring the height of the header after it was generated. This worked on chrome on desktop, android chrome, and android browser, but it broke in ios safari. I don't know why it broke, and I am working on debugging, but I would prefer a cleaner solution that doesn't require inline styles. Thanks!

the react element:

var SimpleScrolly = React.createClass({
    render: function(){
        var lorem = "Lorem ipsum dolor sit amet... ";
        var sampleText = lorem + lorem + lorem + lorem;
        var sampleHeader = "this is a header!"

        return(
            <div className={"simple_scrolly"}>
                <div className={"header"}>
                    {sampleHeader}
                </div>
                <div className={"content"}>
                    {sampleText}
                </div>
            </div>
            );
    }
});

styling for table layout:

.simple_scrolly{

  display: table;
  height: 100%;

  .header{
    display: table-row;
  }

  .content{
    overflow: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    display: table-row;
  }
}

styling for flex layout:

.simple_scrolly{

  display:flex;
  flex-direction: column;
  align-items: flex-start;

  .header{
    flex-grow:0;
  }

  .content{
    overflow: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    flex-grow:1;
  }
}
like image 299
kat Avatar asked Dec 11 '14 21:12

kat


Video Answer


1 Answers

It's actually quite doable without JS. You can easily do this with flex-box using a little "hack".

I worked on top of your flex box example, you can see it yourself in this little pen I made http://codepen.io/elleestcrimi/pen/LENQvr

The whole idea is this:

  1. The header has flex-grow: 0 //This only fills up space as much as the content
  2. The content has flex-grow: 1 //This way this fills up the space even if there is no content
  3. Place all the children of content into a new div called #inner-content
  4. You absolutely place the #inner-content to fill up #content, and you allow it to scroll.
  5. Tada!

Here is code below:

#header {
  flex-grow: 0;
}

#content {
  overflow: hidden;
  flex-grow: 1;
  position: relative;
}

#inner-content {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: auto;
}

body {
  display: flex;
  flex-direction: column;
  height: 100%; // this is needed if you are using any other element
}
like image 123
hyounis Avatar answered Sep 18 '22 18:09

hyounis