zomega
zomega

Reputation: 2316

Is this layout possible with pure css?

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>

Upvotes: 0

Views: 90

Answers (1)

Piotr Wicijowski
Piotr Wicijowski

Reputation: 2115

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>

Upvotes: 1

Related Questions