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.