DEV Community

Nic
Nic

Posted on

Showing the middle of an image

I've found a cute dog photo on Unsplash and I'm using it as a hero image. Since it's longer than it is tall, then I want to constrain the height. Except then it only shows the top of the image. So how to show the middle?

Set up

Here's how I have my hero image set up.

HTML:

<div class="hero">
  <img src="https://images.unsplash.com/photo-1658786335136-0b3e83dcb63a" alt="cute dog">  
</div>
Enter fullscreen mode Exit fullscreen mode

CSS:

.hero {
  max-height: 100vh;
  overflow: hidden;
}

img {
  max-width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

I have an image inside a hero div.

For the .hero div, I'm setting the max height to be 100% of the viewport height, as you're likely to have on a hero section.

Once you set the height of the div, then the image will spill out of it. overflow: hidden; stops that - and also therefore cuts the image off so only the top is shown.

On the image, max-width: 100%; means it will always fill the width of the browser window no matter how big or small that is.

There are two ways (that I've found) of fixing this image so it will show the cute dog in the middle of it.

Option 1: positioning

The image is all there, it's just the bottom bit that's being cut off. We can change which bit is being cut off by moving the image. Since we want to show the centre of it, we know that you can do that like this:

img {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}
Enter fullscreen mode Exit fullscreen mode

Except that doesn't work. That's because it doesn't know the height of the parent. I set it as max-height, rather than height. It means it can't work out what to do with top: 50%;. On seeing that CSS is asking "But 50% of what?"

The solution is to add an explicit height to the hero div:

.hero {
  height: 100vh;
}
Enter fullscreen mode Exit fullscreen mode

Which is fine with this image, but what if we had a really wide and short image? Then it would be stretched. I can't just tell this to be height 100% because it still doesn't know what that's 100% of.

The solution is to tell it that the HTML and body are 100%, as is the hero:

html,
body,
.hero {
  height: 100%;
}
Enter fullscreen mode Exit fullscreen mode

So now it knows that the height of all three elements are 100% of the page. But since .hero has a max-height, then if the height is taller than the max-height, it'll go with the max-height.

Here's all the CSS code for this solution:

.hero {
  max-height: 100vh;
  overflow: hidden;
}

img {
  max-width: 100%;
}

/* Show the centre of the image using positioning */
html,
body,
.hero {
  height: 100%;
}

img {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}
Enter fullscreen mode Exit fullscreen mode

Option 2

This option involves our old centring friend, the flexbox.

.hero {
  display: flex;
  align-items: center;
}
Enter fullscreen mode Exit fullscreen mode

And we're looking at a cute dog.

This does complicate things if you also have text in your hero section. But if you do it's likely to be on top of the image, so then either the image or the text will need to be absolutely positioned anyway.

The cute dog

I know I keep saying how cute it is. So here it is, along with the code, so you can play with it.

I did disappear for a while, because it too hot to do anything. Hopefully now that's the worst of summer over.

Top comments (0)