Home > database >  How do I constrain an image to the height of its parent grid cell?
How do I constrain an image to the height of its parent grid cell?

Time:12-13

I have a simple page layout I want to realize.

I'm using display: grid for my layout. Inside one of the grid cells, I need an img tag that resizes to fit the maximum height of the containing grid cell. Unfortunately I have been unable to do so for two days.

I have been able to create the behaviour I want using the background-image property on the grid cell div, but not using img tag inside that div. My image always ends up to big, causing scrollbars and/or my grid to overflow. I have a hard requirement to keep everything on the page inside the viewport (100vh)

This is my version using background-image which demonstrates the behaviour I want: https://jsfiddle.net/9L2x6d7t/6/

* {
  margin: 0;
  padding: 0;
}

html,
body {
  height: 100vh;
}

div.header {
  background-color: rgba(0, 128, 128, .5);
}

div.main {
  background-color: rgba(0, 128, 128, .5);

  div.image {
    background-color: rgba(128, 0, 0, .5);
    /* max-width: 100%;*/
    background-size: contain;
    background-position: center center;
    background-repeat: no-repeat;
    background-image: url("https://img.pr0gramm.com/2022/06/27/b3ce49bad784ab4c.jpg");

    img {
      display: block;
      max-height: 100%;
      width: auto;
    }
  }

  div.tags {
    background-color: rgba(0, 128, 128, .5);
  }

  div.input {
    background-color: rgba(0, 128, 128, .5);
  }
}

div.footer {
  background-color: rgba(0, 128, 128, .5);
}

.container {
  display: grid;
  grid-template-columns: 100%;
  grid-template-rows: 52px auto min-content;
  gap: 1em 0px;
  grid-auto-flow: row;
  grid-template-areas:
    "header"
    "main"
    "footer";
  width: 100%;
  height: 100%;
}

.footer {
  grid-area: footer;
}

.header {
  grid-area: header;
}

.main {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr min-content min-content;
  gap: 1em 0px;
  grid-auto-flow: row;
  grid-template-areas:
    "image"
    "tags"
    "input";
  grid-area: main;
}

.image {
  grid-area: image;
  width: 100%;
  height: 100%;
}

.tags {
  grid-area: tags;
}

.input {
  grid-area: input;
}
<div >
  <div >footer</div>
  <div >header</div>
  <div >
    <div >
      image
      <!-- <img  draggable="false" src="//img.pr0gramm.com/2022/06/27/b3ce49bad784ab4c.jpg"> -->
    </div>
    <div >
      tags
    </div>
    <div >
      input
    </div>
  </div>
</div>

The image perfectly resizes If I make my viewport taller or shorter. I have not been able to do this with an img

Can someone please help?

CodePudding user response:

Try this. It's using the img tag as you requested and resizes based on the height of the parent (the image div). A word of warning - Be careful with your CSS rules and make sure you are closing rules correctly by placing }'s in the right place

* {
  margin: 0;
  padding: 0;
}

html,
body {
  height: 100vh;
}

div.header {
  background-color: rgba(0, 128, 128, .5);
}

div.main {
  background-color: rgba(0, 128, 128, .5);
}

div.tags {
background-color: rgba(0, 128, 128, .5);
}

div.input {
background-color: rgba(0, 128, 128, .5);
}

div.footer {
  background-color: rgba(0, 128, 128, .5);
}

.container {
  display: grid;
  grid-template-columns: 100%;
  grid-template-rows: 52px auto min-content;
  gap: 1em 0px;
  grid-auto-flow: row;
  grid-template-areas:
    "header"
    "main"
    "footer";
  width: 100%;
  height: 100%;
}

.footer {
  grid-area: footer;
}

.header {
  grid-area: header;
}

.main {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr min-content min-content;
  gap: 1em 0px;
  grid-auto-flow: row;
  grid-template-areas:
    "image"
    "tags"
    "input";
  grid-area: main;
}

.image {
    display: flex;
    align-items: center;
    justify-content: center;
  overflow: hidden;
  position: relative;
  flex-grow: 1;
}

.image img {
  height: 100%;
  position: absolute;
}

.tags {
  grid-area: tags;
}

.input {
  grid-area: input;
}
<html>
<head>
</head>
    <body>
        <div >
            <div >footer</div>
            <div >header</div>
            <div >
                <div >
                  <img  draggable="false" src="https://img.pr0gramm.com/2022/06/27/b3ce49bad784ab4c.jpg" />
                </div>
                <div >
                  tags
                </div>
                <div >
                  input
                </div>
            </div>
        </div>
    </body>
</html>

CodePudding user response:

grid by itself doesn't give size, it structured your page.

You can give a size to row.

Let say your row with image:

grid-template-rows: 52px auto min-content;

if you put

grid-template-rows: 50vh auto min-content;

That gives a "real" height to the row which is computed by the browser. You put any king a value till it's giving a real computed size.

Now you can use all the standard max-height... or other...

  • Related