3

I'm trying to get a flexbox with a navigation header and a scrollable content area to work correctly. The area I want to be able to do this is part of a larger page that includes other elements, so I'm interested in wrapping the flex area in a parent tag so only these two elements are affected.

I'm so close! Here's the fiddle of what I've done so far: http://jsfiddle.net/AurumPotabile/pv9abdax/

The demo has exactly the functionality I'm looking for, but the structure is off because right now it seems to require the html, body style. As soon as I uncomment the opening and closing flexArea tags in the HTML and change the style reference accordingly I lose the percentage sizing on dbList that forces it to expand to the window's height.

How do I wrap the flexible divs so dbList retains the sizing I'm looking for?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
AurumPotabile
  • 431
  • 1
  • 6
  • 17

2 Answers2

2

You were indeed close. Set the flex div to flex and give it 100% height.

Working snippet to follow:

html, body {
  height: 97%;
  display: flex;
  flex-direction: column;
}

#navList {
  text-align: center;
  padding: 10px 0;
  background-color: red;
}

#dbList {
  flex-grow: 1;
  overflow: auto;
  background-color: aqua;
}

.flexArea {
    height: 100%;
    display: flex;
    flex-direction: column;
}
<div class="flexArea">
  <div id="navList">A | B | C | D</div>
  <div id="dbList">This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine. This is my div. There are many like it, but this one is mine.END</div>
</div> 

Explanation:

If you don't set the height of a div, the default values will be auto. your flexBox will therefore adapt to its content. If the content is bigger then the browser window, the flexBox will have to scroll in order to fit. If you set its height to 100%, the flexBox will fit its container (body in this case) and its content will scroll instead.

Percentage height expresses the height relatively to the parent box as documented on MDN:

The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to auto. A percentage height on the root element is relative to the initial containing block.

Alain1405
  • 2,259
  • 2
  • 21
  • 40
  • Thank you both for the assistance. The problem I'm facing now is that I'm trying to drop the working styles and HTML into a SharePoint page, and something about the page structure has me right back to the same problem. I'm not sure if this requires a separate question, but thought I'd mention it here in case you have any immediate ideas. Does the outer element (html and body in the fiddle) need to be the immediate parent of flexArea? I've tried several different approaches without any appreciable success. Sadly I'm not sure a code posting here will help. – AurumPotabile Oct 09 '15 at 03:41
  • 1
    I figured it out, and the MDN excerpt above is to thank for it. I simply added position: absolute to the wrapper div and everything fell into place. – AurumPotabile Oct 09 '15 at 10:06
1

This may be more an issue of how percentage heights work in CSS, rather than how to wrap flex items or a flex container.

Your un-commented code is fine. You've created a solid structure for a flexbox layout.

Your HTML:

<div class="flexArea">
    <div id="navList">A | B | C | D</div>
    <div id="dbList">This is my div. There are many like it... </div>
</div>

The reason your layout breaks when you un-comment the container div (.flexArea) is because you aren't specifying a height for the div, as required for elements that are not absolutely positioned when using percentage heights.

Essentially, if you want to use percentage heights, you must specify the height of all parent elements, up to and including the body and root element (html). So because no height was being declared for .flexArea, you were losing the height you wanted.*

Once you un-comment the HTML code and make the following adjustments to your CSS, the flexbox appears to work as you want.

CSS

html, body {
  height: 97%;
}

.flexArea {
    height: 100%;
    display: flex;
    flex-direction: column;
}

DEMO: http://jsfiddle.net/pv9abdax/5/

* For a clear understanding of how percentage heights work in CSS see my answer here: Working with the CSS height property and percentage values

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701