ChatGPT解决这个技术问题 Extra ChatGPT

Vertically align an image inside a div with responsive height

I have the following code which sets up a container which has a height that changes with the width when the browser is re-sized (to maintain a square aspect ratio).

HTML

<div class="responsive-container">
    <div class="dummy"></div>
    <div class="img-container">
        <IMG HERE>
    </div>
</div>

CSS

.responsive-container {
    position: relative;
    width: 100%;
    border: 1px solid black;
}

.dummy {
    padding-top: 100%; /* forces 1:1 aspect ratio */
}

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

How can I vertically align the IMG inside the container? All my images have variable heights and the container can't have a fixed height/line height because it's responsive... Please help!

Here is a simple flexbox solution: stackoverflow.com/a/31977476/3597276

C
Community

Here is a technique to align inline elements inside a parent, horizontally and vertically at the same time:

Vertical Alignment

1) In this approach, we create an inline-block (pseudo-)element as the first (or last) child of the parent, and set its height property to 100% to take all the height of its parent.

2) Also, adding vertical-align: middle keeps the inline(-block) elements at the middle of the line space. So, we add that CSS declaration to the first-child and our element (the image) both.

3) Finally, in order to remove the white space character between inline(-block) elements, we could set the font size of the parent to zero by font-size: 0;.

Note: I used Nicolas Gallagher's image replacement technique in the following.

What are the benefits?

The container (parent) can have dynamic dimensions.

There's no need to specify the dimensions of the image element explicitly.

We can easily use this approach to align a

element vertically as well; which may have a dynamic content (height and/or width). But note that you have to re-set the font-size property of the div to display the inside text. Online Demo.

<div class="container">
    <div id="element"> ... </div>
</div>
.container {
    height: 300px;
    text-align: center;  /* align the inline(-block) elements horizontally */
    font: 0/0 a;         /* remove the gap between inline(-block) elements */
}

.container:before {    /* create a full-height inline block pseudo=element */
    content: ' ';
    display: inline-block;
    vertical-align: middle;  /* vertical alignment of the inline element */
    height: 100%;
}

#element {
    display: inline-block;
    vertical-align: middle;  /* vertical alignment of the inline element */
    font: 16px/1 Arial sans-serif;        /* <-- reset the font property */
}

The output

https://i.stack.imgur.com/FbpLO.jpg

Responsive Container

This section is not going to answer the question as the OP already knows how to create a responsive container. However, I'll explain how it works.

In order to make the height of a container element changes with its width (respecting the aspect ratio), we could use a percentage value for top/bottom padding property.

A percentage value on top/bottom padding or margins is relative to the width of the containing block.

For instance:

.responsive-container {
  width: 60%;

  padding-top: 60%;    /* 1:1 Height is the same as the width */
  padding-top: 100%;   /* width:height = 60:100 or 3:5        */
  padding-top: 45%;    /* = 60% * 3/4 , width:height =  4:3   */
  padding-top: 33.75%; /* = 60% * 9/16, width:height = 16:9   */
}

Here is the Online Demo. Comment out the lines from the bottom and resize the panel to see the effect.

Also, we could apply the padding property to a dummy child or :before/:after pseudo-element to achieve the same result. But note that in this case, the percentage value on padding is relative to the width of the .responsive-container itself.

<div class="responsive-container">
  <div class="dummy"></div>
</div>
.responsive-container { width: 60%; }

.responsive-container .dummy {
  padding-top: 100%;    /*  1:1 square */
  padding-top: 75%;     /*  w:h =  4:3 */
  padding-top: 56.25%;  /*  w:h = 16:9 */
}

Demo #1.
Demo #2 (Using :after pseudo-element)

Adding the content

Using padding-top property causes a huge space at the top or bottom of the content, inside the container.

In order to fix that, we have wrap the content by a wrapper element, remove that element from document normal flow by using absolute positioning, and finally expand the wrapper (bu using top, right, bottom and left properties) to fill the entire space of its parent, the container.

Here we go:

.responsive-container {
  width: 60%;
  position: relative;
}

.responsive-container .wrapper {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
}

Here is the Online Demo.

Getting all together

<div class="responsive-container">
  <div class="dummy"></div>

  <div class="img-container">
    <img src="http://placehold.it/150x150" alt="">
  </div>
</div>
.img-container {
  text-align:center; /* Align center inline elements */
  font: 0/0 a;       /* Hide the characters like spaces */
}

.img-container:before {
  content: ' ';
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.img-container img {
  vertical-align: middle;
  display: inline-block;
}

Here is the WORKING DEMO.

Obviously, you could avoid using ::before pseudo-element for browser compatibility, and create an element as the first child of the .img-container:

<div class="img-container">
    <div class="centerer"></div>
    <img src="http://placehold.it/150x150" alt="">
</div>
.img-container .centerer {
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

UPDATED DEMO.

Using max-* properties

In order to keep the image inside of the box in lower width, you could set max-height and max-width property on the image:

.img-container img {
    vertical-align: middle;
    display: inline-block;
    max-height: 100%;  /* <-- Set maximum height to 100% of its parent */
    max-width: 100%;   /* <-- Set maximum width to 100% of its parent */
}

Here is the UPDATED DEMO.


Hi Hashem thanks a lot for your answer - this worked like magic for desktop browsers, even when re-sizing to smaller widths. But unfortunately the images are appearing out of position, below the container div, on mobile (Android v2.3.5). Any idea on a fix for this?
@user1794295 I tested this fiddle on three android device with android v2.3 (Galaxy S II, Galaxy Note, Motorola Droid 4) via browserstack.com, Everything works as I expected.You could find the result here: browserstack.com/screenshots/… . Please provide an screenshot or a make specific test of your issue. I'll help as could as possible.
Hi here are some screenshots: browserstack.com/screenshots/… - as you can see with smaller devices (e.g. Xperia, LG Nexus 4) the images appear below the containers... what's going on?!
@HashemQolami This is the Most amazing CSS thing , since i've started building websites :) .
Thanks for font-size: 0;!
D
Danield

With flexbox this is easy:

FIDDLE

Just add the following to the image container:

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex; /* add */
    justify-content: center; /* add to align horizontal */
    align-items: center; /* add to align vertical */
}

This solution works and is much more elegant in my case. CSS3 Flex is awesome!
It doesn't work in Safari :( I guess the problem is flex
@yennefer for safari use -webkit- prefix, or try a library like prefixfree.js :)
This doesn't work when the height of the container is responsive (in percent).
T
Tibos

