1

Some context first:

I'm trying to create a scrollable content area. In reality this is a React app that will asynchronously populate the scrollable area with records from a database. But the following is enough to illustrate the issue I'm facing, which is purely styling related.

I have the following html structure:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
  <div class="app">
                <header class="main-head">The header</header>
                <nav class="main-nav">
                </nav>
                <article class="content">
          <div class="component">
              <div>just here as a placeholder to whatever pushes the div below down</div>
              <div class="table-view">
                <div class="table-content-wrapper">
                  <div class="table-content" style="height:1410px;">
                    scrollable rows go here
                  </div>
                </div>
              </div>
          </div>
                </article>
                <footer class="main-footer">The footer</footer>
            </div>
</body>
</html>

And accompanying CSS

index
* {
    box-sizing: border-box;
}

body {
    width: 100vw;
    height: 100vh;
    margin: 0px;
    padding: 0px;
}

.main-head {
    min-width: 0;
    min-height: 0;
  border: 1px solid #ccc;
    grid-area: header;
}

.content {
    min-width: 0;
    min-height: 0;
  border: 1px solid #ccc;
    grid-area: content;
}

.main-nav {
    min-width: 0;
    min-height: 0;
  border: 1px solid #ccc;
    grid-area: nav;
}

.main-footer {
    min-width: 0;
    min-height: 0;
  border: 1px solid #ccc;
    grid-area: footer;
}

.app {
    display: grid;
    grid-gap: 20px;
    grid-template-areas: "header" "nav" "content" "footer";
    grid-template-rows: 1fr 1fr 10fr 1fr;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

@media (min-width: 700px) {
    .app {
        grid-template-columns: 1fr 5fr;
        grid-template-rows: 2fr 25fr 1fr;
        grid-template-areas: "header header" "nav content" "footer footer"
    }

    nav ul {
        flex-direction: column;
    }
}

.component {
  height:100%;
  display:flex;
  flex-flow:column;
}

.table-view {
  height:100%;
  width:100%;
  border: 1px solid #ccc;
  background: #fff;

  display:flex;
  flex-flow:column;
}

.table-content-wrapper {
  flex: 1;
  overflow: auto;
}

.table-content {
  position: relative;
  overflow: hidden;
  width: 100%;
  min-height: 100%;
}

The issue lies with the table's content.

First of all: take note of the explicit style height on the table-content div. This is set dynamically by the React app in order to create an accurate scroll bar on the table-content-wrapper div and is based on the total number of records the dataset contains multiplied by the set row height.

The problem is when table-content-wrapper is in overflow mode, i.e. when there are more records than can be shown in the height that is available. This makes the table-view div stretch to the total height of the component div, as opposed to only taking up the height that is still available in the component div (i.e.: component div height minus placeholder div height).

This is easily demonstrated by running this fiddle and seeing what happens when you remove the explicit height style from the table-content div. You'll see that the height of the table-view div is then reduced by the height taken up by the placeholder div, and as such now accurately stays within the bounds of the content article element. But then obviously there is no more scrolling.

So I guess the question boils down to: how do I make it so that the table-view div does not grow beyond the space that is available in the component div, while allowing the table-content-wrapper div to be in overflow mode using the explicit height style?

UPDATE 1

Going by the first comments, it seems this might be a cannot reproduce in browser X kind of situation; so here is some additional clarification:

  • I am seeing this behavior in both Brave and Chrome, in both normal and privacy mode (extensions are ruled out, I don't have any).
  • This is a screenshot with the height style. You can clearly see the border of the div going out of the content article element with height style
  • This is a screenshot without the height style. You can clearly see the border of the div respecting the content article element bounds without height style
Timothy Degryse
  • 163
  • 1
  • 8
  • This question lacks clarity. Maybe you can break it down, or otherwise simplify it, a bit more. – Michael Benjamin Mar 21 '20 at 13:53
  • How exactly? This is as clear as it gets, I've already dumbed it down as much as I can while maintaining this behavior. Just run the fiddle and see what happens. To summarize again: The `table-view div` should not grow bigger than the remaining space in its parent (therefor remaining inside the bounds of the `content article` element), while allowing its child (`table-content-wrapper div`) to overflow when its child's (`table-content div`) height is set to something higher than the visible space available. – Timothy Degryse Mar 21 '20 at 14:51
  • That's what I mean. Everything you're describing in your question, and in your comment above, appears to be working already. What browser are you using? – Michael Benjamin Mar 21 '20 at 15:49
  • I'm checking in Chrome, and here's what I'm seeing: – Michael Benjamin Mar 21 '20 at 15:56
  • *"The `table-view div` should not grow bigger than the remaining space in its parent..."* Working. – Michael Benjamin Mar 21 '20 at 15:56
  • *"...(therefore remaining inside the bounds of the `content article` element)..."* Working. – Michael Benjamin Mar 21 '20 at 15:57
  • *"...while allowing its child (`table-content-wrapper div`) to overflow when its child's (`table-content div`) height is set to something higher than the visible space available.*" Working. – Michael Benjamin Mar 21 '20 at 15:57
  • I added an update to the OP. You're not seeing what the screenshots there show? – Timothy Degryse Mar 21 '20 at 17:10
  • 1
    Try adding `min-height: 0` to `.table-view`. https://jsfiddle.net/oc7sjy4z/1/ – Michael Benjamin Mar 21 '20 at 17:34
  • Sigh, I always figured it was going to be a one-liner solution, but this just hurts :D Can you explain *why* this works? – Timothy Degryse Mar 21 '20 at 17:38
  • 1
    You already have the `min-width: 0` and `min-height: 0` overrides throughout your code. They replace the `min-width: auto` and `min-height: auto` default settings for flex / grid items. With this default setting, a flex / grid item cannot be smaller than it's content (`auto`) by default. – Michael Benjamin Mar 21 '20 at 17:42
  • 1
    You were just missing this setting in that particular level of items in the hierarchy. It was like a missing link in the chain. – Michael Benjamin Mar 21 '20 at 17:43
  • 1
    Your post is actually discussed in detail in another post. So I'll close your question as a duplicate, if that's okay with you. – Michael Benjamin Mar 21 '20 at 17:44
  • 1
    Also, on a unrelated note, there are syntax errors in your HTML. In the `main-nav` and `table-content` elements, the class attributes are missing the equals sign. – Michael Benjamin Mar 21 '20 at 17:44
  • 1
    Yeah go ahead with the duplicate. I figured this wouldn't be the first, but I didn't really know what to look for as I'm not *that* proficient in the latest CSS stuff, so I posted anyway. Thanks a ton! It makes sense now :) (I'll update the HTML, I clearly threw it together too quickly) – Timothy Degryse Mar 21 '20 at 17:47

0 Answers0