0

I want to show images in a popup (fixed positioned div).

The popup shall consists of (from top to bottom):

  1. A fixed height "a"-element to close the popup (I will later replace this with a more beautiful close button).
  2. An img-element. The image should be as big as possible but never bigger than its original size. Also the image description (Point 3) must always stay visible.
  3. The image description (text only). Must be as high as its content.

Because it's a generic popup the size of the image is unknown. Same for the image description. I don't want to get the popup bigger then the viewport.

As you can see it's not that complicated.

Currently I have solved it using javascript (onresize event). But pure css would be more beautiful. I played around with a grid but it doesn't work. I also didn't have success with a flex box. Maybe someone can fix it...

#grid
{
    display:grid;
    grid-template-columns:1fr;
    grid-template-rows:auto auto auto;
    position:fixed;
    top:0;
    right:0;
    left:0;
    background:yellow;
    max-height:100%;
}

#head
{
    height:20px;
    text-align:center;
    background:orange;
}

#img
{
    margin:0 auto;
}

#footer
{
    text-align:center;
    background:green;
}
<div id="grid">
    <a id="head" href="#" onclick="document.getElementById('grid').style.display='none';">close</a>
    <img id="img" src="https://i.postimg.cc/1tdZsLn3/1554503066.png" />
    <div id="footer">This is the image description.</div>
</div>

This is the working javascript version:

function MyFoto() // create class
{
}

MyFoto.adjust =
function()
{
    var _w = document.getElementById("container").clientHeight - 50 - document.getElementById("info").clientHeight; // 50 = close button + some more
    document.getElementById("img").style.maxHeight = (_w < 1 ? 1 : _w).toString() + "px";
};

MyFoto.close =
function()
{
    document.getElementById("container").style.display = "none";
    return false;
};

window.onresize = MyFoto.adjust;
MyFoto.adjust();
#container
{
    top:0;
    right:0;
    bottom:0;
    left:0;
    position:fixed;
    background-color:rgba(0,0,0,0.7);
    text-align:center;
}

#a
{
    display:block;
}

#img
{
    vertical-align:bottom; /* removes space under image */
    max-width:100%;
    background:white;
}
<div id="container">
  <a id="a" href="#" onclick="return MyFoto.close()">close</a>
  <img id="img" alt="img" src="https://i.postimg.cc/1tdZsLn3/1554503066.png" />
  <div id="info">Photo description!</div>
</div>
zomega
  • 1,538
  • 8
  • 26

1 Answers1

1

Using simple flexbox layout should give you the desired results:

#grid
{
    display:flex;
    flex-direction: column;
    position:fixed;
    top:0;
    right:0;
    left:0;
    background:yellow;
    max-height:100%;
}

#head
{
    height:20px;
    text-align:center;
    background:orange;
}

#img
{
    margin:0 auto;
}

#footer
{
    text-align:center;
    background:green;
}
<div id="grid">
    <a id="head" href="#" onclick="document.getElementById('grid').style.display='none';">close</a>
    <img id="img" src="https://i.postimg.cc/1tdZsLn3/1554503066.png" />
    <div id="footer">This is the image description.</div>
</div>

Update 1

Since google chrome has problems figuring out heights in flexbox containers (as clearly described in this stackoverflow question), it is necessary to use an additional wrapper to get the same layout as on Firefox. The updated code snippet is shown below:

#grid
{
    display:flex;
    flex-direction: column;
    position:fixed;
    top:0;
    right:0;
    left:0;
    background:yellow;
    max-height:100%;
}

#head
{
    height:20px;
    text-align:center;
    background:orange;
}

#img
{
    margin:0 auto;
    object-fit: contain;
    max-width: 100%;
}

#footer
{
    text-align:center;
    background:green;
}

.img-wrapper {
    display: flex;
    min-height: 0;
}
<div id="grid">
    <a id="head" href="#" onclick="document.getElementById('grid').style.display='none';">close</a>
    <div class="img-wrapper">
      <img id="img" src="https://i.postimg.cc/1tdZsLn3/1554503066.png" />
    </div>
    <div id="footer">This is the image description.</div>
</div>

Update 2

Making the Chrome fixes a bit more robust.

#grid
{
    display:flex;
    flex-direction: column;
    position:fixed;
    top:0;
    right:0;
    left:0;
    background:yellow;
    max-height:100%;
}

#head
{
    height:20px;
    text-align:center;
    background:orange;
}

#img
{
    margin:0 auto;
    object-fit: contain;
    max-width: 100%;
    min-height: 0;
}

#footer
{
    text-align:center;
    background:green;
}

.img-wrapper {
    display: flex;
    flex-direction: column;
    min-height: 0;
}
<div id="grid">
    <a id="head" href="#" onclick="document.getElementById('grid').style.display='none';">close</a>
    <div class="img-wrapper">
      <img id="img" src="https://i.postimg.cc/1tdZsLn3/1554503066.png" />
    </div>
    <div id="footer">This is the image description.</div>
</div>
Piotr Wicijowski
  • 1,975
  • 9
  • 15
  • Thank you but there is one problem. In Firefox it works perfectly. But Chrome seems to ignore max-height 100%. – zomega Apr 07 '19 at 10:25
  • I updated the answer with a solution that fixes the problem on Chrome. – Piotr Wicijowski Apr 07 '19 at 19:30
  • Still not the same. If there is too much vertical space then there will be space between image and footer/header. Here is a screenshot: https://i.postimg.cc/rFGyGmt1/Screenshot-20190409-133442.png – zomega Apr 09 '19 at 11:35
  • I made another update, please see if the additional changes give the satisfactory results. – Piotr Wicijowski Apr 09 '19 at 19:39