0

I try many similar post like Make a div fill the height of the remaining screen space without any success since it's required a fixed height container and i don't have it

I have similar structure

#content {
  height: 100%;
  display: grid;
  grid-template-rows: auto 1fr;
}

#remaining {
  background-color: red;
}
<body>
  <header>
    variable content
  </header>
  <main>
    variable content
    <div id="pagina-id">
      <h1>Title</h1>
      variable content
      <div class="tabs">
        <ul>
          <li>tab1</li>
          <li>tab2</li>
        </ul>
        <div id="content">
          <div>
            variable content
          </div>
          <div id="remaining">
            content that should take all page's remaining space
          </div>
        </div>
      </div>
    </div>
  </main>
</body>

where #remaining should take all page remaining space. all outer containers are not in my total control since are dynamically generated

i try to set flex or grid to #content div and set it to height 100% without success

gt.guybrush
  • 1,320
  • 3
  • 19
  • 48
  • 1
    `height:100%` means 100% of the parent's height. By default, the height is undefined and calculated to fir-content. 100% of undefined is also still undefined. Look into `vh` (view height) – tacoshy Apr 17 '23 at 09:54
  • i know, but vh is all browser height, i need to take all vertical space minus the already used one that can be variable and not known – gt.guybrush Apr 17 '23 at 10:09
  • Will the structure of the HTML change or not? I mean, is the variable content only in the first `
    ` before `#remaining` ? By the way, I don't really understand why `#content` is inside `
    `. I would have expected it outside of the tabs.
    – Patrick Janser Apr 17 '23 at 10:10
  • no, quite in every section outside `#remaining`. sometime under title there are contents, idem outside `#pagina-id` – gt.guybrush Apr 17 '23 at 10:11

1 Answers1

2

It's really not easy if the structure changes. But as described like you did, it should be possible to use several times flexbox in a column mode as you know almost where the content changes.

It might break some of the rest of the layout of your page because you may have some float or other CSS rules. You'll probably have to adapt a bit.

I added a pagina class to your <div id="pagina-id"> as I expect that the id changes. But you could replace .pagina by [id^="pagina-"] if you cannot change the generated HTML.

/* Change box sizing to simplify matters. */
html {
  box-sizing: border-box;
}
*, *::before, *::after {
  box-sizing: inherit;
}

html {
  font: 16px/1.4 Arial, sans-serif;
  /* You have to set a height to <html> if not
     you cannot get min-height working on <body>. */
  height: 100%;
  background: #eee;
}

body {
  margin: 1em;
  padding: 1em;
  min-height: calc(100% - 2em);
  display: flex;
  flex-direction: column;
  background: white;
  box-shadow: 0 0 .5em rgba(0, 0, 0, 0.2);
}

/* Several childs will have to have the same
   way of growing vertically with a flex in
   column mode. */
main,
.pagina,
.tabs,
#content {
  flex: 1; /* To make it grow vertically */

  /* We also want it to be displayed as flex so
     that we can do the same for the child items. */
  display: flex;
  flex-direction: column;
}

#remaining {
  /* Make it the only cell to grow inside #content. */
  flex: 1;
  /* Visually show that this cell grows vertically. */
  background-color: #f8f8f8;
  background-image: linear-gradient(
    45deg,
    white 25%,
    #f8f8f8 25%,
    #f8f8f8 50%,
    white 50%,
    white 75%,
    #f8f8f8 75%,
    #f8f8f8 100%);
  background-size: 3em 3em;
}
<body>
  <header>
    variable content
  </header>
  <main>
    variable content
    <div id="pagina-id" class="pagina">
      <h1>Title</h1>
      variable content
      <div class="tabs">
        <ul>
          <li>tab1</li>
          <li>tab2</li>
        </ul>
        <div id="content">
          <div>
            variable content
          </div>
          <div id="remaining">
            content that should take all page's remaining space
          </div>
        </div>
      </div>
    </div>
  </main>
</body>

If the structure isn't at all handled by you, then I would switch to some JavaScript code. You'll have to react to all window resize events to re-run the calculation of the height to set to your #remaining element in case the height of the page is lower than the window height. You could use the resize observer in order to detect changes and do this calculation. It's not very clean and sexy but I don't know what else you could do.

Patrick Janser
  • 3,318
  • 1
  • 16
  • 18
  • in this way i have to know all parents structure, what if are not in my own control? i use some library for outer layout that can insert large number of containers. only way is to use js to calc element starting position and available space till the end of the page? – gt.guybrush Apr 17 '23 at 12:09
  • If the HTML structure changes then it will effectively be complicated to solve it without JS. I've added a comment about that in my solution, pointing to the [resize observer](https://www.digitalocean.com/community/tutorials/js-resize-observer). But if you're using a library for the outer layout, why would the structure change? Just put your variable content into some specific `
    ` elements so that you reduce the changes of your global HTML skeleton.
    – Patrick Janser Apr 17 '23 at 12:25