11

I have a responsive design with a header image which is placed in a container. The image has width:100%; and height:auto; so it grows as you enlarge the viewport. I don't want to exceed a certain height so the container has a max-height. The image still grows but now the bottom part is cut off now because it aligns to the top of the container.

I would like the image to stay vertically centered in it's container so that parts of the image are cut off at the top and at the bottom. The outcome should look like this:

verticaly centered image

The header images are uploaded by users so they might have different heights therefore I cannot work with specific pixel-values. Is there a CSS-solution for this or do I have to use JavaScript?

Here is the code:

.wrapper {
  width: 90%;
  max-width: 600px;
  margin: 1em auto;
  background-color: #E9ADAD;
}
.container {
  text-align: center;
  height: auto;
  line-height: 200px;
  max-height: 200px;
  overflow: hidden;
}
img {
  width: 100%;
  height: auto !important;
  vertical-align: middle;
}
<div class="wrapper">
  <div class="container">
    <img src="http://placehold.it/600x300/C00000/FFFFFF&text=Image+vertically+centered">
  </div>
</div>

And I prepared a fiddle.

web-tiki
  • 99,765
  • 32
  • 217
  • 249
zork media
  • 952
  • 8
  • 17

5 Answers5

7

You can use absolute positioning for your image , negative top/bottom values and margin:auto; to verticaly center the image in the container :

.wrapper {
  width: 90%;
  max-width: 600px;
  margin: 1em auto;
  background-color: #E9ADAD;
  max-height: 200px;
}
.container {
  position:relative;
  padding-bottom:40%;
  overflow: hidden;
}
img {
  position:absolute;
  top:-50%; bottom:-50%;
  margin:auto;
  width: 100%;
  height: auto;
}
<div class="wrapper">
  <div class="container">
    <img src="http://placehold.it/600x300/C00000/FFFFFF&text=Image+vertically+centered">
  </div>
</div>
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • Thanks, but in this case the container always stays 200px high. I would like it to shrink as the image is getting smaller. – zork media May 08 '15 at 12:20
  • @zorkmedia ok, I modified my answer and used the padding technique to keep the aspect ratio of the container element, this way the container changes its height according to its width. – web-tiki May 08 '15 at 12:25
  • Thanks again, I would never have had the idea just with the padding. But I'll go with your first solution and add some break-points to my css to adjust the height of the container. – zork media May 08 '15 at 12:52
  • 1
    @zorkmedia my pleasure, you can also see this post for more about the padding technique http://stackoverflow.com/questions/1495407/css-maintain-div-aspect-ratio – web-tiki May 08 '15 at 12:54
  • Another favorite - great knowledge. – zork media May 08 '15 at 13:03
  • To get it working, I just had to comment/remove the `bottom:-50%;`. Otherwise, perfect ! – AlexLaforge Nov 09 '20 at 08:44
2

Not so long ago there was only a javascript way to do this but now we have some css rules: object-fit and object-position

They work just like the background-size rules cover and contain:

.container img{
  width: 100%;
  height: auto;
}
@supports(object-fit: cover){
    .container img{
      height: 100%;
      object-fit: cover;
      object-position: center center;
    }
}

The problem with this approach is that is very new and doesn't work on ie or Edge yet. Pen here: http://codepen.io/vandervals/pen/MwKKrm

EDIT: Please, see that you need to declare the width and the height of the image, or it won't work.

Vandervals
  • 5,774
  • 6
  • 48
  • 94
  • Thank you, I've never heard of object-fit before. Right now I do have to support IE but I'll remember this for future times. – zork media May 08 '15 at 12:27
  • Yes, this is a great feature and we hope that microsoft implements it for Edge! I was surprised to find this just a few weeks ago as all other solutions for this looked dirty. – Vandervals May 08 '15 at 12:29
  • 1
    Note that the *parent item* has to have a height set as well. When using `max-height` only, I couldn't get this to work. – Bram Vanroy Jul 24 '18 at 13:18
1

.wrapper {
    width: 90%;
    max-width: 600px;
    margin: 1em auto;
}
.container {
    height: 200px;
    overflow: hidden;
}
.imgWrapper {
    position: relative; 
    width: 200%;
    height: 200%;
    top: -50%;
    left: -50%;
}
img {
    position: absolute; 
    top: 0; 
    left: 0; 
    right: 0; 
    bottom: 0; 
    margin: auto;
    height: auto;
    width: 50%;
}
<div class="wrapper">
    <div class="container">
        <div class="imgWrapper"><img src="http://placehold.it/600x300"></div>
    </div>
</div>

http://jsfiddle.net/ghygpw8t/5/

inspired by: https://css-tricks.com/perfect-full-page-background-image/

Hal-9000
  • 81
  • 2
  • Thank you for the answer - it's almost what I'm searching for, but the container has to stay 200px high. I would like to shrink it as the image is getting smaller. – zork media May 08 '15 at 12:37
  • the container is staying 200px height ... i did not understand the problem – Hal-9000 May 08 '15 at 13:15
  • 1
    I would like the container to get smaller when the image height is smaller then 200px. That's why I set the height of my container to auto. In your solution the container always is 200px high - so there will be whitespace above and beneath the image. Meanwhile I realized that there is no perfect CSS-solution for my problem, so your solution is very close very close and a vote up. Thanks again. – zork media May 08 '15 at 13:23
1

Try like this: Demo

If image size is small it will be arranged in vertical middle and if its big, it will fit in box.

CSS:

 .wrapper {
    width: 90%;
    max-width: 600px;
    margin: 1em auto;
}
.container {
    text-align: center;
    line-height: 200px;
    overflow: hidden;
    background-color:#ccc;
    vertical-align:middle;
    height: 200px;
    border:2px solid green;
    display: flex;
    width: 100%; 
    align-items: center;
    justify-content: center;
}
img {
    width: 100%;  
    max-height: 196px;
    border:2px solid red;    
    vertical-align: middle;
     line-height: 196px;
}

Hope this is what you want!

Community
  • 1
  • 1
G.L.P
  • 7,119
  • 5
  • 25
  • 41
0

On the element you want centered.

.element {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}

on its parent.

.parent { transform-style: preserve-3d; }

Use a polyfill to render cross browser styles.

Cozzbie
  • 1,014
  • 2
  • 12
  • 26