Pete Pete - 6 months ago 13
CSS Question

Vertically align responsive width and height image

I have a div that will change width with the size of the screen. I also want the height of the div to resize with the image up to a maximum height and then any of the overflowing image will be hidden.

So far I have only been able to center the image using absolute positioning, but this means that I also have to include a placeholder image of the same size so that the div will change height:



#test {
max-height: 400px;
width: 50%;
overflow: hidden;
position: relative;
}
#test .test-image {
width: 100%;
}
#test .vertical-align {
left: 0;
top: 50%;
position: absolute;
transform: translateY(-50%);
}

<div id="test">
<!-- this is a placeholder to make the div height expand / contract depending on the width -->
<img src="http://lorempixel.com/800/800/sports/1" class="test-image">

<!-- this is the vertically aligned image -->
<img src="http://lorempixel.com/800/800/sports/1" class="test-image vertical-align">
</div>





Is there any way to do this using relative positioning so I do not need to include the placeholder image?

I thought of the following but it does not seem to work as it just seems to move the image back to where it started and crop from the bottom rather than centering:



#test {
max-height: 400px;
width: 50%;
overflow: hidden;
position: relative;
}
#test .test-image {
width: 100%;
}
#test .vertical-align {
margin-top: 50%;
position: relative;
transform: translateY(-50%);
}

<div id="test">
<!-- this is the vertically aligned image -->
<img src="http://lorempixel.com/800/800/sports/1" class="test-image vertical-align">
</div>





Is this possible with pure css? Please only post css solutions - no js answers.

Thanks

Update

I've managed to figure out why the absolute works but the relative doesn't - when absolute, the
top:50%
is 50% of the parent div, whereas when relative, the
margin-top:50%
is 50% of the image height, which is why the translate just moves it back to it's starting place.

So I guess any solution will be based on moving the image down 50% of the parents height before applying the transform. I've played with padding on the parent but that doesn't seem to work at either

Answer

I found a solution with flex, I hope you find it useful:

#test {
  max-height: 400px;
  width: 50%;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow:hidden;
}

#test .test-image {
  width: 100%;
}
<div id="test">
  <img src="http://lorempixel.com/800/800/sports/1" class="test-image">
</div>

Comments