2

I'm trying to create a 3 column layout where:

  • left and right colums are equal in width
  • left colum is empty
  • right column contains the image caption (a text of arbitrary length)
  • middle column contains an image. Image should have the height of 100% (fill the viewport vertically).
  • no layout shifts happen when the image loads (I included width and height attributes on the image).
  • I intend to use it with srcset and <picture> (too serve correct image sizes and jpeg/webp). I did not include this in the demo.

Here's my attempt:

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

figure {
  max-width: 100vw;
  max-height: 100vh;
  display: grid;
  grid-template-columns: 1fr min-content 1fr;
  grid-template-rows: 1fr;
  grid-gap: 1rem;
  
  border: 2px solid red;
}

figure::before {
  content: 'abc';
}

img {
  height: 100%;
  width: auto;
}
<figure>  
  <img src="http://placekitten.com/g/400/600" width="400" height="600" alt="cat">
  <figcaption>This is a cat</figcaption>
</figure>

This is how it looks like (screenshot shows grid tracks from Firefox dev tools):

unnecessary space around the image

The issue is this space I painted with red pen over. It makes the grid cell with the image too wide. I want this to look like this:

desired result - no space around the image

Here the grid cell is only as wide as it needs to in order to fit the image (preserving aspect ratio). As a result the image is centered horizontally.

How do I do that?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
kamituel
  • 34,606
  • 6
  • 81
  • 98

4 Answers4

0

As a general rule, try to avoid making images into grid or flex items. There are still too many bugs in modern browsers that prevent reliable rendering.

I just wrote about this here: How can I get an image to fit to the size of a grid cell?

That said, here's a solution you may find useful:

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

figure {
  display: grid;
  grid-template-columns: 1fr min-content 1fr;
  grid-gap: 1rem;
  height: 100vh;
  border: 2px solid red;
}

figure::before {
  content: 'abc';
}

div {
  min-height: 0;
}

img {
  object-fit: cover;
  height: 100%;
  vertical-align: bottom;
}

* {
  box-sizing: border-box;
}
<figure>
  <div>
    <img src="http://placekitten.com/g/400/600" width="400" height="600" alt="cat">
  </div>
  <figcaption>This is a cat</figcaption>
</figure>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    yes but you fixed the height to 100vh, I guess he want the element to be at max 100vh and less if the image is smaller (not sure if it's possible btw) – Temani Afif Jun 11 '20 at 21:56
0

Considering the fact that the image will be the highest element you can move the max-height:100vh to it and it will be easier:

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

figure {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-rows: 1fr;
  grid-gap: 1rem;
  
  border: 2px solid red;
}

figure::before {
  content: 'abc';
}

img {
  max-height:calc(100vh - 4px); /* considering the border */
  width: auto;
  max-width:100%;
}
<figure>  
  <img src="http://placekitten.com/g/400/600" width="400" height="600" alt="cat">
  <figcaption>This is a cat</figcaption>
</figure>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
-1

try to put justify-content:center in the figure. and the max-width:100% in the img. this is what will center the image horizontally in the figure and makes it to take the full with.

-2

A few changes I would make ;)

* {
  margin: 0;
  padding: 0;
}

html,
body {
  height: 100%;
  padding: 0;
  margin: 0;
}

body {
  min-height: 100%;
  padding: 0;
}

figure {
  max-width: 100vw;
  max-height: 100vh;
  display: grid;
  height: 100%;
  grid-template-columns: 1fr minmax(50%, min-content) 1fr;
  grid-gap: 1rem;
  border: 2px solid red;
}

figure::before {
  content: 'abc';
}

img {
  object-fit: contain;
  width: 100%;
  height: 100%;
}
<figure>
  <img src="http://placekitten.com/g/400/600" width="400" height="600" alt="cat">
  <figcaption>This is a cat</figcaption>
</figure>
Grzegorz T.
  • 3,903
  • 2
  • 11
  • 24
  • It's close, but it doesn't suit my needs unfortunately. On larger screens the image won't have a height of 100%. I need the image to fill the available space vertically. – kamituel Jun 11 '20 at 19:43
  • Unless I'm missing something, the image doesn't actually fill the screen verticallty. Even when I added `height:100%` to the `
    `.
    – kamituel Jun 11 '20 at 19:58
  • The photo fills 100% of the figure's height. If you add figure height 100% then the figure will be full screen and img vertically centered. – Grzegorz T. Jun 11 '20 at 20:10
  • Correct. I need the figure to be 100% tall too. Sorry if I didn't make it clear upfront. – kamituel Jun 11 '20 at 20:24
  • In the example I added `height:100%` to figure – Grzegorz T. Jun 11 '20 at 20:36
  • So click "Run code snippet" and then "Full page". Assuming you're using a desktop-size monitor, you'll see the image is small, doesn't fill the viewport height. – kamituel Jun 11 '20 at 20:40