0

Edit: Thanks to Temani Afif's suggestion for helping me figure this out. The solution was to use a Flex Layout. One flex item is the navbar, and the other is a div with min-height set to 0. This holds an img whose max-height is set to 100%. All parents of the flex container must have height set to 100%.

The goal of my page is to be a simple image viewer, with a navbar and an image below the navbar that fits in the remaining vertical height of the page. This is simple enough when the height of the navbar is fixed, because one can calculate the maximum image height given the navbar height:

* {
  margin: 0px;
}
#navbar {
  max-height: 50px;
  padding: 5px;
}

img {
    max-height: calc(100vh - 55px);
    max-width: 100%;
}
<div id="navbar">
   <h1>Navbar Contents</h1>
</div>
<img src="https://i.imgur.com/qtWpvMX.jpeg"/>

However, I don't want to have to manually set a height for my navbar, or have to manually adjust the calc expression every time that height changes. Another way that almost works is to set the max-height of the image to "inherit" but that only works when its parent height is known. I want to be able to let the height of my navbar to be set automatically based on what its contents are and for the image to fill the rest of the vertical space without overflowing it. How can I accomplish this?

Here are a some examples from Make a div fill the height of the remaining screen space that don't work because those answers only work for text, or when having a scrollbar is acceptable

Using flexbox (top answer) edit: now with min-height added, which doesn't do anything

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

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

.box .row.header {
  flex: 0 1 auto;
}

.box .row.content {
  flex: 1 1 auto; 
  min-width: 0;
  min-height; 0;
}
<div class="box">
  <div class="row header">
    <p><b>header</b>
      <br />
      <br />(sized to content)</p>
  </div>
  <div class="row content">
    <img src="https://i.imgur.com/qtWpvMX.jpeg">
  </div>
</div>

Second answer on page is my original example, which uses a fixed offset rather than a dynamic one. Third answer also uses manual sizing. Fourth answer uses a table, but the image still overflows:

*
{
    margin:0;padding:0;    
}
html,body
{
    height:100%;
    width:100%;
}
body
{
    display:table;
}
div
{
    width: 100%;
    display:table-row;

}
div+ div
{
    height:100%;  
}
<div>hello</div>
<div>
<img src="https://i.imgur.com/qtWpvMX.jpeg"/>
</div>

I am not sure how I could use Flexbox, Table, or anything else to accomplish my goal.

Luke Sedillo
  • 1
  • 1
  • 3
  • to the solution you picked (the flexbox one) add `min-height: 0;` to row content – Temani Afif Jul 06 '21 at 22:15
  • @TemaniAfif I applied `min-height: 0;` to the flexbox solution like so: `* { min-width: 0; min-height: 0; } ` and the image still overflowed the page. – Luke Sedillo Jul 06 '21 at 22:59
  • https://jsfiddle.net/obnxjeys/ – Temani Afif Jul 06 '21 at 23:19
  • @TemaniAfif Oh wow that finally worked, thank you! Using a min-height flex item to hold a max-height img wouldn't have occurred to me. I also didn't realize that all the parent elements of the img element had to have height set to 100% for this to work (excluding flex items). – Luke Sedillo Jul 07 '21 at 00:58

0 Answers0