3

I need to make a simple layout where the top area is a variable-sized image and the bottom area should be a variable-height footer, where the content of the footer is

My best attempt so far:

* { padding: 0; margin: 0; }

html, body {
  height: 100%;
  min-height: 100%;
}

.body {
  display: flex;
  min-height: 100%;
}

nav {
  width: 150px;
  flex-shrink: 0;
  background-color: gray;
}

main {
  flex-grow: 1;
 display: flex;
 flex-direction: column;
}

.image {
  flex-grow: 1;
  border: 1px solid blue;
  
  background-image: url('https://www.hawaiimagazine.com/sites/default/files/field/image/plumeria%202%20Eric%20Tessmer%20Flickr.jpg');
 background-size: contain;
 background-repeat: no-repeat;
 background-position: top center;
}

footer {
  border: 1px solid red;
}
<div class="body">
  <nav>side nav</nav>
  <main>
    <div class="image"></div>
    <footer>
      I need this to stay directly below the image but not go beneath the fold
    </footer>
  </main>
</div>

(Resize the preview window both horizontally and vertically, and you'll see that even when the image does not fill the height, the footer does not raise to fill it, either.)

I've tried many different ways, including without flexbox, with grid, and with an <img> tag -- and any of those would be fine in the end. (Just no JS...) I almost had success with an <img> tag and using object-fit: contain but it would push the footer beneath the fold.

EDIT: Updated attempt here (still not solved though):

* { padding: 0; margin: 0; }

html, body {
  height: 100%;
  min-height: 100%;
}

.body {
  display: flex;
  min-height: 100%;
}

nav {
  width: 150px;
  flex-shrink: 0;
  background-color: gray;
}

main {
  flex-grow: 1;
 display: flex;
 flex-direction: column;
}

img {
  max-width: 100%;
 max-height: 80vh;
  object-fit: contain;
}

footer {
  height: 20vh;
  border: 1px solid red;
}
<div class="body">
  <nav>side nav</nav>
  <main>
    <img src="https://www.hawaiimagazine.com/sites/default/files/field/image/plumeria%202%20Eric%20Tessmer%20Flickr.jpg">
    <footer>
      I need this to stay directly below the image but not go beneath the fold.<br>
      UPDATED ATTEMPT: This footer is now fixed-height. If possible I'd like to avoid this.
    </footer>
  </main>
</div>

(this example shows the footer staying below the content, but now the footer is fixed-height, which is not desirable)

How can we use pure CSS to cause the content of the footer to stay below the image, while not extending beneath the fold when the image is tall?

(EDIT: And I should clarify, I did set the sizing to contain on purpose; I need to see the full image -- it's for a photo gallery. So cropping is not really an option here.)

Sølve T.
  • 4,159
  • 1
  • 20
  • 31
Matt
  • 22,721
  • 17
  • 71
  • 112
  • Have you tried giving `flex-grow` to the `footer`? – Farid Rn Jan 01 '19 at 16:07
  • Have you, @FaridRn? Not being rude here, just pointing out that the time it took you to ask that question is relatively the same it takes to try your solution in the jsFiddle. – Sølve T. Jan 01 '19 at 16:09
  • @FaridRn Yes; doing so simply defines a ratio of their size, but does not cause the desired results. – Matt Jan 01 '19 at 16:13
  • What do you mean "but not beneath the fold"? – Sølve T. Jan 01 '19 at 16:17
  • @SølveTornøe The "fold" is the bottom of the viewport. In other words, I need the content of the page to remain on the screen, without vertical scrolling. – Matt Jan 01 '19 at 16:18
  • I've updated my original post with a link to another attempt where the footer remains directly beneath the image as desired, but the footer is now fixed-height, which is not ideal... – Matt Jan 01 '19 at 16:22
  • 1
    In your updated fiddle, If you unset the height, it does work, or have I missed something? – Sølve T. Jan 01 '19 at 16:35
  • @Matt Maybe I didn't understand your question properly, but check this fiddle out: http://jsfiddle.net/faridv/8pou169c/ – Farid Rn Jan 01 '19 at 16:37
  • @FaridRn I considered `cover` but since this is for a photo gallery, the image can't be cropped. Thank you for trying that though! – Matt Jan 01 '19 at 16:41
  • you've almost got it in http://jsfiddle.net/htsqunro/23/ to fix the height on the footer use min-height:20vh instead of height:20vh. – jeh Jan 01 '19 at 16:42
  • @SølveTornøe That's close, but not quite, unfortunately. The image overflows the height. http://jsfiddle.net/htsqunro/27/ – Matt Jan 01 '19 at 16:42
  • It does not do that for me: http://jsfiddle.net/htsqunro/28/ – Sølve T. Jan 01 '19 at 16:49
  • 1
    @SølveTornøe Ah, I see what you mean -- you meant to unset the height on just the footer, not the image also. The image is now constrained to only 80% of viewport height, which doesn't fill the content area. That's actually not too bad, I might go with that if there's no way to fill the content area too! – Matt Jan 01 '19 at 16:51
  • 1
    Yes! ^^ This is a tricky issue you've come across. Without javascript that is. If you find a different solution, please answer your own question as I would be interested to see how you solved it. Either way, You should answer your own question with a solution so that people in the future do not have to read through all the comments haha. – Sølve T. Jan 01 '19 at 16:56
  • I will, I'm glad I'm probably not missing something obvious! Either fixing the height of the footer (my updated fiddle) or fixing the height of the content (your suggestion) might be allowable, so I'll try those and update back. Happy new year! – Matt Jan 01 '19 at 16:59

2 Answers2

1

change the background-size: contain to background-size: cover

it worked for me

DerDjamel
  • 104
  • 1
  • 6
1

Thanks @henryfhchan on Twitter for the solution! https://codepen.io/anon/pen/oJpvMZ

<div>
    <img src="...">
    <footer>caption is variable-size!</footer>
</div>

div {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

img {
  display: block;
  max-width: 100%;
  object-fit: contain;
  flex: 0 1 auto;
  min-height: 0;  /* necessary */
}

footer {
  padding: 10px;
  flex: auto
}
Matt
  • 22,721
  • 17
  • 71
  • 112