ChatGPT解决这个技术问题 Extra ChatGPT

How to vertically align an image inside a div

How can you align an image inside of a containing div?

Example

In my example, I need to vertically center the <img> in the <div> with class ="frame":

<div class="frame" style="height: 25px;">
    <img src="http://jsfiddle.net/img/logo.png" />
</div>

.frame's height is fixed and the image's height is unknown. I can add new elements in .frame if that's the only solution. I'm trying to do this on Internet  Explorer 7 and later, WebKit, Gecko.

See the jsfiddle here.

.frame { height: 25px; /* Equals maximum image height */ line-height: 25px; width: 160px; border: 1px solid red; text-align: center; margin: 1em 0; } img { background: #3A6F9A; vertical-align: middle; max-height: 25px; max-width: 160px; }

Hello, sorry but I disagree about use a helper here being the most valuated solution. But It is not the only way. Others are same supported by browsers. I offer a solution here down stackoverflow.com/a/43308414/7733724 and W3C.org about info. You could check. Cheers
Reading Centring Things article on W3C will be useful: w3.org/Style/Examples/007/center.en.html
I think the key is line-height in .frame to make this work

Y
Yashwardhan Pauranik

The only (and the best cross-browser) way as I know is to use an inline-block helper with height: 100% and vertical-align: middle on both elements.

So there is a solution: http://jsfiddle.net/kizu/4RPFa/4570/

.frame { height: 25px; /* Equals maximum image height */ width: 160px; border: 1px solid red; white-space: nowrap; /* This is required unless you put the helper span closely near the img */ text-align: center; margin: 1em 0; } .helper { display: inline-block; height: 100%; vertical-align: middle; } img { background: #3A6F9A; vertical-align: middle; max-height: 25px; max-width: 160px; }

Or, if you don't want to have an extra element in modern browsers and don't mind using Internet Explorer expressions, you can use a pseudo-element and add it to Internet Explorer using a convenient Expression, that runs only once per element, so there won't be any performance issues:

The solution with :before and expression() for Internet Explorer: http://jsfiddle.net/kizu/4RPFa/4571/

.frame { height: 25px; /* Equals maximum image height */ width: 160px; border: 1px solid red; white-space: nowrap; text-align: center; margin: 1em 0; } .frame:before, .frame_before { content: ""; display: inline-block; height: 100%; vertical-align: middle; } img { background: #3A6F9A; vertical-align: middle; max-height: 25px; max-width: 160px; } /* Move this to conditional comments */ .frame { list-style:none; behavior: expression( function(t){ t.insertAdjacentHTML('afterBegin',''); t.runtimeStyle.behavior = 'none'; }(this) ); }

How it works:

When you have two inline-block elements near each other, you can align each to other's side, so with vertical-align: middle you'll get something like this: When you have a block with fixed height (in px, em or another absolute unit), you can set the height of inner blocks in %. So, adding one inline-block with height: 100% in a block with fixed height would align another inline-block element in it ( in your case) vertically near it.


PAY ATTENTION that the: <img src=""/> is NOT inside of the <span></span> helper that was added. It is outside. I just about pulled every strand of my hair our by not realizing this.
It seems like you also need to add "white-space: nowrap;" to the frame or you will run into an issue if you have line break between your image and the helper span. It took me an hour why this solution wasn't working for me.
I'm not sure this is true. I've applied the same methodology to an img without a .helper and it works fine. Just make the img and inline-block and it can vertically align properly.
Pay attention this only works when the img is less height than the frame. if the img is higher than frame, its not aligned to middle.
T
Tahir Yasin

This might be useful:

div {
    position: relative;
    width: 200px;
    height: 200px;
}
img {
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
}
.image {
    min-height: 50px
}

If you wish to also horizontally align the image, add left:0; right: 0; to img
If you don't know the size of the image in advance then make a duplicate image: .img1 { position: absolute; top: 0; bottom: 0; margin: auto; } .img2 { visibility: hidden; }
P
Peter Mortensen

matejkramny's solution is a good start, but oversized images have a wrong ratio.

Here's my fork:

Demo: https://jsbin.com/lidebapomi/edit?html,css,output

https://i.imgur.com/Fgh89yb.png

HTML:

<div class="frame">
  <img src="foo"/>
</div>

CSS:

.frame {
    height: 160px; /* Can be anything */
    width: 160px; /* Can be anything */
    position: relative;
}
img {
    max-height: 100%;
    max-width: 100%;
    width: auto;
    height: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

I tried this and worked perfectly , thanks
P
Peter Mortensen

A three-line solution:

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

This applies to anything.

From here.


If this solution is crossbrowser it should deinitely be on the top!
d
dota2pro

A pure CSS solution:

.frame { margin: 1em 0; height: 35px; width: 160px; border: 1px solid red; position: relative; } img { max-height: 25px; max-width: 160px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; background: #3A6F9A; }

Key stuff

// position: relative; - in .frame holds the absolute element within the frame
// top: 0; bottom: 0; left: 0; right: 0; - this is key for centering a component
// margin: auto; - centers the image horizontally & vertically

R
Ricardo Zea

For a more modern solution, and if there is no need to support legacy browsers, you can do this:

.frame { display: flex; /** Uncomment 'justify-content' below to center horizontally. ✪ Read below for a better way to center vertically and horizontally. **/ /* justify-content: center; */ align-items: center; } img { height: auto; /** ✪ To center this image both vertically and horizontally, in the .frame rule above comment the 'justify-content' and 'align-items' declarations, then uncomment 'margin: auto;' below. **/ /* margin: auto; */ } /* Styling stuff not needed for demo */ .frame { max-width: 900px; height: 200px; margin: auto; background: #222; } p { max-width: 900px; margin: 20px auto 0; } img { width: 150px; }

Here's a Pen using Flexbox: http://codepen.io/ricardozea/pen/aa0ee8e6021087b6e2460664a0fa3f3e

EDIT 1/13/22

There's a better way to do this using CSS Grid and the place-content shorthand:

.frame-text-grid { display: grid; place-content: center; /** ✪ "place-content" is the shorthand for "align-content" and "justify-content". ✪ The "place-content" shorthand requires two values, the first one is for "align-content" and the second one for "justify-content". If only one value is present (like in this demo), then that single value is applied to both directions. ✪ Comment the "place-content: center;" declaration above to see how the elements are spread along the height of the container. **/ }

Using Grid and place-content

Only two lines are needed to center vertically and horizontally.

Here's a Pen using CSS Grid: https://codepen.io/ricardozea/pen/c4e27f1e74542618d73e21f7c2276272?editors=0100


This "grid" solution is easy, thanks for updating us. It also helps with long, horizontal images combined with overflow:hidden and max-width to reduce the distortion of weird aspect ratios. In other words, you might want to crop the sides of a long image, in addition to solving the main problem with vertical images.
P
Peter Mortensen

This way you can center an image vertically (demo):

div{
  height: 150px; // Internet Explorer 7 fix
  line-height: 150px;
}
img{
  vertical-align: middle;
  margin-bottom: 0.25em;
}

P
Peter Mortensen

Also, you can use Flexbox to achieve the correct result:

.parent { align-items: center; /* For vertical align */ background: red; display: flex; height: 250px; /* justify-content: center; <- for horizontal align */ width: 250px; }


Thank you, this finally worked for me!
B
BBlackwo

There is a super easy solution with flexbox!

.frame {
    display: flex;
    align-items: center;
}

Yes but you can hardly see it in all of the answers. I was trying to highlight it simply and clearly as it's a much much easier solution than all of the other answers.
This is the best answer that also worked for me. But in my case in the frame "inline-flex" worked better for me. and for the image inside it i added: "vertical-align: middle".
Flexbox has a really wide range support nowadays. This is the easiest solution (and probably your responsive will thank you). support documentation: caniuse.com/#feat=flexbox
f
fdrv

Imagine you have

<div class="wrap">
    <img src="#">
</div>

And css:

.wrap {
    display: flex;
}
.wrap img {
    object-fit: contain;
}

Y
Yeodave

You could try setting the CSS of PI to display: table-cell; vertical-align: middle;


m
m4n0

CSS Grid

If you want to align a single image vertically inside an image container you can use this:

.img-container {
  display: grid;
}

img { 
  align-self: center;
}

.img-container { display: grid; grid-auto-flow: column; background: #BADA55; width: 1200px; height: 500px; } img.vertical-align { align-self: center; }

If you want to align multiple images inside an image container you can use this:

.img-container {
  display: grid;
  align-items: center;
}

.img-container { display: grid; grid-auto-flow: column; align-items: center; background: #BADA55; width: 1200px; height: 500px; }

Please note that I have used grid-auto-flow: column in both the cases because otherwise the elements wrap to a row with specifying explicit grid items. In the question code, I see the item centered horizontally too. In that case, just make use of the place-items: center instead of align-items: center.


P
Peter Mortensen

You can try the below code:

.frame{ display: flex; justify-content: center; align-items: center; width: 100%; }


P
Peter Mortensen

Background image solution

I removed the image element altogether and set it as background of the div with a class of .frame

http://jsfiddle.net/URVKa/2/

This at least works fine on Internet Explorer 8, Firefox 6 and Chrome 13.

I checked, and this solution will not work to shrink images larger than 25 pixels height. There is a property called background-size which does set the size of the element, but it is CSS 3 which would conflict with Internet Explorer 7 requirements.

I would advice you to either redo your browser priorities and design for the best available browsers, or get some server-side code to resize the images if you'd want to use this solution.


P
Peter Mortensen

http://jsfiddle.net/MBs64/

.frame {
    height: 35px;      /* Equals maximum image height */
    width: 160px;
    border: 1px solid red;
    text-align: center;
    margin: 1em 0;
    display: table-cell;
    vertical-align: middle;
}
img {
    background: #3A6F9A;
    display: block;
    max-height: 35px;
    max-width: 160px;
}

The key property is display: table-cell; for .frame. Div.frame is displayed as inline with this, so you need to wrap it in a block element.

This works in Firefox, Opera, Chrome, Safari and Internet Explorer 8 (and later).

UPDATE

For Internet Explorer 7 we need to add a CSS expression:

*:first-child+html img {
    position: relative;
    top: expression((this.parentNode.clientHeight-this.clientHeight)/2+"px");
}

C
Community

You could do this:

Demo

http://jsfiddle.net/DZ8vW/1

CSS

.frame {
    height: 25px;      /* Equals maximum image height */
    line-height: 25px;
    width: 160px;
    border: 1px solid red;
    
    text-align: center; 
    margin: 1em 0;
    position: relative; /* Changes here... */
}
img {
    background: #3A6F9A;
    max-height: 25px;
    max-width: 160px;
    top: 50%;           /* Here.. */
    left: 50%;          /* Here... */
    position: absolute; /* And here */
}    

JavaScript

$("img").each(function(){
    this.style.marginTop = $(this).height() / -2 + "px";
})

Nice. Any chance for a pure-css solution ?
Unfortunately no unless you want to use tables or drop compatibility with older versions of IE. :( If you knew the exact size of the images before hand it would be different, but not without that it's not possible with CSS alone.
@Joseph How would you fix it with tables?
@Benjamin Udink ten Cate It's messy but it could be done this way: jsfiddle.net/DZ8vW/2 (this is not advised, but should work)
Well it suits arnauds needs perfectly. No JS, only CSS and HTML.
J
JGallardo

This works for modern browsers (2016 at time of edit) as shown in this demo on codepen

.frame {
    height: 25px;
    line-height: 25px;
    width: 160px;
    border: 1px solid #83A7D3;          
}
.frame img {
    background: #3A6F9A;
    display:inline-block;
    vertical-align: middle;
}

It is very important that you either give the images a class or use inheritance to target the images that you need centered. In this example we used .frame img {} so that only images wrapped by a div with a class of .frame would be targeted.


only ie7, just put line-height:25px;
it doesn't seem to be properly aligned even on firefox and chrome ( jsfiddle.net/4RPFa/19 )
works perfectly.
P
Peter Mortensen

Solution using a table and table cells

Sometimes it should be solved by displaying as table/table-cell. For example, a fast title screen. It is a recommended way by W3 also. I recommend you check this link called Centering a block or image from W3C.org.

The tips used here are:

Absolute positioning container displayed as table

Vertical aligned to center content displayed as table-cell

.container { position: absolute; display: table; width: 100%; height: 100%; } .content { display: table-cell; vertical-align: middle; }

Peace in the world

Personally I actually disagree about use helpers for this purpose.


I
Ilya Lysenko

My solution: http://jsfiddle.net/XNAj6/2/

<div class="container">
    <div class="frame">
        <img src="http://jsfiddle.net/img/logo.png" class="img" alt="" />
    </div>
</div>

.container {
    display: table;
    float: left;
    border: solid black 1px;
    margin: 2px;
    padding: 0;
    background-color: black;
    width: 150px;
    height: 150px;
}
.frame {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
    border-width: 0;
}
.img {
    max-width: 150px;
    max-height: 150px;
    vertical-align: middle;
}

P
Peter Mortensen

Try this solution with pure CSS http://jsfiddle.net/sandeep/4RPFa/72/

Maybe it is the main problem with your HTML. You're not using quotes when you define class & image height in your HTML.

CSS:

.frame {
    height: 25px;      /* Equals maximum image height */
    width: 160px;
    border: 1px solid red;
    position: relative;
    margin: 1em 0;
    top: 50%;
    text-align: center;
    line-height: 24px;
    margin-bottom: 20px;
}

img {
    background: #3A6F9A;
    vertical-align: middle;
    line-height: 0;
    margin: 0 auto;
    max-height: 25px;
}

When I work around with the img tag it's leaving 3 pixels to 2 pixels space from top. Now I decrease line-height, and it's working.

CSS:

    .frame {
        height: 25px;      /* Equals maximum image height */
        width: 160px;
        border: 1px solid red;
        margin: 1em 0;
        text-align: center;
        line-height: 22px;
        *:first-child+html line-height:24px; /* For Internet Explorer 7 */
    }

    img {
        background: #3A6F9A;
        vertical-align: middle;
        line-height: 0;    
        max-height: 25px;
        max-width: 160px;
    }
@media screen and (-webkit-min-device-pixel-ratio:0) {
    .frame {
        line-height:20px; /* WebKit browsers */
    }

The line-height property is rendered differently in different browsers. So, we have to define different line-height property browsers.

Check this example: http://jsfiddle.net/sandeep/4be8t/11/

Check this example about line-height different in different browsers: input height differences in Firefox and Chrome


Doesn't work (at least in Firefox). For the missing quotes, this is allowed in HTML5 (don't know which doctype is used in jsfiddle though)
P
Peter Mortensen

I am not sure about Internet Explorer, but under Firefox and Chrome, if you have an img in a div container, the following CSS content should work. At least for me it works well:

div.img-container {
    display: table-cell;
    vertical-align: middle;
    height: 450px;
    width: 490px;
}

div.img-container img {
    max-height: 450px;
    max-width: 490px;
}

IE8+, unfortunately. Fine for me, but maybe not for others.
also note that display:table-cell; doesn't accept % as widths
P
Peter Mortensen

An easy way which work for me:

img {
    vertical-align: middle;
    display: inline-block;
    position: relative;
}

It works for Google Chrome very well. Try this one out in a different browser.


P
Peter Mortensen

For centering an image inside a container (it could be a logo) besides some text like this:

https://i.stack.imgur.com/sVHfi.png

Basically you wrap the image

.outer-frame { border: 1px solid red; min-height: 200px; text-align: center; /* Only to align horizontally */ } .wrapper{ line-height: 200px; border: 2px dashed blue; border-radius: 20px; margin: 50px } img { /* height: auto; */ vertical-align: middle; /* Only to align vertically */ }

some text


P
Peter Mortensen

If you can live with pixel-sized margins, just add font-size: 1px; to the .frame. But remember, that now on the .frame 1em = 1px, which means, you need to set the margin in pixels too.

http://jsfiddle.net/feeela/4RPFa/96/

Now it's not centered any more in Opera…


P
Peter Mortensen

I had the same problem. This works for me:

<style type="text/css">
    div.parent {
        position: relative;
    }

    img.child {
        bottom: 0;
        left: 0;
        margin: auto;
        position: absolute;
        right: 0;
        top: 0;
    }
</style>

<div class="parent">
    <img class="child">
</div>

actually the "position: fixed" on the image worked for me where i've been frustrated over the numerous false answers of people suggesting the table-cell method that didn't work in neighter of my works. With the method suggested by algreat you don't need an extra container too.
P
Peter Mortensen

You can use this:

 .loaderimage {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 60px;
    height: 60px;
    margin-top: -30px; /* 50% of the height */
    margin-left: -30px;
 }

A
Alireza

Using table and table-cell method do the job, specially because you targeting some old browsers as well, I create a snippet for you which you can run it and check the result:

.wrapper { position: relative; display: table; width: 300px; height: 200px; } .inside { vertical-align: middle; display: table-cell; }

Centre me please!!!


P
Peter Mortensen

Want to align an image which have after a text / title and both are inside a div?

See on JSfiddle or Run Code Snippet.

Just be sure to have an ID or a class at all your elements (div, img, title, etc.).

For me works this solution on all browsers (for mobile devices you must to adapt your code with: @media).

h2.h2red { color: red; font-size: 14px; } .mydivclass { margin-top: 30px; display: block; } img.mydesiredclass { margin-right: 10px; display: block; float: left; /* If you want to allign the text with an image on the same row */ width: 100px; heght: 100px; margin-top: -40px /* Change this value to adapt to your page */; }


Text aligned after image inside a div by negative manipulate the img position


s
svnm

I have been playing around with using padding for center alignment. You will need to define the top level outer-container size, but the inner container should resize, and you can set the padding at different percentage values.

jsfiddle

<div class='container'>
  <img src='image.jpg' />
</div>

.container {
  padding: 20%;
  background-color: blue;
}

img {
  width: 100%;
}

P
Peter Mortensen

The best solution is that

.block{
    /* Decor */
    padding:0 20px;
    background: #666;
    border: 2px solid #fff;
    text-align: center;
    /* Important */
    min-height: 220px;
    width: 260px;
    white-space: nowrap;
}
.block:after{
    content: '';
    display: inline-block;
    height: 220px; /* The same as min-height */
    width: 1px;
    overflow: hidden;
    margin: 0 0 0 -5px;
    vertical-align: middle;
}
.block span{
    vertical-align: middle;
    display: inline-block;
    white-space: normal;
}