Use this css, as you already have the markup for it:

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
}

.img-container > img {
  margin-top:-50%;
  margin-left:-50%;  
}

Here is a working JsBin: http://jsbin.com/ihilUnI/1/edit

This solution only works for square images (because a percentage margin-top value depends on the width of the container, not the height). For random-size images, you can do the following:

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%); /* add browser-prefixes */
}

Working JsBin solution: http://jsbin.com/ihilUnI/2/edit


Sorry, not working for me - this is just reducing the size of the images to half the width of the container.
I don't see how that can happen from the CSS i mentioned. Please provide a working sample i can see so i can improve my answer. PS: I also provided another solution :)
S
Salman A

You can center an image, both horizontally and vertically, using margin: auto and absolute positioning. Also:

It is possible to ditch extra markup by using pseudo elements. It is possible to display the middle portion of LARGE images by using negative left, top, right and bottom values.

.responsive-container { margin: 1em auto; min-width: 200px; /* cap container min width */ max-width: 500px; /* cap container max width */ position: relative; overflow: hidden; /* crop if image is larger than container */ background-color: #CCC; } .responsive-container:before { content: ""; /* using pseudo element for 1:1 ratio */ display: block; padding-top: 100%; } .responsive-container img { position: absolute; top: -999px; /* use sufficiently large number */ bottom: -999px; left: -999px; right: -999px; margin: auto; /* center horizontally and vertically */ }

Note: images are center-cropped on <400px screen width.
Open full page demo and resize browser.


Thanks! your .responsive-container img css was the only one that worked for me.
佚名

Try this one

  .responsive-container{
          display:table;
  }
  .img-container{
          display:table-cell;
          vertical-align: middle;
   }

Sorry this doesn't work, I think because my .img-container is absolutely positioned - this is necessary to keep the square aspect ratio/dynamic height.
J
John Slegers

Here's a technique that allows you to center ANY content both vertically and horizontally!

Basically, you just need a two containers and make sure your elements meet the following criteria.

The outher container :

should have display: table;

The inner container :

should have display: table-cell;

should have vertical-align: middle;

should have text-align: center;

The content box :

should have display: inline-block;

If you use this technique, just add your image (along with any other content you want to go with it) to the content box.

Demo :

body { margin : 0; } .outer-container { position : absolute; display: table; width: 100%; height: 100%; background: #ccc; } .inner-container { display: table-cell; vertical-align: middle; text-align: center; } .centered-content { display: inline-block; background: #fff; padding : 12px; border : 1px solid #000; } img { max-width : 120px; }

See also this Fiddle!


A
Alexandra

I came across this thread in search of a solution that:

uses 100% of the given image's width

keeps the image aspect ratio

keeps the image vertically aligned to the middle

works in browsers that do not fully support flex

Testing some of the solutions posted above I didn't find one to meet all of this criteria, so I put together this simple one which might be useful for other people needing to do the same:

.container { width: 30%; float: left; border: 1px solid turquoise; margin-right: 3px; margin-top: 3px; } .container:last-of-kind { margin-right: 0px; } .image-container { position: relative; overflow: hidden; padding-bottom: 70%; /* this is the desired aspect ratio */ width: 100%; } .image-container img { position: absolute; /* the following 3 properties center the image on the vertical axis */ top: 0; bottom: 0; margin: auto; /* uses image at 100% width (also meaning it's horizontally center) */ width: 100%; }

Working example on JSFiddle


P
Paramasivan

Try

Html

<div class="responsive-container">
     <div class="img-container">
         <IMG HERE>
     </div>
</div>

CSS

.img-container {
    position: absolute;
    top: 0;
    left: 0;
height:0;
padding-bottom:100%;
}
.img-container img {
width:100%;
}

W
William

html code

<div class="image-container"> <img src=""/> </div>

css code

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

Whilst this code snippet is welcome, and may provide some help, it would be greatly improved if it included an explanation of how it addresses the question. Without that, your answer has much less educational value - remember that you are answering the question for readers in the future, not just the person asking now! Please edit your answer to add explanation, and give an indication of what limitations and assumptions apply.
D
Discover

Make another div and add both 'dummy' and 'img-container' inside the div

Do HTML and CSS like follows

html , body {height:100%;} .responsive-container { height:100%; display:table; text-align:center; width:100%;} .inner-container {display:table-cell; vertical-align:middle;}

Sample
Image tag

Instead of 100% for the 'responsive-container' you can give the height that you want.,