HTML + CSS layout with bottom box showing all content, variable height top box with scroll


Tags: html,css

Problem :

  • I want two boxes, one on top of the other.
  • The bottom box should take as much height as it needs to display its entire content (I don't know how much height this content will take).
  • The top box should fill the remaining height of the container, generating scroll for its content if necessary.

Working example

This fiddle is a working example of what I described above: https://jsfiddle.net/gabrielmaldi/q258g40y/

HTML:

<div class="container">
  <div class="my-component">
    <div class="my-component_top-content">
      Variable content that should fill the container and scroll.
    </div>
    <div class="my-component_bottom-content">
      Variable content that should extend in height as much as needed.
    </div>
  </div>
</div>

CSS:

.container {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 320px;
}

.my-component {
  display: table;
  height: 100%;

  background-color: lightblue;
}

.my-component_top-content {
  display: table-row;
  height: 100%;
  float: left;
  overflow-y: auto;

  background-color: green;
}

.my-component_bottom-content {
  display: table-row;
  height: 0;

  background-color: orange;
}

This works fine in Chrome (up until version 49) and Safari. The problem is that it breaks in Chrome 50 and above (you can browse the fiddle in Chrome Canary and see for yourself).

I filed this issue: https://bugs.chromium.org/p/chromium/issues/detail?id=594376 and there's been some discussion going on. But maybe this isn't a regression in Chrome as per the CSS spec (the Chrome 49 behavior doesn't match Firefox, while the Chrome 50 behavior does).

I haven't been able to find a way to achieve what I want that works in Chrome Canary (or Firefox, which although I don't specifically need to support, maybe a layout that works in Firefox will also work in newer Chrome versions).

So, how could I achieve what I described in the three initial bullets, and which works in Safari, Chrome 49, and Chrome 50 (Canary)?

EDIT: I need to support older Android Stock Browser, so it's best if this can be achieved without display: flex; which doesn't have very good support there.

Thanks!



Solution :

Update based on comment/requirement for older browser support, here is a display: table version

Update 2 and does now work on Webkit (Canary inlcuded), Firefox, Edge, IE11

html, body {
  margin: 0;
  height: 100%;
}
.container {
  height: 100%;
}
.my-component {
  display: table;
  height: 100%;
  width: 100%;
}
.my-component-top {
  display: table-row;
  background-color: yellow;
  height: 100%;
}
.my-component-top-cell {
  display: table-cell;
  height: 100%;
  position: relative;
}
  /* IE11 fix - need block */
  _:-ms-fullscreen, :root .my-component-top-cell { display: block; }

.my-component-top-inner {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
}
.my-component-bottom {
  display: table-row;
  background-color: green;
}
<div class="container">
  <div class="my-component">
    <div class="my-component-top">
      <div class="my-component-top-cell">
        <div class="my-component-top-inner">
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
          Variable content that should fill the container and scroll.<br>
        </div>
      </div>
    </div>
    <div class="my-component-bottom">
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
    </div>
  </div>
</div>


For modern browsers, use flex like this, where the top box has flex: 1 to fill the remaining space and bottom box has flex: 0 to make it take as little as possible of the available space.

Also I added a min-height: 20px; on the top box in case the content in the bottom box gets to big (prevent it from disappear completely).

html, body {
  margin: 0;
  height: 100%;
}

.container {
  height: 100%;
}
.my-component {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.my-component_top-content {
  background-color: yellow;
  overflow: auto;
  flex: 1;
  min-height: 20px;
}

.my-component_bottom-content {
  background-color: green;
  flex: 0;
}
<div class="container">
  <div class="my-component">
    <div class="my-component_top-content">
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
      Variable content that should fill the container and scroll.<br>
    </div>
    <div class="my-component_bottom-content">
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
      Variable content that should extend in height as much as needed.<br>
    </div>
  </div>
</div>


    CSS Howto..

    How to change 'inherited' font families using the CSS style sheet

    How to change the font size in table cells according to cells content?

    How do let CSS change the inset shadow on li hover, instead of resetting it?

    Vaadin - How to customize MenuBar to look like links

    show hidden div below current row of divs in responsive layout with jquery

    Show content on and off with Javascript

    HTML/CSS How to prevent highlighting text from spanning entire width of page in google chrome

    How to remove space above and below the in-line block elements?

    How to make a border colorful using CSS?

    CSS - How to center a DIV menu

    How can I workaround this CSS anomaly?

    How to increase Page Width with the Help of CSS?

    How to use HTC behavior in jQuery CSS for IE?

    ASP.NET - How to include CSS only if it isn't alrealy included?

    How to get CSS left property value on second element of anchor

    Tricky: In CSS and HTML, how to make a sub DIV go under the container if the container has a z-index of 0?

    How can i add a preload function for my images?

    How can I insert text before an item with CSS?

    How to put an image at the left side of text without putting the image into css

    How to add css to jquery backstretch?

    How to make a box expand a distance from the sides

    How can I configure this gulpfile the right way to have a nice workflow

    How to Highlight a list item after user clicks on link

    How to inject css in another page

    how to order CSS elements?

    How to remove pseudo-element styles from the first element?

    How to fit CSS buttons into table cells?

    CSS gone wild - how to stop a style from going too far

    CSS: How to define a centered div with endless vertical borders and an initial height of 100%?

    how to change CSS on the youtube subscribe widget