1

Need to fit img into dynamically calculated height of li due to flex. Currently it takes all height, and pull height content. Image should just fit into dynamically calculated height of LI, e.g. 50px and fit into it.

No hardcoded height is needed. Page should be 100% in any device. header/footer - flex: 1, main - flex: 3.

body,
ul {
  margin: 0;
  padding: 0;
}

html,
body,
.root {
  height: 100%;
}

.root {
  display: flex;
  flex-direction: column;
}

main {
  flex: 3;
  background: lightyellow;
}

ul {
  display: flex;
  flex-direction: column;
  height: 100%;
}

ul li {
  flex: 1;
  background: aliceblue;
  outline: 1px solid #000;
  display: flex;
  /* align-items: center; */
  justify-content: space-between;
}

img {
  /* object-fit: contain; */
}

header,
footer {
  flex: 1;
}

header {
  background: lightgray;
}

footer {
  background: lightblue;
}
<div class="root">
  <header>
    HEAD
  </header>

  <main>
    <ul>
      <li>
        <img src="http://via.placeholder.com/200x200" />
        <span>text</span>
      </li>
      <li>
        <img src="http://via.placeholder.com/200x200" />
        <span>text</span>
      </li>
      <li>
        <img src="http://via.placeholder.com/200x200" />
        <span>text</span>
      </li>
    </ul>
  </main>

  <footer>
    FOOTER
  </footer>
</div>

https://jsfiddle.net/sefb3o95/18/

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Alex Ivasyuv
  • 8,585
  • 17
  • 72
  • 90

1 Answers1

1

The main thing to make this work is to use Flexbox all the way.

Simply put, one need to nest flex parent/child instead of using height: 100%, to make use of Flexbox's own properties making its flex children stretch/fill their parents, and the reason is that height: 100% is not gonna work properly.

Additionally, having the img as a flex item will cause you some cross browser issues, so wrap it and give it a max-height: 100%, and it will size properly.

See my notes in the CSS. The min-height: 0 fix for Firefox is well explained here:


Updated fiddle

Stack snippet

body,
ul {
  margin: 0;
  padding: 0;
}

html,
body,
.root {
  height: 100%;
}

.root {
  display: flex;
  flex-direction: column;
}

main {
  flex: 3;
  background: lightyellow;
  display: flex;                 /*  added  */
  flex-direction: column;        /*  added  */
  min-height: 0;                 /*  added, Firefox need this  */
}

ul {
  display: flex;
  flex-direction: column;
  min-height: 0;                 /*  added, Firefox need this  */
}

ul li {
  flex: 1;
  background: aliceblue;
  outline: 1px solid #000;
  display: flex;
  /* align-items: center; */
  justify-content: space-between;
  min-height: 0;                 /*  added, Firefox need this  */
}

img {
  max-height: 100%;              /*  added  */
}

header,
footer {
  flex: 1;
}

header {
  background: lightgray;
}

footer {
  background: lightblue;
}
<div class="root">
  <header>
    HEAD
  </header>

  <main>
    <ul>
      <li>
        <span>
          <img src="http://via.placeholder.com/200x200" />
        </span>
        <span>text</span>
      </li>
      <li>
        <span>
          <img src="http://via.placeholder.com/200x200" />
        </span>
        <span>text</span>
      </li>
      <li>
        <span>
          <img src="http://via.placeholder.com/200x200" />
        </span>
        <span>text</span>
      </li>
    </ul>
  </main>

  <footer>
    FOOTER
  </footer>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • Thanks! It works on Chrome now, but doesn't work on Safari - iOS 10.3.3. Actually I need to make it work there.... – Alex Ivasyuv Feb 14 '18 at 14:53
  • @AlexIvasyuv Don't have access to Safari now. Can you send a screen shot? – Asons Feb 14 '18 at 14:57
  • @AlexIvasyuv Does this work in Safari? https://jsfiddle.net/622ftLcL/9/ – Asons Feb 14 '18 at 16:14
  • It works on macOS on Safari v11.0.3, if add max-width: 100%; to img. But still not work on mobile Safari on iOS. – Alex Ivasyuv Feb 14 '18 at 16:29
  • @AlexIvasyuv Can you test if this works in Safari 10: https://jsfiddle.net/622ftLcL/24/ – Asons Feb 18 '18 at 09:46
  • @AlexIvasyuv Another option, based on the fact that the images should adjust to the first `span`'s height, you could also use `background-image` on it: https://jsfiddle.net/622ftLcL/27/ – Asons Feb 18 '18 at 09:51
  • 1
    The primary issue in Safari is the use of `max-height: 100%` on the `img`. Safari is quite strict in requiring parent elements to have a specified `height` reference when the child has a percentage height. Flex heights and min/max heights are not enough. Safari requires the `height` property. More details in the following post. In particular, see the paragraph right before the **Solutions** section: https://stackoverflow.com/q/33636796/3597276 – Michael Benjamin Mar 08 '18 at 18:27
  • 1
    @Michael_B Thank you very much...and plus 1 on that link's answer. – Asons Mar 08 '18 at 19:53
  • @AlexIvasyuv If you check Michael's comment above, and follow that link, you get an explanation why it won't be that simple to make Safari play along. The option I gave in a previous comment, using `background-image`, will likely be your best workaround. Let me know if I should add that to my answer. – Asons Mar 08 '18 at 19:56