Fill an image to the height of a div

toolman,

This is not flex CSS but it could be quite easily.

This demo is a “working page”. I would like to ask you to copy this code to a file, open it in your browser and drag the window between wide and narrow.

Please tell me if the size/height of the image is satisfactory at single column widths or if you expect the height of the image to match the height of the text below it in single column mode, doubling the height of the text overall.

@coothead wrote it and I modified it so the height of the image will NOT match the height of the text in one column mode.

Your feedback is requested.

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Untitled Document</title>
    <style media="screen">
body {
    background-color:#f0f0f0;
    font:1em/150% verdana, arial, helvetica, sans-serif;
}
#container {
    display:table;
    width:100%;
    max-width:62.5em;
    margin:auto;
    border:0.062em solid #888;
    box-shadow:0.4em 0.4em 0.4em rgba( 0, 0, 0, 0.3 );
}
#container div {
    display:table-cell;
    width:50%;
    padding:1em;
    box-sizing:border-box;
    background-color:#212e4e;
    color:#fff;
}
#container div:first-of-type {
    background:url(http://coothead.co.uk/images/buddha.jpg) no-repeat 50% 0;
    background-size:cover;
}
@media (max-width: 30em) {
  #container {
    display:block;
  }
  #container div {
    display:block;
    width:100%;
  }
  #container div:first-of-type {
    padding-top:80%;
  }
}
</style>
</head>
<body>

<div id="container">
  <div></div>
  <div>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
       Morbi pretium urna ligula, nec porttitor est venenatis a. 
       Phasellus vel convallis nisl. Aliquam ac ullamcorper magna, 
       a lobortis nisi. Cras in nisi vel tortor lobortis laoreet. 
       Vestibulum fringilla fermentum nisl. Nullam vel nibh aliquet, 
       suscipit lectus et, fermentum velit. 
    </p>
  </div>
</div>

</body>
</html>

Thanks PaulOB that worked. I had to set a fixed height to the image on the smaller screens as the image disappeared. Thanks.

Seriously, everyone is making this out to be much harder than it needs to be. Try this. It uses modern css techniques.

CSS

/* set up flexbox */
.about-us {
  display: flex;
}

/* make image take up 50% of the space */
.about-us__image {
  width: 50%;
  display: flex;

  /* apply background image as a backup */
  background-size: cover;
  background-image: url (/path/to/image.jpg)
}

/* take up full size of parent container */
.about-us__image img {
  display: block;
  width: 100%;

  /* works like background-size: cover; but for img tags */
  object-fit: cover;

  /* hide on browsers that don't support object-fit */
  opacity: 0;
}

/* show image if object-fit is supported */
@supports (object-fit: cover) {
  .about-us__image img{
    opacity: 1;
  }
}

/* vertically stack on tablets */
@media screen and (max-width: 1024px) {
  .about-us {
    flex-direction: column;
  }
}
HTML

<div class="about-us">
  <div class="about-us__image"
    <img src="/path/to/image.jpg"/>
  </div>
  <div class="about-us__text">
    <p>Text goes here </p>
  </div>
</div>

I would normally apply the backup background image via js but I wanted to keep the example simple.

Including you as that is much more complicated than my original in post #10 :slight_smile:

Also I don’t think it does what was requested:

What i am trying to do is to have the image on the left fill the exact height of the right div even if the image is taller than the right div.

That phrase seems to suggest that the image should match the height of the text only and not vice versa. i.e. If the text is only xxpx tall then the image needs to match that height. (Although both versions are possible in my example with a little tweak anyway.)

At least that was my take on it :slight_smile:

2 Likes

Actually… yeah you’re right.

I was writing my example and ran into more and more issues :confused:

The main thing I wanted to get across is that object-fit: cover; is the modern way of making an image take up unknown proportions without getting squashed or stretched.

1 Like

Oh and also using flex-direction: column to stack the elements vertically instead of display: block;

But flex-box is not a replacement for default block behaviour. It should only be used when you require the special characteristics of the flex-box method.
Regular blocks are perfectly adequate and more efficient for general vertical stacking within the document flow.

Yes object-fit is great but not supported in IE yet (although it’s just landed in Edge).

As an aside you can imitate object-fit:cover quite easily as shown in my example #10 where you just set the min-width/height to 100% and height/width to auto and then hide the overflow on the parent. It gives you (nearly) the same effect as cover.

Not quite. object-fit:cover; will center the image by default. What you described would position it in the top left corner.

In your #10 example you used background-size: cover; to replicate the functionality.

1 Like

Yes, you are right, it’s not quite the same. It could be used as a fallback instead.

Only for the first example in that post. The second example is the one I was talking about :slight_smile:

If you don’t need to support IE8 then replacing the .object-fit img rule in your little code pen with this will perfectly replicate the centering effect without the image getting zoomed more than it needs to:

.object-fit img {

    /* top left corner positioned in center of parent */
    position:absolute;
    top:50%;
    left:50%;

    /* shifts image so that center of image is in center of container */
    transform:translateX(-50%) translateY(-50%);

    /* ensures image fully covers the parent element */
    width:auto;
    height:auto;
    min-width:100%;
    min-height:100%;
}
1 Like

You may need to use prefixes on the transform rule if you don’t have autoprefixer as part of your build process.

IE9 requires the -ms- prefix for it to work.

-ms-transform:translateX(-50%) translateY(-50%);
transform:translateX(-50%) translateY(-50%);

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.